Mybatis执行流程
mybatis中xml解析是通过SqlSessionFactoryBuilder.build()方法。
初始化mybatis(解析xml文件构建成Configuration对象)并初始化SqlSessionFactory对象
-
- 在解析xml时会同时根据其中节点做相应的初始化操作
- 关键节点: settings、typeAliases、mappers
通过SqlSesssionFactory.openSession()方法打开一个SqlSession对象
-
- SqlSessionFactory对象的作用是里面存了全局的配置信息以及初始化环境和DataSource,DataSource对象可以用来开辟连接,SqlSessionFactory对象是用来保存全局信息并且打开数据库连接
- 在打开SqlSession对象的时候就会开辟一个连接对象并传给SqlSession对象,和数据库打交道的操作入口在于SqlSession对象
通过SqlSession.getMapper()根据传入的Mapper对象类型动态代理并返回一个动态代理后的Mapper对象
由SqlSession.select()/update(),MapperProxy对象的invoke()方法执行后再执行execure方法,再根据情况选择执行select/update
Executor执行Query/queryFromDatabase,在前面经过参数名封装和缓存查询之后(缓存为空),会调用queryFromDatabase方法去数据库当中查
SimpleExecurot执行doQuery()方法,初始化prepareStatement并且给#{}参数赋值
StatementHandler执行query()方法,执行sql语句
ResuletHandler.handleResultSets()方法封装结果集
具体执行流程如下图:
mybatis面试题
1. spring和mybatis整合之后为什么一级缓存会失效?
一级缓存使用者可以随时使用或者销毁缓存,从SqlSession对象打开时缓存就已经存在。当关闭SqlSession对象缓存就失效。
当与spring整合的时候,直接跳过SqlSession对象,无法直接操作到SqlSession对象,spring在操作SqlSession的时候,不知道用户什么时候关闭,所以每调用完一个dao方法就关闭了,所以导致一级缓存失效。
如果开启了事务,一级缓存就会生效,因为开启了事务,执行完dao就不会销毁,因为一旦销毁,事务就没有了,你开启了事务,spring就知道你什么时候需要结束
2. 二级缓存中要注意的事情?
二级缓存里面的数据不能存放那种一直累加到很大的数据
二级缓存是基于命名空间的,当多个命名空间操作同一张表的时候,最好不要用二级缓存,当一个命名空间insert之的一,不会刷新缓存,用另一个命名空间select的时候还是会查询缓存
3. ResultMap和ResultType的区别?
ResultMap是自己指定返回值与对象及与对象内部属性名和数据库列名的绑定
ResultType是直接返回值与别名库当中的java对象的映射
4. #{}和${}的区别?
#{}将传入的数据都当成一个字符串,会对自动传的数据加一个双引号,#{}方式能够很大程度防止sql注入
${}将传入的数据是直接显示生成在sql中,${}无法防止sql注入
${}方式一般用于传入数据库对象,例如传入表名
一般能用#{}的就别用${},Mybaits排序时使用order by动态参数时需要注意,用${}而不能用#{}
5. MyBatis与Hibernate有哪些不同?
MyBatis是一个半自动ORM而Hibernate是一个完全的ORM框架
因为MyBatis需要自己编写sql语句,不过MyBatis可以通过xml或注解方式配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。可严格控制sql执行性能,灵活度高。但是灵活的前提是 Mybatis无法做到数据库无关性,如果需要实现支持多种数据库的则需要自定义多套sql映射文件。
Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高,如果用Hibernate开发可以节省很多代码,提高效率。但是hibernate学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力。
6. 为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
Mybatis在查询关系或关联集合对象时需要手动编写sql来完成,所以称之为半自动ORM映射工具。
7. Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是钊对Resultset结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
8. Mybatis映射文件中,如果A标签通过include引用B标签的内容,请问B标签能否定询问在A标签的后面,还是说必须定义在A标签的前面?
虽然Mybatis解析xml映射文件是按照顺序解析的,但是被引用的B标签依然可以定义在任何地方,Mybatis都可以正常识别。原理是Mybatis解析A标签时发现A标签引用了B标签,但是B标签尚未解析到,此时,Mybatis会将A标签标记为未解析状态,然后继续解析余下的标签,包含B 标签,待所有标签解析完毕,Mybatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签就可以正常解析完成了。
9. Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行原理?
Mybatis动态sql可以让我们在xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
Mybatis提供了9种动态sql标签:trim、where、set、foreach、if、choose、when、otherwise、bind
执行原理:使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql功能。
原文地址:https://www.cnblogs.com/zouhg/p/11634171.html