首页 / 缓存 / mybatis集成redis作为二级缓存
mybatis集成redis作为二级缓存
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了mybatis集成redis作为二级缓存,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6683字,纯文字阅读大概需要10分钟。
内容图文
mybatis默认开启了二级缓存功能,在mybatis主配置文件中,将cacheEnabled设置成false,则会关闭二级缓存功能
<settings> <!--二级缓存默认开启,false关闭--> <setting name="cacheEnabled" value="false" /> <!--mybatis日志打印到控制台--> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings>
mybatis框架虽然默认开启了二级缓存功能,但是并没有默认实现,也就是下面这句代码返回null, 然后走一级缓存
下面是配置Redis作为mybatis的二级缓存,代码如下:
(1)mybatis主配置文件mybatis-config.xml中添加如下配置
<settings> <!--二级缓存默认开启,false关闭--> <setting name="cacheEnabled" value="true" /> <!--mybatis日志打印到控制台,以便于观察--> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings>
(2)FemaleMapper.xml 配置如下
<mapper namespace="qinfeng.zheng.FemaleMapper"> <select id="getFemaleById" resultType="qinfeng.zheng.entity.Female" parameterType="int"> SELECT id,name FROM tb_female where id = #{id}; </select> <cache eviction="LRU" type="qinfeng.zheng.RedisCache"/> </mapper>
LRU是mybatis默认的过期策略
(3)qinfeng\zheng\RedisCache.java
import org.apache.ibatis.cache.Cache; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Map; /** * 使用redis的Hash结构 */ public class RedisCache implements Cache { private String id; private JedisPool jedisPool; privatestaticint EXPIRE_TIME = 1000 * 1000; public RedisCache(String id) { if (id == null) { thrownew IllegalArgumentException("Cache instances require an ID"); } this.id = id; JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPool = new JedisPool(jedisPoolConfig, "192.168.79.221", 6379, 3000, "123456"); } @Override public String getId() { return id; } @Override publicvoid putObject(Object key, Object value) { execute(jedis -> { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ObjectOutputStream outputStream = new ObjectOutputStream(stream); outputStream.writeObject(value); byte[] idBytes = id.getBytes(); jedis.hset(idBytes, key.toString().getBytes(), stream.toByteArray()); // 设置一个过期时间。。if (jedis.ttl(idBytes) == -1) { jedis.expire(idBytes, EXPIRE_TIME); } } catch (Exception e) { thrownew RuntimeException("put object to redis error!", e); } returnnull; }); } @Override public Object getObject(Object key) { return execute(jedis -> { try { byte[] bytes = jedis.hget(id.getBytes(), key.toString().getBytes()); if (bytes == null) { returnnull; } ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); return objectInputStream.readObject(); } catch (Exception e) { thrownew RuntimeException("get data from redis error!", e); } }); } @Override public Object removeObject(Object key) { return execute(jedis -> jedis.hdel(id.getBytes(), key.toString().getBytes())); } @Override publicvoid clear() { execute(jedis -> jedis.del(id.getBytes())); //因为id是String类型,所以直接jedis.del(id)也行 } @Override publicint getSize() { return (Integer) execute(jedis -> { Map<byte[], byte[]> map = jedis.hgetAll(id.getBytes()); return map.size(); }); } private Object execute(RedisCallBack redisCallBack) { try (Jedis jedis = jedisPool.getResource()) { return redisCallBack.callBack(jedis); } catch (Exception e) { thrownew RuntimeException(e.getMessage()); } } }
public interface RedisCallBack { Object callBack(Jedis jedis); }
使用redis作为mybatis的二级缓存框架,最主要就是实现mybatis提供的spi接口--Cache即可,然后实现putObject,getObject这两个主要的方法即可。
除此之外,记得pom.xml文件中添加jedis依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
(4)修改测试代码
public class V1Test { public static void main(String[] args) { try (InputStream is = Resources.getResourceAsStream("mybatis-config.xml")) { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession sqlSession = sqlSessionFactory.openSession(true); FemaleMapper femaleMapper = sqlSession.getMapper(FemaleMapper.class); Female female = femaleMapper.getFemaleById(1); System.out.println(female); System.out.println("-----------分隔符----------------------------------"); SqlSession sqlSession2 = sqlSessionFactory.openSession(true); FemaleMapper femaleMapper2 = sqlSession2.getMapper(FemaleMapper.class); Female female2 = femaleMapper2.getFemaleById(1); System.out.println(female2); } catch (Exception e) { e.printStackTrace(); } } }
第一次运行:
Opening JDBC Connection Created connection 331510866. ==> Preparing: SELECT id,name FROM tb_female where id = ?; ==> Parameters: 1(Integer) <== Columns: id, name <== Row: 1, soga <== Total: 1 Female(id=1, name=soga) -----------分隔符---------------------------------- Opening JDBC Connection Created connection 1316061703. ==> Preparing: SELECT id,name FROM tb_female where id = ?; ==> Parameters: 1(Integer) <== Columns: id, name <== Row: 1, soga <== Total: 1 Female(id=1, name=soga)
哈哈,貌似还是查库两次,redis缓存好像没有起到作用。
事实上,mybatis框架为二级缓存提供了一个缓冲Map, 需要在调用commit方法之后,才会将缓冲区Map中的数据写入到redis中。
我们修改一下测试代码,然后再运行观察结果
public class V1Test { public static void main(String[] args) { try (InputStream is = Resources.getResourceAsStream("mybatis-config.xml")) { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession sqlSession = sqlSessionFactory.openSession(true); FemaleMapper femaleMapper = sqlSession.getMapper(FemaleMapper.class); Female female = femaleMapper.getFemaleById(1); System.out.println(female); sqlSession.commit(); System.out.println("-----------分隔符----------------------------------"); SqlSession sqlSession2 = sqlSessionFactory.openSession(true); FemaleMapper femaleMapper2 = sqlSession2.getMapper(FemaleMapper.class); Female female2 = femaleMapper2.getFemaleById(1); System.out.println(female2); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
哎哎哎,报了个错,记得Female 需要序列化
Opening JDBC Connection Created connection 490150701. ==> Preparing: SELECT id,name FROM tb_female where id = ?; ==> Parameters: 1(Integer) <== Columns: id, name <== Row: 1, soga <== Total: 1 Female(id=1, name=soga) -----------分隔符---------------------------------- Cache Hit Ratio [qinfeng.zheng.FemaleMapper]: 0.5 Female(id=1, name=soga)
请看,这次只查了一个库,第2冲直接缓存命中、
我们再运行一次刚才的代码
Cache Hit Ratio [qinfeng.zheng.FemaleMapper]: 1.0 Female(id=1, name=soga) -----------分隔符---------------------------------- Cache Hit Ratio [qinfeng.zheng.FemaleMapper]: 1.0 Female(id=1, name=soga)
两次都缓存命中!!
再看一下redis:
好了, mybatis整合redis为二级缓存到此完毕,下章分析一下它的源码实现!
原文:https://www.cnblogs.com/z-qinfeng/p/11920606.html
内容总结
以上是互联网集市为您收集整理的mybatis集成redis作为二级缓存全部内容,希望文章能够帮你解决mybatis集成redis作为二级缓存所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。