mybatis系统性详解(学习笔记)
Posted 如月之恒-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis系统性详解(学习笔记)相关的知识,希望对你有一定的参考价值。
目录
mybatis知识
传统JDBC不足
- 没有连接池,耗费资源
- 硬编码,不利于维护
mybatis基础
-
mybatis之注解和xml优缺点
注解:不适合复杂sql,收集sql不方便,重新编译
XML:条件不确定、特殊字符需转义 -
mybatis的plugin
-
mybatis逆向工程。重要
mybatis核心应用配置与原理解析
mybatis核心概念
整体认识mybatis源码包
- session— 提供操作数据库的方法
- cache —缓存
- annotations— 注解相关
- binding— mapper相关
- builder— 解析xml相关
- parsing— 解析xml相关
- cursor —返回resultSet
- datasourcer— 数据管理
- exceptionsr— 异常
- executorr —执行器
- io classloader
- jdbc
- mapping —mapper相关封装
- plugin —拦截器
- reflection —反射相关
- scripting —数据厂家
- transaction —事务
mybatis基本流程类调用
- java代码引用mybatis
- 返回SqlSessionFactory
- 拿到sqlsession对我们的执行器进行初始化
- selectOne具体执行
mybatis流程记录
- IO流对xml文件进行获取,获得xmlConfigBuilder对象Parser
- 解析Parser ,也就是对配置文件中 的各配置(如typeAliaes,Mapper)进行解析
- mapper配置的解析是重点
- 用XNode对mapper内容进行解析(无须关注这个,其实就是解析XML文件)
- 获取配置文件中mappers获得结果集
- 解析完成获取Configuration对象(也就是mybatis-config.xml配置文件的所有信息)
- 通过Configuration去创建SqlSessionFactory
- 通过SqlSessionFactory.openSession()方法获得SqlSession
- 通过SqlSession来操作数据库
- 根据执行器类型和事务管理级别来获取执行器
- 执行器会加载XML中配置的plugin(责任链模式:订单系统、java异常底层也是责任链模式)
- 用SqlSession对执行器进行初始化完成
- SelectOne→DeafaultSession.SelectOne→SelectList
- 获取MapperStatement(MapperStatement对应的就是我们在XML中写的查询语句)
<select id="selectUser" parameterType="integer" resultType="user"> select * from user where id = #id </select>`
- 执行query方法→通过getBoundSql获取查询语句
select * from user where id = #id
- 创建缓存(默认一级缓存)→CreateCacheKey。运用装饰器模式,如果有缓存就查本地,没有就查数据库。
- 再调用SimpleExectuor.doQuery()方法。在该方法中生成StatementHandler对象(具体操作数据库相关的handler接口)。
- 调用javaSql的PrepareStatement。到此处就说明了mybatis调用的是JDBC,跟我们自己写个PrepareStatement一样,只是mybatis进行了封装。
- 调用ResultSetHandler(具体操作数据库返回的结果集的handler接口)
- 至此,mybatis基本调用全流程就算完成了。
mybatis处理流程图
mybatis*之session
sqlSession创建过程
mybatis之mapper
下图1、2两个方法底层调用的是同一个方法。
获取mapper
mybatis之sql
mybatis之executor
- 类图
Executor实际上没有真正做事,真正做事的是StatementHandler–PrepareStatementHandler
mybatis 之Cache
每一次查询sql语句,理论上都是要连接一次数据库。如果我们在极短时间内查询相同的sql语句,那么结果极有可能是一样的。所以mybatis默认一级缓存,可以读取缓存数据,以避免多次连接数据库。
一级缓存
mybatis的一级缓存是SqlSession级别的缓存,在操作数据库的时候需要先创建SqlSession会话对象,在对象中有一个HashMap用于存储缓存数据,此HashMap是当前会话对象私有的,别的SqlSession会话对象无法访问。
一级缓存执行过程:
1.第一次执行select完毕会将查到的数据写入SqlSession内的HashMap中缓存起来
2.第二次执行会从缓存中查数据,如果select相同且传参数一样,那么就能从缓存中返回数据,不用去数据库了,从而提高了效率
注意:
1.如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前SqlSession缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读
2.当一个SqlSession结束后,里面的一级缓存也就不存在了。
3.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。
二级缓存
二级缓存是Application应用级别的缓存,它的是生命周期很长,跟Application的声明周期一样,也就是说它的作用范围是整个Application应用。但MyBatis并不是简单地对整个Application就只有一个Cache缓存对象,它将缓存划分的更细,即是Mapper(nameSpace)级别的,即每一个Mapper都可以拥有一个Cache对象,也就是同一个namespace的mappe.xml,当多个SqlSession使用同一个Mapper操作数据库的时候,得到的数据会缓存在同一个二级缓存区域。
如果想让多个Mapper公用一个Cache的话,可以使用节点,来指定你的这个Mapper使用到了哪一个Mapper的Cache缓存。
MyBatis对二级缓存的支持粒度很细,它会指定某一条查询语句是否使用二级缓存。
虽然在Mapper中配置了,并且为此Mapper分配了Cache对象,这并不表示我们使用Mapper中定义的查询语句查到的结果都会放置到Cache对象之中,我们必须指定Mapper中的某条选择语句是否支持缓存,即如下所示,在节点中配置useCache=“true”,Mapper才会对此Select的查询支持缓存特性,否则,不会对此select查询,不会经过Cache缓存。如下所示,select语句配置了useCache=“true”,则表明这条select语句的查询会使用二级缓存。
<select id="selectUser" resultType="com.dto.userDTO" useCache="true">
缓存作用域
一级缓存作用域:sqlSession
Session级别二级缓存作用域是:全局
作用域图:(mybatis的缓存是通过redis来实现的)
mybatis集成spring
- 配置
注入sqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--<property name="mapperLocations" value="classpath*:mybatis/UserMapper.xml" />-->
</bean>
扫包注入映射器
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.jiagouedu.mapper" />
</bean>
org.mybatis.spring.SqlSessionTemplate等同于sqlSession
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
其实只是把本来自己创建的SqlSessionFactory等方法,通过mybatis-spring的包,交由springIOC来统一管理,真正涉及到数据库的操作依旧是由上面提到的mybatis的包来实现。
通用mapper
本来有三个mapper,都是执行简单的单表增删改查
这种情况可以通过“反射”和“泛型”抽象出一个BaseMapper的类,其他三个Mapper的简单增删改查可以不用去写,只要继承BaseMapper,就可以实现。
缺点:只支持单表,简单的增删改查。
徒手实现mybatis(待完善)
注
- 文章是个人知识点整理总结,如有错误和不足之处欢迎指正。
- 如有疑问、或希望与笔者探讨技术问题(包括但不限于本章内容),欢迎添加笔者微信(o815441)。请备注“探讨技术问题”。欢迎交流、一起进步。
以上是关于mybatis系统性详解(学习笔记)的主要内容,如果未能解决你的问题,请参考以下文章
MyBatis学习笔记 —— MyBatis核心配置文件详解