欢迎来到 IT实训基地 - 科迅教育
咨询电话:400-836-0509
首页
科迅动态
就业真相
视频教程
项目实战
学员专访
技术交流
当前位置:
首页
技术交流
【科迅干货】java mybatis-plus
【科迅干货】java mybatis-plus
浏览量:449
时间:2019/5/18
类别:技术交流

mybatis-plus是完全基于mybatis开发的一个增强工具,它的设计理念是在mybatis的基础上只做增强不做改变,为简化开发、提高效率而生,它在mybatis的基础上增加了很多实用性的功能,比如增加了乐观锁插件、字段自动填充功能、分页插件、条件构造器、sql注入器等等,这些在开发过程中都是非常实用的功能,mybatis-plus可谓是站在巨人的肩膀上进行了一系列的创新,我个人极力推荐。下面我会详细地从源码的角度分析mybatis-plus(下文简写成mp)是如何实现sql自动注入的原理。

我们回顾一下mybatisMapper的注册与绑定过程,我之前也写过一篇「Mybatis源码分析之Mapper注册与绑定」,在这篇文章中,我详细地讲解了Mapper绑定的最终目的是将xml或者注解上的sql信息与其对应Mapper类注册到MappedStatement中,既然mybatis-plus的设计理念是在mybatis的基础上只做增强不做改变,那么sql注入器必然也是在将我们预先定义好的sql和预先定义好的Mapper注册到MappedStatement中。

 

现在我将Mapper的注册与绑定过程用时序图再梳理一遍:

�?.png

解析一下这几个类的作用:

 

SqlSessionFactoryBean:继承了FactoryBeanInitializingBean,符合spring loc容器bean的基本规范,可在获取该bean时调用getObject()方法到SqlSessionFactory

 

XMLMapperBuilderxml文件解析器,解析Mapper对应的xml文件信息,并将xml文件信息注册到Configuration中。

 

XMLStatementBuilderxml节点解析器,用于构建select/insert/update/delete节点信息。

 

MapperBuilderAssistantMapper构建助手,将Mapper节点信息封装成statement添加到MappedStatement中。

 

MapperRegistryMapper注册与绑定类,将Mapper的类信息与MapperProxyFactory绑定。

 

MapperAnnotationBuilderMapper注解解析构建器,这也是为什么mybatis可以直接在Mapper方法添加注解信息就可以不用在xmlsql信息的原因,这个构建器专门用于解析Mapper方法注解信息,并将这些信息封装成statement添加到MappedStatement中。

 

从时序图可知,Configuration配置类存储了所有Mapper注册与绑定的信息,然后创建SqlSessionFactory时再将Configuration注入进去,最后经过SqlSessionFactory创建出来的SqlSession会话,就可以根据Configuration信息进行数据库交互,而MapperProxyFactory会为每个Mapper创建一个MapperProxy代理类,MapperProxy包含了Mapper操作SqlSession所有的细节,因此我们就可以直接使用Mapper的方法就可以跟SqlSession进行交互。

源码分析

Mapper的注册与绑定过程的时序图看,要想将sql注入器无缝链接地添加到mybatis里面,那就得从Mapper注册步骤添加,果然,mp很鸡贼地继承了MapperRegistry这个类然后重写了addMapper方法:

�?.png

方法中将MapperAnnotationBuilder替换成了自家的MybatisMapperAnnotationBuilder,在这里特别说明一下,mp为了不更改mybatis原有的逻辑,会用继承或者直接粗暴地将其复制过来,然后在原有的类名上加上前缀“Mybatis”

�?.png

sql注入器就是从这个方法里面添加上去的,首先判断Mapper是否是BaseMapper的超类或者超接口,BaseMappermp的基础Mapper,里面定义了很多默认的基础方法,意味着我们一旦使用上mp,通过sql注入器,很多基础的数据库操作都可以直接继承BaseMapper实现了,开发效率爆棚有木有!

�?.png

GlobalConfigurationmp的全局缓存类,用于存放mp自带的一些功能,很明显,sql注入器就存放在GlobalConfiguration中。

 

这个方法是先从全局缓存类中获取自定义的sql注入器,如果在GlobalConfiguration中没有找到自定义sql注入器,就会设置一个mp默认的sql注入器AutoSqlInjector

 

sql注入器接口:

�?.png

所有自定义的sql注入器都需要实现ISqlInjector接口,mp已经为我们默认实现了一些基础的注入器:

其中AutoSqlInjector提供了最基本的sql注入,以及一些通用的sql注入与拼装的逻辑,LogicSqlInjectorAutoSqlInjector的基础上复写了删除逻辑,因为我们的数据库的数据删除实质上是软删除,并不是真正的删除。

该方法是sql注入器的入口,在入口处添加了注入过后不再注入的判断功能。

�?.png

注入之前先将Mapper类提取泛型模型,因为继承BaseMapper需要将Mapper对应的model添加到泛型里面,这时候我们需要将其提取出来,提取出来后还需要将其初始化成一个TableInfo对象,TableInfo存储了数据库对应的model所有的信息,包括表主键ID类型、表名称、表字段信息列表等等信息,这些信息通过反射获取。

 �?.png

所有需要注入的sql都是通过该方法进行调用,AutoSqlInjector还提供了一个inject方法,自定义sql注入器时,继承AutoSqlInjector,实现该方法就行了。

�?0.png

我随机选择一个删除sql的注入,其它sql注入都是类似这么写,SqlMethod是一个枚举类,里面存储了所有自动注入的sql与方法名,如果是批量操作,SqlMethod的定义的sql语句在添加批量操作的语句。再根据tablesql信息创建一个SqlSource对象。

�?1.png

sql注入器的最终操作,这里会判断MappedStatement是否存在,这个判断是有原因的,它会防止重复注入,如果你的Mapper方法已经在Mybatis的逻辑里面注册了,mp不会再次注入。最后调用MapperBuilderAssistant助手类的addMappedStatement方法执行注册操作。

77
互联网升职加薪,科迅教育为你加油!
视频教程
项目演示
学员专访
南京校区:南京市建邺区新城科技园聚广路33号安科大厦4楼
18724002960
南通校区:南通市崇川区人民中路23号新亚大厦3楼
13626271253
上海校区:筹建中...
敬请期待
全国咨询电话
400-836-0509
周一至周六   08:30-21:30
扫码关注免费学习
南通科迅教育信息咨询有限公司     苏ICP备15009282号     法律顾问:江苏瑞慈律师事务所     Copyright 2008-
关闭
领取学习视频资料
限前100名
在线咨询
免费电话
QQ联系
先学习,后交费
TOP
您好,您想咨询哪门课程呢?