mybatis的缓存机智

本文详细介绍了Mybatis的一级和二级缓存机制。一级缓存是SqlSession级别的,而二级缓存则是Mapper级别的,可跨SqlSession使用。文章讨论了如何启用二级缓存,包括配置文件设置、Mapper配置、序列化接口实现等,并指出二级缓存存在的数据一致性问题,尤其在多条数据更新时可能引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.mybatis的缓存机制

1.1一级缓存:直观的理解就是某个sqlseesion的一个Map,结果用于存储一定数量的查询结果,在sqlseesion进行更新,删除操作时,mybatis会清空一级缓存,保持数据的一致性。值得注意的是mybatis与spring结合,一级缓存当sqlsession的事务提交了,spring将会关闭sqlseesion也就是将此sqlseesion的缓存清空。

1.2二级缓存:也就是某个mapper的一个Map,但是二级缓存不一定存在内存,而是多种存储介质,还可以是借助ehcache实现分布式存储。第一个sqlseesion查询了数据库之后,mybatis会进行缓存,当第二个sqlseesion 查询的时候首先会在mapper的缓存下,查询,没有再查询数据库。

2.使用

2.1一级缓存

//一级缓存一般不用管理,在你不知不觉下的就会使用了,使用代码,理解一级缓存的效果
@Controller
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderMapper ordermapper;

    //事务管理
    @Autowired
    private DataSourceTransactionManager txManager;

    //事务定义
    @Autowired
    private DefaultTransactionDefinition txDefinition;

    @RequestMapping(value="/findorder",method=RequestMethod.GET)
    public String findOrderAndOrderDetail(HttpServletRequest request)
    {   
        //获取事务状态
        TransactionStatus status = txManager.getTransaction(txDefinition);

        Order order = ordermapper.findOrderAndOrderDetail();
        System.out.println(order.toString()+"这是订单一");
        Order order2 = ordermapper.findOrderAndOrderDetail();
        System.out.println(order2.toString()+"这是订单二");
        request.setAttribute("order", order);

        txManager.commit(status);
        return "order_detail";
    }


//进行页面访问之后控制台打印
/**
DEBUG [http-bio-8080-exec-11] - ==>  Preparing: SELECT orders.*, orderdetail.items_id, orderdetail.items_num FROM orders, orderdetail WHERE orderdetail.orders_id = orders.id AND orders.id=3 
DEBUG [http-bio-8080-exec-11] - ==> Parameters: 
DEBUG [http-bio-8080-exec-11] - <==      Total: 2
DEBUG [http-bio-8080-exec-11] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3716e720]
com.ssm.model.Order@4fcd0175这是订单一
DEBUG [http-bio-8080-exec-11] - Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3716e720] from current transaction
DEBUG [http-bio-8080-exec-11] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3716e720]
com.ssm.model.Order@4fcd0175这是订单二
**/

//此时就可以看查询order1的时候,由于没有缓存数据,边进行查询数据库,但是查询order2 的时候不再向数据库发送查询语句

2.2二级缓存

2.2.1在mybatis配置文件打开二级缓存开关

2.2.2在你需要开启二级缓存的mapper 下打开二级缓存开关

<mapper namespace="com.ssm.mapping.OrderMapper">
    <!-- 开启本mapper的二级缓存 -->
    <cache></cache>
    <!--这里还有关于二级缓存的众多选项,这里只做基础测试-->

2.2.3对pojo类进行实现序列化接口

public class Order implements Serializable

2.2.4使用


/**二级缓存是mapper级别的缓存,那么使用两次访问便可以看到效果,第一次进行查询sqlseesion关闭,mapper进行缓存,第二次查询则是另一个sqlseesion了,**/
@Controller
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderMapper ordermapper;

    //事务管理
    @Autowired
    private DataSourceTransactionManager txManager;

    //事务定义
    @Autowired
    private DefaultTransactionDefinition txDefinition;

    @RequestMapping(value="/findorder",method=RequestMethod.GET)
    public String findOrderAndOrderDetail(HttpServletRequest request)
    {   
        //获取事务状态
        TransactionStatus status = txManager.getTransaction(txDefinition);

        Order order = ordermapper.findOrderAndOrderDetail();
        System.out.println(order.toString()+"这是订单一");

        request.setAttribute("order", order);

        txManager.commit(status);
        return "order_detail";
    }

2.2.5结果

**<!--这是第一次查询,可以看到Cache Hit Ratio缓存命中率0.0,向数据库发送了查询语句-->**
DEBUG [http-bio-8080-exec-12] - Creating a new SqlSession
DEBUG [http-bio-8080-exec-12] - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3a3b6630]
DEBUG [http-bio-8080-exec-12] - Cache Hit Ratio [com.ssm.mapping.OrderMapper]: 0.0
DEBUG [http-bio-8080-exec-12] - ==>  Preparing: SELECT orders.*, orderdetail.items_id, orderdetail.items_num FROM orders, orderdetail WHERE orderdetail.orders_id = orders.id AND orders.id=3 
DEBUG [http-bio-8080-exec-12] - ==> Parameters: 
DEBUG [http-bio-8080-exec-12] - <==      Total: 2
DEBUG [http-bio-8080-exec-12] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3a3b6630]
com.ssm.model.Order@7b49a5a9这是订单一

**<!--这是第二次查询,可以看到Cache Hit Ratio缓存命中率0.5 并没有向数据库发送查询语句-->**
DEBUG [http-bio-8080-exec-8] - Creating a new SqlSession
DEBUG [http-bio-8080-exec-8] - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5382276e]
DEBUG [http-bio-8080-exec-8] - Cache Hit Ratio [com.ssm.mapping.OrderMapper]: 0.5
DEBUG [http-bio-8080-exec-8] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5382276e]
com.ssm.model.Order@64b013a这是订单一

3. 对二级缓存的总结

3.1也就是说二级缓存是mapper级别的,可以供不同的session使用,二级缓存有其的缺陷,比如说sqlseesion1向数据库查询了多次不同的数据,mybatis进行缓存多次的查询数据,sqlseesion2也如此,那么当sqlseesion1进行对一个数据的update,delete操作时,二级缓存就需要清空所有缓存保持数据一致性,那么sqlseesion2的缓存也被清除掉了,也就是二级缓存对数据的细粒度不够友好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值