网站首页 > 技术文章 正文
文章目录
- 一、Mybatis的执行流程
- 二、Mybatis中的执行器
- 三、#{}和${}区别
- 四、为什么需要预编译
- 五、为什么调用dao接口的方法就能调用sql查询数据,原理是什么
- 六、Mybatis的一级缓存和二级缓存
- 七、Mybatis如何进行分页的
- 八、Mybatis延迟加载的原理
- 九、Mybatis的xml映射文件和Mybatis内部数据结构之间的映射关系
- 总结
一、Mybatis的执行流程
- 初始化工作解析配置文件,得到sqlSessionFactory,把配置文件中的参数都保存到configuration类中。解析mapper.xml文件,把每一个文件封装成一个MappedStatement,并且放入到Map。为每一个mapper接口类都会封装成一个MapperProxyFactory与namespace映射关系保存到map(key:namespace+sqlid value:MappedStatement)中。
- 会话创建创建会话去执行sql,肯定是离不开sqlSession的。创建事务创建执行器,有三种执行器(会在下面的题中谈到)。返回defaultSqlSession对象。
- 语句执行从knownMappers获取该接口的代理工厂类。使用JDK动态代理创建接口的代理类,MapperProxy为代理类,用于代理Mapper接口方法,调用mapper接口的方法都会到代理类MapperProxy的invoke方法。获取MappedStatement,这个在初始化的时候就知道存的是什么了,一个sql语句标签对应一个MappedStatement。通过执行器执行语句,返回结果。
二、Mybatis中的执行器
- SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。
- ReuseExecutor:执行update或select以sql作为key查找statement对象,存在就使用,不存在就创建,用完后,不关闭statement对象,而是放置于Map<String,Statement>内,供下次使用,就是重复使用Statement对象。
- BatchExecutor:执行update,将所有sql都添加到批处理中,等待统一执行,,它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executorBatch()批处理。
三、#{}和${}区别
#{}是预编译处理,${}是字符串替换。
Mybatis在处理#{}时,会将sql中的#{}替换为?,调用PreparedStatement的set方法来赋值。
Mybatis在处理 ${}时,会把 ${}替换成变量的值。
使用#{}可以有效的防止SQL注入,提供系统安全性。
四、为什么需要预编译
预编译可以优化SQL的执行。
防止sql注入。
五、为什么调用dao接口的方法就能调用sql查询数据,原理是什么
在第一步build的时候就会根据mapperXML里面的nameSpace拿到接口并且创建一个代理类工厂
newMapperProxy<>(type),存入knownMappers集合中,此时还没有创建代理类bindMapperForNamespace();同时会把sql语句放入mappedStatements的一个map中,再调用
session.getMapper(BlogMapper.class)方法时,会根据class创建一个代理类,并且返回代理类,执行方法时,执行的是我们代理类的方法MapperProxy,在代理类方法中,执行我们的逻辑,并且从MappedStatement拿到一开始就加载好的sql语句。
六、Mybatis的一级缓存和二级缓存
一级缓存:作用域为SqlSession,存在BaseExecutor下的PerpetualCache下的cache,默认开启,存在查询的方法里面。在同一个SqlSession中执行两次相同的SQL语句时,第一次执行完毕会将结果保存在缓存中,第二次查询直接从缓存中获取。
二级缓存:作用域为nameSpace
二级缓存开启需要2个条件
a.要有CachingExecutor,所以由cacheEnable配置决定,默认是true;
b.Mapper必须要有cache标签,也就是决定currentCache有没有
c.还要在sql上useCache标签为true,对于query语句默认为true,如果想关闭可以设置为false。
d.修改和删除都会清除缓存
<setting name="cacheEnabled" value="true"/>
<cache type="" size="" eviction = "LRU" flushInterval = "120000"
readOnly="false" />
<select id="selectBlogById" resultMap="BaseResultMap" useCache="true" statementType="PREPARED" > select * from blog where bid = #{bid} </select>
<select id="save" parameterType="XX" flushCache="true" useCache="false">
</select>
七、Mybatis如何进行分页的
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内执行书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页,分页插件基本原理是使用M ybatis提供的插件口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql。
八、Mybatis延迟加载的原理
使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询管理B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。
九、Mybatis的xml映射文件和Mybatis内部数据结构之间的映射关系
Mybatis将所有xml配置信息都封装到All-In-One重量级对象Configuration内部,在Xml映射文件中,parameterMap标签会被解析为ParameterMap对象,其每个子元素会被解析为ParameterMapping对象,resultMap标签会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping对象。每一个select、insert、update、delete标签均会被解析为MappedStatement对象,标签内的sql会被解析为BoundSql对象
总结
无论怎么样,每天都要进步一点点
- 上一篇: 肝一波 ~ 手写一个简易版的Mybatis,带你深入领略它的魅力
- 下一篇: Mybatis框架
猜你喜欢
- 2024-11-21 MyBatis详解(二)
- 2024-11-21 想要开发中灵活的使用Mybatis?精通结果映射,你准了吗?
- 2024-11-21 小学妹问:Mybatis常见注解有哪些?
- 2024-11-21 重学Mybatis(二)-------主键自增 (含面试题)
- 2024-11-21 Mybatis入门
- 2024-11-21 重学Mybatis(五)-------分页 (含面试题)
- 2024-11-21 一、手写mybatis框架
- 2024-11-21 MyBatis中的翻页
- 2024-11-21 Mybatis的基础和高级查询应用实践
- 2024-11-21 看完这一篇学会MyBatis就够了
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)