本次重点是SpringBoot 2.x整合Redis。
1、业务层代码
package com.example.demo.service.impl;
import com.example.demo.entity.User;
import com.example.demo.mapper.testMapper.TestMapper;
import com.example.demo.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created by McheNike on 2018/11/7.
*/
@Service
public class TestServiceImpl implements TestService{
@Autowired
private TestMapper testMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
@Cacheable(value="myrediscache",keyGenerator="keyGenerator")
public User getUser(String name, String pass) {
return testMapper.getUser(name,pass);
}
@Override
public List<User> getAllUser() {
return testMapper.getAllUser();
}
@Override
@CacheEvict(value="myrediscache",keyGenerator="keyGenerator",condition="#name != null AND #result > 0",beforeInvocation=false,allEntries=true)
public int updateByName(String name,int age) {
redisTemplate.opsForValue().getOperations().delete("myrediscache::com.example.demo.service.impl.TestServiceImpl:getUser:lgflgf");
return testMapper.updateByName(name,age);
}
}
上面 updateByName 方法,测试使用了@CacheEvict 注解和RedisTemplate 类方法清除指定键的缓存;这个地方还存在一点问题待解决。
2、RedisCacheConfig 自定义类代码
package com.example.demo.util;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Created by McheNike on 2018/11/22.
*/
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport{
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate redisTemplate = new RedisTemplate();
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);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
//SpringBoot 1.x 配置CacheManager方法
/*@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate){
RedisCacheManager redisCacheManager = new RedisCacheManager(reidsTemplate);
redisCacheManager.setDefaultExpiration(6000);
return redisCacheManager;
}*/
//SpringBoot 2.x 配置CacheManager方法
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
//============CacheManager 使用Spring默认的 配置
/*RedisCacheManager redisCacheManager = RedisCacheManager.create(redisConnectionFactory);*/
//============使用自定义配置
//RedisCacheConfiguration 的方法都会返回 RedisCacheConfiguration 对象
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
RedisCacheConfiguration rcf = RedisCacheConfiguration.defaultCacheConfig()
//设置缓存过期时间
.entryTtl(Duration.ofMinutes(1L))
//空值不缓存
.disableCachingNullValues()
//键的序列化方法 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
//值的序列化方法 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer));
//可以预先定义 要使用的缓存目录,就可以为不同的缓存设置特定的缓存配置,即:redisCacheConfiguration,如果比较多 可以考虑封装
Set<String> cacheNames = new HashSet<String>();
String[] cacheNamesArr = {"myrediscache1","myrediscache2"};
cacheNames.add(cacheNamesArr[0]);
cacheNames.add(cacheNamesArr[1]);
Map<String,RedisCacheConfiguration> cacheConfigMap = new HashMap<String,RedisCacheConfiguration>();
cacheConfigMap.put(cacheNamesArr[0],rcf);
cacheConfigMap.put(cacheNamesArr[1],rcf.entryTtl(Duration.ofHours(1L)));
RedisCacheManager redisCacheManager = RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(rcf)
.initialCacheNames(cacheNames)
.withInitialCacheConfigurations(cacheConfigMap)
.transactionAware()
.build();
return redisCacheManager;
}
@Bean
@Override
public KeyGenerator keyGenerator(){
return new KeyGenerator(){
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName().toString()).append(":").append(method.getName().toString()).append(":");
if(objects.length>0){
for(Object obj : objects){
sb.append(obj.toString());
}
}
return sb.toString();
}
};
}
}
3、application.properties
####################### tomcat 配置
server.tomcat.uri-encoding=UTF-8
####################### spring 配置
#配置JDBC连接信息
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:ORACAL
spring.datasource.username=lgf
spring.datasource.password=lgf
#配置文件切换
spring.profiles.active=prod
######################## mybais 配置
#配置mybatis的mapper.xml扫描路径
mybatis.mapper-locations=classpath*:com/example/demo/mapper/*/*.xml
logging.level.com.example.demo.mapper=DEBUG
####################### redis 配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=myrediscache
spring.redis.timeout=3000ms
spring.redis.database=0
spring.redis.jedis.pool.min-idle=3
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=-1s