Mybatis基础知识(3)

1、查询缓存

      Mybatis提供一级缓存和二级缓存。

      

      一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象。在该对象中有一个数据结构(HashMap)用户存储缓存数据。

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

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

      1.1、一级缓存

      1.1.1、一级缓存工作原理

      

      1.1.2、一级缓存测试

      测试代码:(使用同一个sqlSession进行查询)

    @Test
    public void testFirstCache(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        
        User user = userDao.findUserById(1);
        User user1 = userDao.findUserById(1);
        
        System.out.println(user);
        System.out.println(user1);
    }
      测试结果:(查询结果相同,而且只生成一条sql语句,证明一级缓存存在)

      

      1.2、二级缓存

      1.2.1、二级缓存原理:

      
      Mybatis是根据映射文件来开辟二级缓存的存储空间:使用哪个映射文件进行查询,就开辟哪一个映射文件的二级缓存。
      使用多个映射文件查询的,根据namespace运行存储空间的开辟。
      Mybatis查询获取原理:
      第一次使用sql语句进行查询,首先检测二级缓存,如果二级缓存中没有,再检测一级缓存,如果一级缓存也没有,查询数据库。
      第二次使用相同的sql语句进行查询,如果二级缓存开启的情况下,先检测二级缓存,如果二级缓存有,直接使用。
      二级缓存数据存储结构:
      Map结构:key是hashcode+sqlid+sql语句,value是存储查询值。

     1.2.2、开启二级缓存

      Mybatis的二级缓存是mapper级别的,除了需要在sqlMapConfig.xml中开启二级缓存,还需要在具体的mapper.xml中开启二级缓存。
      ☆注意:Mybatis缓存对应的pojo类要实现序列化接口(Serializable)
      在核心配置文件中加入:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
	<!-- 开启二级缓存 -->
	<setting name="cacheEnabled" value="true"/>
</settings>
      在具体的mapper.xml文件中开启二级缓存:
<?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="lsq.study.dao.UserDao">

	<!-- 开启本mapper的namespace下的二级缓存 -->
	<cache/>

	<select id="findUserById" parameterType="int" resultType="lsq.study.domain.User">
		select * from user where id = #{id}
	</select>

</mapper>

      1.2.3、测试代码

      ☆注意:sqlSession1要提交关闭,
    @Test
    public void testSecondCache(){
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        UserDao userDao1 = sqlSession1.getMapper(UserDao.class);
        
        User user1 = userDao1.findUserById(1);
        sqlSession1.commit();
        sqlSession1.close();
        
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        UserDao userDao2 = sqlSession2.getMapper(UserDao.class);
        
        User user2 = userDao2.findUserById(1);
        
        System.out.println(user1);
        System.out.println(user2);
    }
      测试结果:
      

      1.2.4、useCache配置

      在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql语句查询,默认情况是true,即该sql使用二级缓存。
      <select id = "..." resultMap="..."   useCache="false">
      总结:针对每次查询都需要最新数据的sql,要设置成useCache=false,禁用二级缓存。

      1.2.5、刷新缓存

      在mapper的同一个namespace中,如果有其他insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。
      设置statement配置中的flushCache="true"属性,默认情况下为true,即刷新缓存。如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。
      如下:
      <insert   id=" "   parameterType=" "   flushCache="true">
      总结:一般情况下,执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。



      








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值