美文网首页
mybatis缓存 浅尝辄止

mybatis缓存 浅尝辄止

作者: 侧耳倾听y | 来源:发表于2021-06-30 18:04 被阅读0次

    参考文章

    • 使用mybatis版本
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.4</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
    

    一级缓存:session级别

    一级缓存是默认开启的,但是也只是在同一session会生效。

        @Transactional(rollbackFor = Exception.class)
        public Order findByOrderNo(String orderNo) {
            Order order1 = orderMapper.findByOrderNo(orderNo);
            Order order2 = orderMapper.findByOrderNo(orderNo);
            Order order3 = orderMapper.findByOrderNo(orderNo);
            log.info("order1, {}", order1);
            log.info("order2, {}", order2);
            log.info("order2, {}", order3);
            return orderMapper.findByOrderNo(orderNo);
        }
    

    在添加了@Transactional的方法里,调用同一查询方法,就会触发一级缓存,只有第一次会去数据库查询,第二三次会直接用缓存。以下是日志:

    : ==>  Preparing: select * from `order` where order_no = ?;
    : ==> Parameters: 1234(String)
    : <==      Total: 1
    : order1, org.example.model.Order@62105cd5
    : order2, org.example.model.Order@62105cd5
    : order2, org.example.model.Order@62105cd5
    

    如果是非@Transactional的方法内,调用同一查询方法,则不会触发一级缓存。

    二级缓存:sessionFactory级别

    不同session都可以拿到缓存,可以理解为同一rest接口,多次调用,都会去调用缓存

    • 添加依赖
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-ehcache</artifactId>
                <version>1.0.0</version>
            </dependency>
    
    • 配置缓存
    <?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="org.example.mapper.OrderMapper">
    
        <cache type="org.mybatis.caches.ehcache.LoggingEhcache">
            <property name="memoryStoreEvictionPolicy" value="LRU"/>
        </cache>
    
        <select id="findByOrderNo" resultType="org.example.model.Order">
            select *
            from `order`
            where order_no = #{orderNo};
        </select>
    </mapper>
    
    • 测试
    //    @Transactional(rollbackFor = Exception.class)
        public Order findByOrderNo(String orderNo) {
            Order order1 = orderMapper.findByOrderNo(orderNo);
            // 触发mybatis一级缓存
    //        Order order2 = orderMapper.findByOrderNo(orderNo);
    //        Order order3 = orderMapper.findByOrderNo(orderNo);
            log.info("order1, {}", order1);
    //        log.info("order2, {}", order2);
    //        log.info("order2, {}", order3);
            return orderMapper.findByOrderNo(orderNo);
        }
    
    • 输出
    : ==>  Preparing: select * from `order` where order_no = ?;
    : ==> Parameters: 1234(String)
    : <==      Total: 1
    : order1, org.example.model.Order@1924321e
    : Cache Hit Ratio [org.example.mapper.OrderMapper]: 0.5
    : Cache Hit Ratio [org.example.mapper.OrderMapper]: 0.6666666666666666
    : order1, org.example.model.Order@1924321e
    : Cache Hit Ratio [org.example.mapper.OrderMapper]: 0.75
    : Cache Hit Ratio [org.example.mapper.OrderMapper]: 0.8
    : order1, org.example.model.Order@1924321e
    : Cache Hit Ratio [org.example.mapper.OrderMapper]: 0.8333333333333334
    

    可以看出来多次请求,拿出来的都是同一个对象,说明是拿了缓存

    总结

    1. MyBatis一级缓存的生命周期和SqlSession一致。
    2. MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
    3. MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。
    4. MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。
    5. MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
    6. 在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。
    7. 建议MyBatis缓存特性在生产环境中进行关闭,单纯作为一个ORM框架使用可能更为合适。

    相关文章

      网友评论

          本文标题:mybatis缓存 浅尝辄止

          本文链接:https://www.haomeiwen.com/subject/wuirultx.html