Mybatis整合Redis实现分布式缓存

Mybatis自带二级缓存底层数据结构为HashMap,无法适用于分布式环境。

本文要点:

1.Mybatis整合Redis实现分布式缓存

2.查看自定义缓存实现类RedisCache及相关源码,了解Redis在实现MyBatis二级缓存中的执行工作流 (更多二级缓存知识点可参考MyBatis二级缓存),存储类型(hash)等

1. Mybatis整合Redis实现分布式缓存

A.引入Mybatis整合Redis依赖 Jar包

        
            org.mybatis.caches
            mybatis-redis
            1.0.0-beta2
        

B.SqlMapConfig.xml中开启二级缓存

    
        
    

C.apper.xml中标签使用的type属性,将RedisCache设置为二级缓存实现类

D.resources下添加redis.properties文件,配置redis连接信息 (路径及命名强制要求为redis.properties,具体原因可见下面的源码分析)

redis.host=localhost
redis.port=6379
redis.connectionTimeout=5000
redis.password= redis.database=0

E.代码及执行后日志信息 (Mybatis日志信息开启需要在项目中配置log4j.properties,可参考MyBatis二级缓存中的配置,因为日志信息与实现了org.apache.ibatis.cache的类org.apache.ibatis.cache.decorators.LoggingCache相关)

第二次查询不执行SQL,控制台显示命中率为0.5;且在Redis中查看到相应的key value已生成

key= -604684758:1070847255:com.kay.dao.UserMapper.findById:0:2147483647:select * from user where id = ?:1:dev

    @Test
    public void testRedisLevelTwoSuccess(){
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession(true);
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
        UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
        System.out.println("--------------执行SqlSession1创建的UserMapper1对象的查询---------------------");
        User user1 = userMapper1.findById(1);
        sqlSession1.close(); // 查询后关闭sqlSession1
        System.out.println("--------------执行SqlSession2创建的UserMapper2对象的查询---------------------");
        User user2 = userMapper2.findById(1);
        System.out.println("两次查询出来的对象 user1 user2 是否相等 : " + (user1 == user2));
        sqlSession1.close();
    }

Mybatis整合Redis实现分布式缓存_第1张图片

 (由redis中生成的数据可知道 mybatis二级缓存在redis中存储方式为hash,且key为namespace,具体代码验证见下面源码分析部分)

Mybatis整合Redis实现分布式缓存_第2张图片

2. .自定义缓存实现类RedisCache及相关源码

A.查看redis二级缓存实现类RedisCache源码 Mybatis在启动加载Mapper.xml文件时,会加载对应的RedisCache类,执行RedisCache的构造方法(传入的Id为Mapper文件的namesapce) 通过执行RedisConfig redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration();获取RedisConfig对象 ,并根据RedisConfig对象生成redis操作类JedisPool

Mybatis整合Redis实现分布式缓存_第3张图片

B.RedisConfig为redis连接的基本信息实体类(该实体类初始化时赋予了默认值;故启动时,如果本地的redis配置为redis默认配置,那么不配置redis.properties也可以实现)

Mybatis整合Redis实现分布式缓存_第4张图片

C.根据步骤A进入parseConfiguration()方法中,可见将配置文件都成流并封装到RedisConfig对象中读取的文件为System.getProperty("redis.properties.filename", "redis.properties") 是固定代码

===》》》》redis基本信息的配置文件必须放在resourcesc下并且名字必须为redis.properties

Mybatis整合Redis实现分布式缓存_第5张图片

D.redis.properties中数据封装到RedisConfig对象中后,通过此RedisConfig创建JedisPool对象( A图中parseConfiguration下一步)

pool = new JedisPool(redisConfig, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getConnectionTimeout(), redisConfig.getSoTimeout(), redisConfig.getPassword(), redisConfig.getDatabase(), redisConfig.getClientName());

E.查看RedisCache中的核心方法 putObject() getObject() 可知:Mybatis中的二级缓存在redis中是以Hash的方式存储的,key为RedisCache类下的属性id.getBytes(即为mapper.xml文件的namespace),name为二级缓存的key.getBytes,value为二级缓存value对象序列化后的值 (示例可见上文中redis生成的数据)

Mybatis整合Redis实现分布式缓存_第6张图片

 相关代码:https://gitee.com/sunshinekay/mybatis-practice.git

你可能感兴趣的:(Mybatis系列,mybatis,java,redis,分布式,hash)