美文网首页
mybatis 二级缓存实践

mybatis 二级缓存实践

作者: 尹楷楷 | 来源:发表于2022-05-16 14:48 被阅读0次

    参考文档
    https://mybatis.org/mybatis-3/sqlmap-xml.html#cache

    xml and java

    1、@CacheNamespace(flushInterval = 1800000)
    2、<cache flushInterval="1800000">
    </cache>
    3、二者不能同时配置(否则报错),想要同时生效。就需要在xml中配置cache 。然后java中配置ref自己

    那么问题来了,如何在一个namespace下配置多个 ache-ref?
    我现在是莫得办法的。。只有暂时规避这种情况

    if use mybatis_plus

    yml file add

    cache-enabled: true
    

    for mapper

    @CacheNamespace(
    implementation = PerpetualCache.class,
    eviction = LruCache.class,
    flushInterval = 60 * 60 * 30,
    size = 1024,
    readWrite = true,
    blocking = true)

    for statament

    add cache
    @Options(useCache=true) 默认 开启单语句缓存
    @Options(useCache=false) 关闭单语句缓存

    clear cache
    @Options(flushCache= Options.FlushCachePolicy.FALSE) 关闭单语句刷新缓存
    @Options(flushCache= Options.FlushCachePolicy.true) 单语句总是刷新缓存
    @Options(flushCache= Options.FlushCachePolicy.DEFAULT) 默认情况下 select 是false,aud是true

    if use join

    如何在join查询中控制cache的维护?
    假设在a表中存在一个mapper接口:a join b 查询生成了cache。
    b表被修改了。我想让这个a表mapper的cache失效,该如何做到?

    使用@CacheNamespaceRef注解可以做到

    要修改的接口

    @CacheNamespaceRef(ProductBrandRepository.class)
    @CacheNamespace(
            flushInterval = 30 * 60 * 1000
    )
    @Mapper
    public interface CateBrandRelationShipMapper extends BaseMapper<CateBrandRelationShip> {
    

    查询的接口

    @CacheNamespace(
            flushInterval = 30 * 60 * 1000
    )
    @Mapper
    public interface ProductBrandRepository extends BaseMapper<ProductBrand> {
    
        @Select("SELECT\n" +
                "   a.id,\n" +
                "   a.brand_no brandNo,\n" +
                "   a.brand_name brandName,\n" +
                "   a.brand_img_url brandImgUrl,\n" +
                "   a.desc,\n" +
                "   GROUP_CONCAT( DISTINCT CONCAT_WS( ' ', b.category_name, b.brand_no ) SEPARATOR '\\n' ) k3CodePrefix \n" +
                "FROM\n" +
                "   product_brand a\n" +
                "   LEFT JOIN cate_brand_relationship b ON a.id = b.brand_id  \n" +
                "   ${ew.customSqlSegment}\n" +
                "GROUP BY\n" +
                "   a.brand_name \n" +
                "ORDER BY\n" +
                "   a.id DESC ")
        @Options
        IPage<ProductBrandDto>
        findByPage(@Param("page") IPage<ProductBrandDto> page, @Param(Constants.WRAPPER) Wrapper<ProductBrandDto> queryWrapper);
    
    
    • first,它不能同时使用在a,b之间。否则报错,只能使用在一个mapper类上
    • CacheNamespaceRef只能使用在mapper类上。只有mapper上的改注解会被扫描到
    • 有@CacheNamespaceRef的一方可以操作清除指定ref的一方缓存
    • 如果存在xml和注解形式并存的情况。我们在xml中配置cache表标签。接口中使用CacheNamespaceRef可以让二者兼顾

    a 中配置了CacheNamespaceRef,指向b;
    含义是 a来操作b的缓存

    缺陷

    1、对于多表join的cache的维护不太好;

    2、最好在【只有单表操作】的表上使用缓存,不只是要保证这个表在整个系统中只有单表操作,而且和该表有关的全部操作必须全部在一个namespace下。必须约束对指定表的crud写在指定namesapce mapper下。否则会出现数据不一致

    3、myabtis 2 level cache 控制粒度比较粗。不能做到像spring cache那样根据 缓存key 细粒度的控制缓存

    best practice 最佳实践

    针对join的情况
    1、多对多。中间表。
    我们可将所有的join语句放到中间表的mapper中。然后通过ref指定其它两个的表,mapper。这样其它表的mapper进行update时会让join查询cache失效。以此达到目的

    2、1对多。
    随便取一个。然后另一个ref它就行

    问题

    在只使用注解的情况下可能会出现mapper的扫描加载的顺序先后原因导致的报错。Cache-ref not yet resolved

    中间表mapper中,用xml的方式代替注解的cache声明解决:

    <?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="com.gbm.cloud.treasure.dao.CateBrandRelationShipMapper">
        <cache>
        </cache>
    
    </mapper>
    
    

    接口中要ref自己。否则mapper接口中的实现不能生效

    @CacheNamespaceRef(CateBrandRelationShipMapper.class)
    @Mapper
    public interface CateBrandRelationShipMapper extends BaseMapper<CateBrandRelationShip> {
    
    

    多对多的一方

    @CacheNamespaceRef(CateBrandRelationShipMapper.class)
    @Mapper
    public interface ProductCategoryRepository extends BaseMapper<ProductCategory> {
    

    多对多的另一方

    @CacheNamespaceRef(CateBrandRelationShipMapper.class)
    @Mapper
    public interface ProductBrandRepository extends BaseMapper<ProductBrand> {
    

    相关文章

      网友评论

          本文标题:mybatis 二级缓存实践

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