Mybatis常见问题

Mybatis执行流程

  • 理解各组件的联系
  • Sql的执行过程(参数映射,sql解析,执行和处理结果)
  • 首先通过mybatis-config.xml文件去加载连接数据库的相关配置,加载sql的映射文件
    Mybatis常见问题_第1张图片
    Mybatis常见问题_第2张图片
  • 通过mybatis的配置文件然后去构建会话工厂SqlSessionFactory(会话工厂,全局一个,用于生产sqlSession)
  • 紧接着进行创建会话SqlSession项目和数据库的会话,包含了执行sql语句的所有方法,每次操作一次会话,有多个。
  • 然后进入Executor执行器,真正执行数据库操作接口,也负责查询缓存的维护
  • 最后进入MappedStatement对象来读取标签中的信息
    Mybatis常见问题_第3张图片
    标签中的id resultMap对象 以及参数等等都会通过MappedStatement对象来读取的
    MappedStatement对参数的类型进行转化,随后操作数据库,最后将数据库中返回的结果转化为java中的类型。
    Mybatis常见问题_第4张图片
    Mybatis执行流程
  1. 读取Mybatis配置文件,mybatis-config.xml加载运行环境和映射文件
  2. 构建会话工厂SqlSessionFactory
  3. 会话工厂创建SqlSession对象(包含了执行sql语句的所有方法)
  4. 操作数据库的接口,Executor执行器,同时负责查询缓存的维护
  5. Exector接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
  6. 输入参数映射
  7. 输出结果的映射

Mybatis常见问题_第5张图片
查询用户的时候,把用户所属的订单数量也查询出来,这个是立即加载
查询用户的时候,暂时不查询订单数据,当需要订单的时候再查询订单,这个就是延迟加载

延迟加载的原理

  1. 使用CGLIB创建目标对象的代理对象
  2. 当调用目标方法user.getOrderList()时,进入拦截器invoke方法,发现user.getOrderList()是null值时,执行sql查询order列表
  3. 把order查询上来,然后调用user.setOrderList(List< Order > orderList),接着完成user.getOrderList()方法调用。
    Mybatis常见问题_第6张图片
    Mybatis是否支持延迟加载?
  • 延迟加载的意思是:就是需要用到数据时才进行加载,不需要用到数据时就不加载数据
  • Mybatis支持一对一关联和一对多关联集合对象的延迟加载
  • 在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled = true | false。默认是关闭的

延迟加载的底层原理知道吗?
4. 使用CGLIB创建目标对象的代理对象
5. 当调用目标方法时,进入拦截器invoke方法,发现目标方式是null值,执行sql查询
6. 获取数据之后,调用set方法设置属性值,再继续查询目标方法,就有值了

Mybatis缓存

Mybatis的一级,二级缓存用过吗?
Mybatis常见问题_第7张图片

  • 本地缓存,基于PerpetualCache,本质上是一个HashMap
  • 一级缓存:作用域是session级别
  • 二级缓存:作用域是namespace和mapper作用域,不依赖于session

一级缓存
一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当session进行flush或close之后,该session中所有的cache就将清空,默认打开一级缓存
Mybatis常见问题_第8张图片
如果同时去调用同一个mapper的同一个方法,那么他就会使用一级缓存

二级缓存
二级缓存是基于namespace和mapper的作用域起作用的,不是依赖于SQL session,默认也是采用PerpetualCache。HashMap存储
Mybatis常见问题_第9张图片

二级缓存是默认关闭的:
开启方式,两步:

  1. 局部配置文件
<settings>
    <setting name="cacheEnabled" value="true">setting>
settings>
  1. 映射文件
    使用< cache/ >标签让当前mapper生效二级缓存

Mybatis的一级缓存,二级缓存用过吗?

  • 一级缓存,基于Perpetual的HashMap本地缓存,其存储作用域是Session,当Session进行flush或close之后,该session中的所有cache就将清空默认打开一级缓存。
  • 二级缓存是基于namespace和mapper的作用域起作用的,不是依赖SQL Session,默认也是采用了PerpetualCache,HashMap存储,需要单独开启,一个核心配置,一个mapper映射文件
    Mybatis的危机缓存什么时候清除缓存数据
    当某一个作用域(一级缓存Session/二级缓存Session)进行了新增,修改,删除等操作后,默认打开该作用域下的所有select中的缓存将被clear。

你可能感兴趣的:(mybatis,java,数据库)