mybatis缓存 (九)

在mybatis中缓存分为一级缓存和二级缓存:

一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。

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

1、mybatis一级缓存

一级缓存是默认开启的,所以第一次发起查询用户id为1的用户信息,先去找缓存中是否有1的用户,如果有的话拿去用,如果没有去数据库中查去。得到用户信息放入一级缓存中去。如果SqlSession去执行commit操作(执行插入、删除、更新)的话,清空SqlSession中的一级缓存,这样做就是为了让缓存中的数据保持最新,避免用户读到错误的数据。

具体体现如下代码:

@Test
public void testFindById(){
    User user = userDao.findById(45);
    System.out.println("查询第一次用户"+user);
    User user2 = userDao.findById(45);
    System.out.println("第二次查询用户"+user2);
    System.out.println(user == user2);
}

以上我们对同一个id进行两次查询,结果如下我们两次查询实际只调用了一次sql语句去查询,这里就使用的mybatis一级缓存:

 

一级缓存清除:

(1)使用指定方法进行清除,测试代码如下:实际结果查询了两次

@Test
public void testFirstCache(){
    User user1 = userDao.findById(57);
    System.out.println(user1);
    //sqlSession.close;
    //再次获取SqlSession
    //sqlSession = factory.openSession();

    sqlSession.clearCache();//清空缓存
    userDao = sqlSession.getMapper(UserDao.class);

    User user2 = userDao.findById(57);
    System.out.println(user2);
    System.out.println(user1 == user2);
}

(2)执行插入、删除、更新操作进行缓存清除

@Test
public void testClearCache(){
    User user1 = userDao.findById(57);
    System.out.println(user1);

    user1.setUserName("更新名称");
    user1.setUserAddress("更新地址");
    userDao.updateUser(user1);

    User user2 = userDao.findById(57);
    System.out.println(user2);
    System.out.println(user1==user2);
}

如上我们在查询时进行更新操作,结果第二次查询时发现执行了两次sql证明缓存清除了

2、mybatis二级缓存

二级缓存需要我们手动开启,开启后sqlSession 去查询用户信息,查询到用户信息会将查询数据存储到二级缓存中。sqlSession2 去查询与 sqlSession1 相同的用户信息,首先会去缓存中找是否存在数据,如果存在直接从缓存中取出数据。如果 SqlSession3 去执行相同 mapper 映射下 sql,执行 commit 提交,将会清空该 mapper 映射下的二级缓存区域的数据。

 

具体代码实现如下:

SqlMapConfig.xml配置
<!--开启耳机缓存支持
    因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为
    false 代表不开启二级缓存。
    -->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

UserDao.xml配置
<!--根据用户id查询用户
将 UserDao.xml 映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement 要使用
二级缓存,如果不使用二级缓存可以设置为 false。
注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
-->
<select id="findById" resultMap="userMap" parameterType="Integer" useCache="true">
    select * from user where id = #{id};
</select>

调用具体方法:

@Test
public void testSecondCache(){
    SqlSession sqlSession1 = factory.openSession();
    UserDao dao1 = sqlSession1.getMapper(UserDao.class);
    User user1 = dao1.findById(57);
    System.out.println(user1);
    sqlSession1.close();//一级缓存消失

    SqlSession sqlSession2 = factory.openSession();
    UserDao dao2 = sqlSession2.getMapper(UserDao.class);
    User user2 = dao2.findById(57); //实际调用了二级缓存
    System.out.println(user2);
    sqlSession2.close();

    System.out.println(user1 == user2);

}

 

结果如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值