mybatis源码手写篇
1.需求祥设部分
1.1 为什么程序需要mybatis?原生jdbc不行??那我们来使用原生jdbc看下有什么问题?
1.加载驱动
//1.注册驱动
DriverManager.registerDriver(new OracleDriver());
//2.创建连接
Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@103.10.87.51:1521/myoracle", "wangcf", "wangcf");
//3.创建statement对象
Statement statement = connection.createStatement();
//4.获取结果
ResultSet resultSet = statement.executeQuery("select * from test");
// 5遍历结果
while (resultSet.next()) {
}
_________________________________
以上代码有什么问题?
1.模板化代码太多 2.因编码问题 3.可维护性;。。。
假设你是一个公共开发组的;需要优化,有哪些需要设计?
开始做祥设:
1.根据接口开发使用动态代理方式
1根据方法名查询sql语句
1.1 sql语句和sqlid 建立一种映射关系 mappedStatment
1.2 全局配置文件和映射文件分别存放
1.3 一个全局配置文件包含多个映射文件 即保护多个mappedStatment
2。sql 语句封装以及解析
1.sql语句封装到mapperStatment (保护参数类型,返回值类型,sql语句类型)
2.参数解析 封装到parameterMapping对象中
整个解析之后到sqlSource对象中包含解析之后的语句
3. sql 执行流程
1通过sqlsouce获得可执行的sql语句
2.通过sqlSource 的封装到parameterMapping对象设置参数
3.执行sql语句
4.通过mappedStatment拿到返回值类型 ,反射创建对象遍历结果集给对象赋值;
——————————-
以上我们想达到开发任务只需要写一个接口,就可以完成crud,其他的代码自动生成。下面开始编码
//最后想要达成这样的效果

执行结果:

//配置文件和依赖如下




//接口没有实现类,肯定是我们给他生成了一个代理类在代理类中提供了crud方法
以下是一行代码生产的代理类 传递当前全局配置文件的路径和接口名称传递到了proxyInvocation;

//下面我们来看下proxyInvocation
通过传递的path,解析成流对象;再传递到sqlSessionFactoryBuild方法中;
构建sqlsessionFatory;

//SqlSessionFactoryBuilder到底干了些什么;
我们最终要把全局配置文件和mapper文件解析到configuration对象中;

这里分别解析了datasource和mapper标签放置到configuration对象中;

//解析mapper标签成mapperStatment放到configuration对象中

//最终解析成configuation对象放置到factory

//在通过opensession方法传递给sqlsession,这样sqlsession就有了执行crud的能力;
这里具体sql执行的话交给了Excutor对象;

//具体sql执行分为以下几步
1.通过原生sql获得可执行sql语句
2.创建链接
3.创建preparedStament
4.设置参数
5.执行sql
6.遍历结果集封装成对象返回
//以下分表看下每个方法;

//获取可执行sql 这里使用string工具类处理
可以看到使用分词器,遇到#{}替换成?,并组装成paremetermappig对象,以便设置参数时使用;

//看下分词过程 最后得到可以执行的sql 和参数名称;

//再来看下设置参数使用反射根据获取到的参数名称设置参数;
如果是对象反射取得字段值设置参数,注意stament参数位置从1开始

//最后根据返回值类型遍历结果集
反射给对象设值;

//以上若有疏漏,请多交流沟通