Mybatis使用Redis实现二级缓存

您所在的位置:网站首页 mybatis缓存和redis缓存 Mybatis使用Redis实现二级缓存

Mybatis使用Redis实现二级缓存

2023-09-17 04:56| 来源: 网络整理| 查看: 265

mybatis配合redis实现分布式

文章内容输出来源:拉勾教育Java高薪训练营

服务场景

相信很多小伙伴都有在分布式框架中无法使用mybatis二级缓存的困扰把,因为二级缓存是单服务工作的,无法实现分布式缓存,例如两个服务器1和2,当用户1访问了服务器1时候查询的缓存会在1服务器上面,而这时候有用户访问服务器2的时候,就无法取出刚刚的缓存 在这里插入图片描述 为了解决此问题,我们需要引入第三方缓存框架Redis,我们将二级缓存查询出来内容放入到Redis中实现服务器共享,以后无论有多少台服务器,我们都能从缓存中获取数据。 在这里插入图片描述

mybatis提供了一个cache接口,如果我们要实现自己的逻辑就要实现cache接口来开发即可,mybatis提供了一个针对cache接口的redis实现类,该类存在mybatis-redis包下

org.mybatis.caches mybatis-redis 1.0.0-beta2

实现:

一.首先开启二级缓存

我们这里使用两种方法开启(二级缓存默认是关闭的) 1.采用注解方式开启二级缓存

@CacheNamespace(implementation = RedisCache.class) //开启二级缓存

2.通过配置文件进行开启二级缓存 useCache=“true”

select * from user 二.创建redis.properties

此处需要注意一定要与sqlMapConfig.xml处于同一目录下(redis密码自行修改) 在这里插入图片描述

redis.host=localhost redis.port=6379 redis.connectionTimeout=5000 redis.password= redis.database=0 三.创建redis.properties

此处需要注意运行sqlSession1.close();方法会清空一级缓存,这样就可以判断数据是否是从二级缓存中来,在进行commit操作时会刷新一级缓存以及二级缓存

@Test public void SecondLevelCache(){ SqlSession sqlSession1 = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); SqlSession sqlSession3 = sqlSessionFactory.openSession(); IUserMapper userMapper1 = sqlSession1.getMapper(IUserMapper.class); IUserMapper userMapper2 = sqlSession2.getMapper(IUserMapper.class); IUserMapper userMapper3 = sqlSession3.getMapper(IUserMapper.class); User user1 = userMapper1.findUserById(1); sqlSession1.close(); //清空一级缓存 User user2 = userMapper2.findUserById(1); System.out.println(user1 == user2); User user = new User(); user.setId(1); user.setUsername("asdasdawd"); userMapper3.update(user); //操作事务会把二级缓存清空 sqlSession3.commit(); User user3 = userMapper3.findUserById(1); System.out.println(user2==user3); }

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

源码分析

RedisCache和Mybatis缓存方式大致相同,都是实现类Cache接口,并将jedis操作缓存

public final class RedisCache implements Cache { public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require anID"); } this.id = id; RedisConfig redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration(); pool = new JedisPool(redisConfig, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getConnectionTimeout(), redisConfig.getSoTimeout(), redisConfig.getPassword(), redisConfig.getDatabase(), redisConfig.getClientName()); } }

RedisCache是由MyBatis的CacheBuilder创建的,创建方式就是调用了RedisCache带有String参数的构造方法,而在RedisCache的构造方法中会调用 RedisConfigurationBuilder来创建对象RedisCache,并使用RedisCache来创建JedisPool。

RedisConfig类继承了 JedisPoolConfig,并提供了 host,port等属性的包装 在这里插入图片描述 RedisConfig对象是由RedisConfigurationBuilder创建的,会根据parseConfiguration方法从classpath中读取一个redis.properties文件

public RedisConfig parseConfiguration(ClassLoader classLoader) { Properties config = new Properties(); InputStream input = classLoader.getResourceAsStream(this.redisPropertiesFilename); //读取redis.properties if (input != null) { try { config.load(input); } catch (IOException var12) { throw new RuntimeException("An error occurred while reading classpath property '" + this.redisPropertiesFilename + "', see nested exceptions", var12); } finally { try { input.close(); } catch (IOException var11) { } } } RedisConfig jedisConfig = new RedisConfig(); this.setConfigProperties(config, jedisConfig); return jedisConfig; }

在这里插入图片描述 并将配置文件中内容设置到RedisConfig中返回,然后是RedisCache使用 RedisConfig类创建完成edisPool,在RedisCache中实现了一个简单的模板方法,用来操作Redis: 在这里插入图片描述 Cache是通过putObject和getObject来操作看mybatis-redis 储存的数据 在这里插入图片描述 再次可以看到mybatis-redis在存储数据时候是使用hash结构来存储的,把cache的id作为key,mapper中的查询缓存数据作为 hash 的field,需要缓存的内容直接使用SerializeUtil存储,,SerializeUtil和其他的序列化类差不多,负责 对象的 序列化和反序列化。 到此为止 我们大致了解了mybatis使用redis实现二级缓存的代码及原理和源码分析~



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3