一. MyBatis 缓存
MyBatis 也与Hibernate一样,具有一级缓存和二级缓存,其中,一级缓存默认开启,二级缓存默认关闭,需要手动开启。
可以与Hibernate 比较性学习: Hibernate的一级缓存和二级缓存(七)
一级缓存是 SqlSession 级别的缓存, 二级缓存是Mapper 级别的缓存。
二. 一级缓存
二.一 验证一级缓存
@Test public void F1Test(){ SqlSession sqlSession=SqlSessionFactoryUtils.getSession(); UserMapper userMapper=sqlSession.getMapper(UserMapper.class); //第一次查询 User user1=userMapper.selectByPrimaryKey(1); System.out.println("user1:"+user1); //第二次查询 User user2=userMapper.selectByPrimaryKey(1); System.out.println("user2:"+user2); }
测试运行,查看控制台:
查询的sql语句,只查询了一条,第二次直接从缓存中拿数据,并不是从数据库中查询。
二.二 验证一级缓存存在于SqlSession级别,而不是Mapper 级别
@Test public void F2Test(){ SqlSession sqlSession=SqlSessionFactoryUtils.getSession(); UserMapper userMapper=sqlSession.getMapper(UserMapper.class); SqlSession sqlSession2=SqlSessionFactoryUtils.getSession(); UserMapper userMapper2=sqlSession2.getMapper(UserMapper.class); //第一次查询 User user1=userMapper.selectByPrimaryKey(1); System.out.println("user1:"+user1); //先进行关闭。 sqlSession.close(); //第二次查询 User user2=userMapper2.selectByPrimaryKey(1); System.out.println("user2:"+user2); }
测试运行,查看控制台:
查询的sql执行了两条,存在于SqlSession中,当SqlSession 关闭时,会清空缓存。
二.三 改变缓存的方式
缓存,如果都是查询时,是不变的。 如果中间过程中有 插入 insert, 删除 delete, 更新 update 方法时,会自动清空缓存的内容,可以避免脏读问题。 如执行update 时,会清空缓存。
@Test public void F3Test(){ SqlSession sqlSession=SqlSessionFactoryUtils.getSession(); UserMapper userMapper=sqlSession.getMapper(UserMapper.class); //第一次查询 User user1=userMapper.selectByPrimaryKey(1); System.out.println("user1:"+user1); user1.setDescription("更新时会清空缓存"); //进行修改。 userMapper.updateByPrimaryKey(user1); sqlSession.commit(); User user2=userMapper.selectByPrimaryKey(1); System.out.println("user2:"+user2); }
测试运行:
更新提交之后,会清空缓存,当再次查询时,会从数据库中查询。
二.四 查询时设置是否用缓存 useCache
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" useCache="true">
默认是true, 用缓存。 即,如果缓存中有数据,默认从缓存中拿。
如果修改成false, 则不用缓存,即使缓存中有,也会再次重新查询。
将F1Test() 的测试方法运行,会查询两次结果。
常用于 select 语句中。
二.五 是否清空缓存 flushCache 默认为true
默认是true, 每次都清空缓存。 为false时,不清空缓存。
设置成true时,将F1Test() 的测试方法运行,会查询两次结果。
常用于insert, update,delete 语句中,用于清空缓存。
<insert id="insertSelective" parameterType="com.yjl.pojo.User" flushCache="true">