redis常常作为项目中的缓存机制存在。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
<exclusions>
<exclusion>
<groupId>io.lettucegroupId>
<artifactId>lettuce-coreartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
dependency>
关于lettuce以及jedis都是Redis的客户端框架。Redis存在有三个客户端框架,还有一个是Redisson。
spring:
redis:
database: 0
host: ???
port: ???
password:
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
timeout: 0
下一个任务就是要保证你的Redis数据库的连接使用,这里在配置文件中进行配置即可。
/**
* 自定义缓存配置文件,继承CachingConfigurerSupport
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
public RedisConfig() {
super();
}
/**
* 指定使用哪一种缓存机制,用redis连接工厂创建一个redis缓存机制(RedisCacheManager)
* @return
*/
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheManager rcm=RedisCacheManager.create(factory);
return rcm;
}
@Override
public CacheResolver cacheResolver() {
return super.cacheResolver();
}
/**
* 指定默认的key生成方式
* @return
*/
@Override
public KeyGenerator keyGenerator() {
KeyGenerator keyGenerator=new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb=new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for(Object obj:objects){
sb.append(obj.toString());
}
return sb.toString();
}
};
return keyGenerator;
}
@Override
public CacheErrorHandler errorHandler() {
return super.errorHandler();
}
/**
* 使用fastJson作为默认序列化方式,否则需要对实体类进行序列化
* @param factory
* @return
*/
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<Object,Object> redisTemplate=new RedisTemplate<>();
//建议redis连接操作
redisTemplate.setConnectionFactory(factory);
//新定义一个fastJson序列化方式
GenericFastJsonRedisSerializer genericFastJsonRedisSerializer=new GenericFastJsonRedisSerializer();
//配置redis连接
redisTemplate.setDefaultSerializer(genericFastJsonRedisSerializer);
redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(genericFastJsonRedisSerializer);
redisTemplate.setKeySerializer(genericFastJsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 转换返回的object为json
*/
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters(){
//定义一个converter转换器
FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
//添加fastJSON的配置信息
FastJsonConfig fastJsonConfig=new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//在converter中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
//将convert添加到converters中
HttpMessageConverter<?> converter=fastConverter;
return new HttpMessageConverters(converter);
}
}
@Import(RedisConfig.class)
@EnableCaching
在原本的数据库操作的service层实现类加入缓存的概念即可。
@Service
public class UserServiceImpl implements UserService {
private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@Resource
private UserMapper userMapper;
@Autowired
private RedisTemplate redisTemplate;
/**
* 先写入数据库中再写入缓存中
* @param record
* @return
*/
@Transactional
@Override
public int insert(User record) {
//存入数据库
ValueOperations<String,User> operations=redisTemplate.opsForValue();
int result=userMapper.insert(record);
if(result!=0){
String key="user_"+record.getId();
operations.set(key,record);
logger.info("---------写入数据{}到缓存----------",record);
}
return result;
}
/**
* 先写入数据库中,再写入缓存中
* @param record
* @return
*/
@Override
public int insertSelective(User record) {
int result=userMapper.insertSelective(record);
ValueOperations operations=redisTemplate.opsForValue();
if(result!=0){
String key="user_"+record.getId();
operations.set(key,record);
logger.info("---------写入数据{}到缓存----------",record);
}
return result;
}
/**
* 读取数据的时候先从缓存中读取数据,如果缓存中不存在,再从数据库中读出,并存入缓存
* @param id
* @return
*/
@Override
public User selectById(Integer id) {
ValueOperations<String,User> operations=redisTemplate.opsForValue();
String key="user_"+id;
boolean hasKey=redisTemplate.hasKey(key);
if(hasKey){//缓存中存在
User user=operations.get(key);
logger.info("-------从缓存中获取该数据{}----------",user.toString());
return user;
}else{
User user=userMapper.selectById(id);
logger.info("-------------从表中获取数据{}------------",user.toString());
logger.info("------------将数据写入缓存-----------");
operations.set(key,user,5, TimeUnit.HOURS);
return user;
}
}
@Override
public List<User> selectAll() {
return userMapper.selectAll();
}
@Override
//先删除表中的数据,然后删除缓存
public int deleteById(Integer id) {
int result= userMapper.deleteById(id);
String key="user_"+id;
if(result!=0){
boolean hasKey=redisTemplate.hasKey(key);
if(hasKey){
redisTemplate.delete(key);
logger.info("----------从缓存中删除:"+key+"-------------");
}
}
return result;
}
@Override
public int updateById(User user) {
ValueOperations<String,User> operations=redisTemplate.opsForValue();
int result=userMapper.updateById(user);
if(result!=0){//更新表成功
String key="user_"+user.getId();
boolean hasKey=redisTemplate.hasKey(key);
if(hasKey){
redisTemplate.delete(key);
logger.info("----------从缓存中删除------------");
}
User newUser=userMapper.selectById(user.getId());
if(newUser!=null){
operations.set(key,newUser,3,TimeUnit.HOURS);
System.out.println("----------删除之后,更新缓存------------");
}
}
return result;
}
}
主要用于配置该类中会用到的一些共用的缓存配置。
@CacheConfig(cacheNames = "users")//表明该类中所有缓存都存在users集合中
应用到读取数据的方法上,即可缓存的方法,如查找方法,先从缓存中读取,如果没有再调用相应方法获取数据,然后把数据添加到缓存中。
@Cacheable(value = "user", key = "#id")//在user集合中,建是id的值
应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存.
@CachePut(value = "user", key = "#id")//在user集合中,建是id的值
应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据
组合做个cache注解使用
@Caching(
put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.age")
}
}
参考文章:
https://www.cnblogs.com/kingsonfu/p/10409596.html
https://www.cnblogs.com/yixianyixian/p/7427878.html