第一步固然是建立一個springBoot項目,並導入依賴嘛。這就很少說了。
這兒咱們就不用jedis了,spring對redis也有支持,咱們就用spring-boot-starter-data-redis來整合redis。java
<!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.3.5.RELEASE</version> </dependency>
spring: #redis 的配置 redis: host: localhost port: 6379 database: 0 # 數據源,我用了druid datasource: type: com.alibaba.druid.pool.DruidDataSource password: 12345678 username: root url: jdbc:mysql://localhost:3306/redis?characterEncoding=UTF-8 druid: stat-view-servlet: url-pattern: /druid/* login-password: 123456 login-username: admin #mybatis 的配置 mybatis: mapper-locations: classpath:/mapper/*.xml # 配置日誌打印 logging: level: com.tao.redis_demo_springboot.dao: debug
## 環境
咱們來搭建基本的一個增刪該查
咱們新建一個測試類,來測試一下
那咱們該如何讓redis進行緩存呢?
在mybatis中,咱們能夠經過cache標籤來開啓二級緩存,這個默認的緩存是org.apache.ibatis.cache.impl.PerpetualCache
來實現的。
在cache標籤中,type能夠指定緩存類。那咱們能夠自定義一個緩存類,用springboot提供的redistemplate 來對redis進行操做。也就是說,咱們經過這個自定義的緩存類來操做redis,咱們也就成功地用redis來作緩存了。mysql
那咱們如何來定義一個緩存類呢?
咱們能夠看看mybatis他是如何實現的,咱們能夠照貓畫虎,去看看PerpetualCache
的源碼。redis
public class PerpetualCache implements Cache { private final String id; private final Map<Object, Object> cache = new HashMap<>(); public PerpetualCache(String id) { this.id = id; } @Override public String getId() { return id; } @Override public int getSize() { return cache.size(); } @Override public void putObject(Object key, Object value) { cache.put(key, value); } @Override public Object getObject(Object key) { return cache.get(key); } @Override public Object removeObject(Object key) { return cache.remove(key); } @Override public void clear() { cache.clear(); } @Override public boolean equals(Object o) { if (getId() == null) { throw new CacheException("Cache instances require an ID."); } if (this == o) { return true; } if (!(o instanceof Cache)) { return false; } Cache otherCache = (Cache) o; return getId().equals(otherCache.getId()); } @Override public int hashCode() { if (getId() == null) { throw new CacheException("Cache instances require an ID."); } return getId().hashCode(); } }
一看源碼就很清晰了,他是用一個map來管理緩存。那能夠把緩存在redis中也寫成一個map的格式。算法
那麼咱們能夠來編寫一個本身定義的緩存類,來實現Cache接口。
在這以前,咱們須要考慮如何在這個緩存類中拿到RedisTemplate呢?咱們能夠寫一個工具類,繼承於ApplicationContextAware類,這樣咱們能夠經過這個類來拿到spring中的redisTemplate。spring
@Component public class ApplicationContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext Context) throws BeansException { applicationContext = Context; } public Object getBean(String beanName){ Object bean = applicationContext.getBean(beanName); return bean; } }
接下來咱們在自定義的緩存類中就能夠拿到redisTemplate了並實現Cache中的方法。sql
public class RedisCache implements Cache { private final String id ; public RedisCache(String id) { this.id = id; } @Override public String getId() { return this.id; } @Override public void putObject(Object o, Object o1) { getRedisTemplate().opsForHash().put(id.toString(),o.toString(),o1); } @Override public Object getObject(Object o) { return getRedisTemplate().opsForHash().get(id.toString(), o.toString()); } @Override public Object removeObject(Object o) { return null; } @Override public void clear() { getRedisTemplate().delete(id.toString()); } @Override public int getSize() { int size = Math.toIntExact(getRedisTemplate().opsForHash().size(id.toString())); return size; } private RedisTemplate getRedisTemplate(){ ApplicationContextUtil applicationContextUtil = new ApplicationContextUtil(); RedisTemplate redisTemplate = (RedisTemplate) applicationContextUtil.getBean("redisTemplate"); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); return redisTemplate; } }
而後咱們在mybatis中的mapper 的xml中添加上cache標籤,並把type設置爲咱們自定義的緩存類。這時候咱們的redis中就會存在咱們查詢過的結果了。apache
redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer());
由於咱們在redis中存儲的數據是String類型的,因此咱們須要將其序列化而後再存儲到redis中。緩存
優化:咱們能夠將那麼一大串的key縮短,例如使用md5算法,將key統一地變爲32位的16進制數字。springboot
mybatis中的二級緩存會在進行寫操做的時候,會將該mapper中的緩存清空。可是,,咱們考慮一下,若是是多表更新呢,在A mapper中的更新語句中更新了B的某個記錄的值,那麼,B的緩存中沒有作對應的修改,這樣就會致使髒讀,督導一個錯誤的數據。爲了解決這個問題,能夠將cache標籤中的改成cache-ref,將這個緩存指向關聯表的mapper。
例如:在A的mapper <cache type="com.tao.redis_demo_springboot.cache.RedisCache"/>
而B的mapper 爲<cache-ref namespace="com.tao.redis_demo_springboot.dao.UserMapper"/>
mybatis