Java高频面试题- 每日三连问?【Day5】 — MyBatis篇2

作者 | 浩说编程
来源 | 公众号:浩说编程
[ 大厂技术资源 | 研发必备安装包 | 经典必读电子书 | 限时免费获取 ]

在这里插入图片描述
 

问题导读

一、了解MyBatis的一级缓存、二级缓存吗?

追问-1:如何配置二级缓存?

追问-2:一级缓存和二级缓存的使用顺序?

二、MyBatis的分页原理是什么?

三、MyBatis如何实现一对多复杂查询?

 

一、了解MyBatis的一级缓存、二级缓存吗?

图片

正经回答:

先说缓存,合理使用缓存是系统优化的常见手段。

将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询。

而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力。

同时提高系统性能。

 

一级缓存

一级缓存是SqlSession级别的缓存。

在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。

不同的sqlSession之间的缓存数据区域是互相不影响的。

也就是他只能作用在同一个sqlSession中,不同的sqlSession中的缓存是互相不能读取的。

 

一级缓存的工作原理

与Redis同理,用户发起查询请求,查找某条数据,sqlSession先去缓存中查找,是否有该数据。

如果有,直接返回;如果没有,从数据库中查询,并将查询到的数据放入一级缓存区域,供下次查找使用。

但sqlSession执行commit,即增删改操作时会清空缓存。这么做的目的是避免脏读。

图片

码文不易
你的关注是浩说编程持续更新的动力
浩说编程会做的更好

二级缓存

为什么要有二级缓存?

二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存。

二级缓存是跨SqlSession的。二级缓存的作用范围更大。

在实际开发中,MyBatis通常和Spring进行整合开发。

Spring将事务放到Service中管理,对于每一个service中的sqlsession是不同的。

这是通过mybatis-spring中的

org.mybatis.spring.mapper.MapperScannerConfigurer创建sqlsession自动注入到service中的。

每次查询之后都要进行关闭sqlSession,关闭之后数据即被清空。

所以spring整合之后,如果没有事务,一级缓存是没有意义的。
 

深入追问:

追问-1:如何配置二级缓存?

MyBatis对二级缓存的支持粒度很细,它会指定某一条查询语句是否使用二级缓存。

1、MyBatis支持二级缓存的总开关,全局配置变量cacheEnabled=true

在mybatis-config.xml添加

<settings>  
    <setting name="cacheEnabled" value="true"/><!-- 二级缓存 -->
</settings> 

2、该select语句所在的Mapper,配置 或节点

<mapper namespace="com.xxxx.dao.TaskDao">
    <cache/>
    <insert id="addxxx" parameterType="xxx" >
        insert into xxx (name, price) values (#{name}, #{price})    
    </insert>
    <select id="listXXX" resultType="xxx">
        select * from  xxx     
    </select>
</mapper>

3、该select语句的参数 useCache=true

<select id="selectXXXX" resultMap="task" parameterType="java.util.Map" useCache="true">

 

追问-2:一级缓存和二级缓存的使用顺序?

MyBatis查询数据的顺序是:

二级缓存 👉 一级缓存 👉 数据库

图片

 

二、MyBatis的分页原理是什么?

正经回答:

Mybatis使用RowBounds对象进行分页

它是针对ResultSet结果集执行的内存分页,而非物理分页。

可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理

使用Mybatis提供的插件接口,实现自定义插件。

在插件的拦截方法内拦截待执行的sql,然后重写sql。

根据dialect方言,添加对应的物理分页语句和物理分页参数。

拦截过程举例:

select * from student;

拦截sql后重写为:

select t.* from (select * from student) t limit 0, 10

 

三、MyBatis如何实现一对多复杂查询?

场景举例:

比如一个用户存在多个订单(一对多关系),那么如何通过MyBatis一次查询出用户以及用户下包含的订单集合?

图片

正经回答:

可以使用联合查询语句,只查询一次,

然后通过使用resultMap里面的associationcollection节点配置一对多的类就可以完成。

使用举例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
<mapper namespace="com.kerwin.mybatis.pojo.Person">
  <resultMap type="com.kerwin.mybatis.pojo.Person" id="personreSultMap">
    <id column="p_id" property="id"/>
    <result column="name" property="name"/>
    <collection property="orderList" ofType="com.kerwin.mybatis.pojo.Orders" column="pid">
      <id column="o_id" property="id"/>
      <result column="price" property="price"/>
    </collection>
  </resultMap>
  
  <select id="selectPersonFetchOrder" parameterType="int" resultMap="personreSultMap" >
    select p.*,o.* from person p,orders o where o.pid=p.p_id and p.p_id=#{id}
  </select>
</mapper>

===

每日小结

今天我们复习了面试中常考的MyBatis三个问题,你做到心中有数了么?

对了,**如果你的朋友也在准备面试,请将这个系列扔给他,如果他认真对待,肯定会感谢你的!!**

好了,今天就到这里,学废了的同学,记得三连,也会给我继续更新的动力。

图片
作者 | 浩说编程
来源 | 公众号:浩说编程
[ 大厂技术资源 | 研发必备安装包 | 经典必读电子书 | 限时免费获取 ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值