mybatis系统性详解(学习笔记)

Posted 如月之恒-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis系统性详解(学习笔记)相关的知识,希望对你有一定的参考价值。

目录

mybatis知识


传统JDBC不足

  1. 没有连接池,耗费资源
  2. 硬编码,不利于维护

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学习笔记2--配置环境详解

MyBatis学习笔记 —— MyBatis核心配置文件详解

项目笔记: IDEA+MAVEN+Bootstrap+Spring+Mybatis+SpringMVC+Mysql

MyBatis学习笔记

MyBatis学习笔记

MyBatis学习笔记