今天是周六,因为 小白云 要出去写生画画,我在家闲着也没事,正好来公司练习下造轮子的能力。
昨天正好跟着 詹哥 学习了基本的Mybatis原理,上午首先画个思维导图巩固一下理解,吃完饭下午就开始撸代码。
这里分享下早上画的图:
思维导图中还有一些细节步骤没展示出来,下面是导出的文本,可以按照流程实现:
框架设计分析
接口如何设计
-
SqlSession接口(CRUD)
- Object selectOne(String statementId, Object param)
- void insert(String statementId, Object param)
- ...(剩余接口)
DefaultSqlSession作为实现类
配置文件编写格式
-
直接参考mybatis本身配置文件的编写
全局配置文件,配置数据源ds
-
mapper映射文件
配置SQL语句,一个SQL语句对应一个statement执行,每个statement都有一个唯一的idSQL语句
参数
映射对象
读取全局配置文件
将其中信息封装到一个对象Configuration
- DataSource信息
- Map<String,MappedStatement>
读取映射配置文件
-
多个MappedStatement
(对应映射配置文件中的一个标签)- sql语句
- statement类型
- 输入参数类型
- 输出结果类型
接口实现类功能如何实现
-
a. 获取连接
- 通过Configuration获取DataSource
- 通过DataSource获取Connection
-
b. 执行Statement操作
要考虑执行的是哪种Statement,不同的Statement,操作不同,参数设置不同,结果处理也不同
-
获取Statement类型
根据StatementId去Configuration查找对应的MappedStatement,根据Statement对象获取statementType类型
-
通过MappedStatement获取sql语句
SELECT * FROM user where id = #{id} and username = #{username}
SQL语句:SELECT * FROM user where id = ? and username= ?
解析占位符参数List<ParameterMapping>
ParameterMapping(参数名称)
解析#{}中的参数名称:id -
给SQL语句设置参数
遍历List<ParameterMapping>挨个处理入参
获取入参的Java类型,根据类型(8种基本类型、String类型、POJO类型等)判断如何获取参数值
比如说如果是Integer类型,则只有将入参对象直接赋值给SQL语句即可
preparedStatement.setObject(1, "王五");如果是POJO类型,通过反射根据参数名称获取POJO对象的属性值
preparedStatement.setObject(1, "王五"); -
执行statement
rs = preparedStatement.executeQuery();
-
处理结果集
获取要封装的java对象类型(Class对象)
通过MappedStatement对象获取结果映射的Java类型遍历结果集,取出结果集中的每条结果的列名
通过rs获取metaData(列名)根据列名通过反射获取java对象中的field名称
要求:SQL语句的列名一定要和java对象中的属性名称一致。
通过反射给指定field赋值
-
配置文件如何解析
-
dom4j
指定要解析的配置文件的路径(类路径、磁盘路径、网络路径)---Resource
通过类加载器去指定路径加载,放入 InputStream流对象,读取Source资源中的数据
通过InputStream流对象,去创建Document对象(dom4j)---此时没有针对xml文件中的语义进行解析
DocumentReader---去加载InputStream流,创建Document对象的
进行mybatis语义解析(全局配置文件语义解析、映射文件语义解析)
XMLConfigParser---解析全局配置文件
XMLMapperParser---解析全局配置文件
SqlSession如何创建
通过工厂模式SqlSessionFactory创建
SqlSessionFactory如何创建
使用构建者模式,SqlSessionFactoryBuiler
今天花了一天时间,整理加实现,目前只实现了mapper映射文件的select标签支持,后续有时间会继续完善,原理其实都一样的。这也证实了,起码框架源码并没有那么难读,行动起来,总会有收获。
感兴趣的朋友可以看下我今天造的轮子: 代码地址: https://github.com/ccgogoing/01-mybatis
水平有限,记录自己的学习过程,欢迎大家一起交流学习。