Mybatis Plus使用redis作为二级缓存
1. mybatis-plus开启二级缓存
- mybatis-plus.configuration.cache-enabled=true
#全局设置主键生成策略
mybatis-plus:
global-config:
db-config:
id-type: auto
logic-delete-field: isDeleted #全局逻辑删除字段值
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
cache-enabled: true
2. 定义RedisTemplate的bean交给spring管理,这里为了能将对象直接存取到redis中,进行了一些序列化的操作
@Configuration
public class RedisConfig {
// 自己定义了一个 RedisTemplate
@Bean(value = "redisTemplate")
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 我们为了自己开发方便,一般直接使用 <String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
3. 自定义自己的缓存管理
@Slf4j
public class MybatisRedisCache implements Cache {
/**
* 读写锁
*/
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
/**
* 这里使用了redis缓存,使用springboot自动注入
*/
private RedisTemplate<String, Object> redisTemplate;
private String id;
public MybatisRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
}
@Override
public String getId() {
return this.id;
}
@Override
public void putObject(Object key, Object value) {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
try {
if (value != null) {
log.info("key>>>>>>>>>>>>>>>>>>>>>>> {} ", key);
log.info("value>>>>>>>>>>>>>>>>>>>>>>> {}", value);
redisTemplate.opsForValue().set(String.valueOf(key), value);
}
}catch (Exception e) {
e.printStackTrace();
log.error("缓存set出错 ");
}
}
@Override
public Object getObject(Object key) {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
try {
if (key != null) {
return redisTemplate.opsForValue().get(key.toString());
}
} catch (Exception e) {
e.printStackTrace();
log.error("缓存get出错 ");
}
return null;
}
@Override
public Object removeObject(Object key) {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
try {
if (key != null) {
redisTemplate.delete(key.toString());
}
}catch (Exception e) {
e.printStackTrace();
log.error("缓存delete出错 ");
}
return null;
}
@Override
public void clear() {
log.debug("清空缓存");
if (redisTemplate == null) {
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
try {
Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
if (!CollectionUtils.isEmpty(keys)) {
redisTemplate.delete(keys);
}
}catch (Exception e) {
e.printStackTrace();
log.error("缓存清空缓存出错 ");
}
}
@Override
public int getSize() {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
try {
Long size = redisTemplate.execute((RedisCallback<Long>) RedisServerCommands::dbSize);
return size.intValue();
}catch (Exception e) {
e.printStackTrace();
log.error("缓存size存出错 ");
}
return 0;
}
@Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
}
4. 在mapper上加上注解@CacheNamespace
@Repository
@CacheNamespace(implementation= MybatisRedisCache.class,eviction= MybatisRedisCache.class)
public interface PfParkingMapper extends BaseMapper<Parking> {}
如果调用该mapper下的方法,那么会使用redis缓存