最近复习了Mybatis,就想用自己的理解手写mybatis框架,Mybatis源码的核心是jdk动态代理和jdbc。本文完成的Mybatis功能比较简单,代码还有许多需要改进的地方,欢迎大家可以结合Mybatis源码去动手完善。
一、Mybatis流程简介
在手写自己的Mybatis框架之前,我们先来了解一下Mybatis,它的源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,才能够更深入的理解源码(ref:Mybatis源码解读-设计模式总结)。我们对上图进行分析总结:
mybatis的配置文件有2类
mybatisconfig.xml,配置文件的名称不是固定的,配置了全局的参数的配置,全局只能有一个配置文件。
Mapper.xml 配置多个statemement,也就是多个sql,整个mybatis框架中可以有多个Mappe.xml配置文件。
通过mybatis配置文件得到SqlSessionFactory
通过SqlSessionFactory得到SqlSession,用SqlSession就可以操作数据了。
SqlSession通过底层的Executor(执行器),执行器有2类实现:
基本实现
带有缓存功能的实现
MappedStatement是通过Mapper.xml中定义statement生成的对象。
参数输入执行并输出结果集,无需手动判断参数类型和参数下标位置,且自动将结果集映射为Java对象
HashMap,KV格式的数据类型
Java的基本数据类型
POJO,java的对象
二、手动实现Mybatis框架思路
二、梳理自己的Mybatis的设计思路
根据上文Mybatis流程,我简化了下,分为以下步骤:
1.dom4j读取数据库配置,建立连接
LzxDBConfigurationUtils通过dom4j读取mybatis-config.xml的工具类,mybatis3添加了数据库环境配置本文通过读取标签的default,将属性和连接数据库的操作封装在MyConfiguration对象中供后面的组件调用。
2.dom4j读取Mapper配置
读取mapper.xml的工具类,将接口类名、方法、返回类型封装在LzxMapperBean对象中供后面的组件调用。
3.创建SqlSession
MySqlSession的成员变量中必须得有Executor和Configuration去做调配,箭头就像是一种关联关系。我们自己的SqlSession将有一个getMapper方法,然后使用动态代理生成对象后,就可以做数据库的操作了。
4.创建Executor,封装JDBC操作数据库
Executor是一个执行器,负责SQL语句的生成和查询缓存(缓存还没完成)的维护,也就是jdbc的代码将在这里完成。
5.创建LzxMapperProxy,使用动态代理生成Mapper对象
我们只是希望对指定的接口生成一个对象,使得执行它的时候能运行一句sql罢了,而接口无法直接调用方法,所以这里使用动态代理生成对象,在执行时还是回到LzxSqlSession中调用查询,最终由LzxExecutor做JDBC查询。这样设计是为了单一职责,可扩展性更强。