springboot中将redis作为mysql缓存层

Property文件配置

# redis缓存管理配置

#设置缓存类型位redis

spring.cache.type=redis

#配置缓存名称

spring.cache.cache-names=redisCache

#是否允许redis缓存空值

spring.cache.redis.cache-null-values=true

#redis的键前缀

spring.cache.redis.key.prefix=

#缓存超时时间戳,配置为0则不设置超时时间

spring.cache.redis.time-to-live=0ms

#是否启用redis的键前缀

spring.cache.redis.use-key-preficx=true

SpringBoot中一般使用RedisTemplate提供的方法来操作Redis,Springboot会默认配置redistemplate。(这句话我写来干嘛?)

 

java配置

@Configuration
//Redis 缓存配置类
public class RedisConfig extends CachingConfigurerSupport {
  
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisSerializer stringSerializer = new StringRedisSerializer();

//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值//(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
 
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括//private和public
om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.PUBLIC_ONLY);

//  指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比//如String,Integer等会抛出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);

// 使用StringRedisSerializer来序列化和反序列化redis的key值
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer); 

//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);    
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

CacheManager cacheManager = new RedisCacheManager(redisTemplate);
     return cacheManager;
    }
}

上述代码主要是使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值,因为默认使用JDK的序列化方式,JDK的序列化方式,数据在redisclient(可使用redisclient这一工具来操控redis)上不能正常显示。

注:

1,用StringRedisSerializer进行序列化的值,在JavaRedis中保存的内容是一样的

2,用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。

3,用JdkSerializationRedisSerializer进行序列化的值,对于Key-ValueValue来说,是在Redis中是不可读的。对于HashValue来说,比Java的内容多了一些字符。

有些demo在用java(jredis)操控redis时,会使用jredis将数据(对象)存储到redis中,此时可以使用jdk序列化方式将对象存储到redis中,也可以将对象转为json存储到redis中,具体代码不再列出,懂的都懂。

 

还需要在service层加入几个注解,这几个注解在中文社区上解释的并不完整(大家都在CV)

具体可去查看spring官方文档(reference doc或api均可)

使用Redisclient查看数据如下:

springboot中将redis作为mysql缓存层_第1张图片

代码如下:

@CacheConfig(cacheNames="categories")
public class CategoryService {
   @Autowired CategoryDAO categoryDAO;

   @CacheEvict(allEntries=true)
// @CachePut(key="'category-one-'+ #p0")
   public void add(Category bean) {
      categoryDAO.save(bean);
   }
   @CacheEvict(allEntries=true)
// @CacheEvict(key="'category-one-'+ #p0")
   public void delete(int id) {
      categoryDAO.delete(id);
   }
   
   @Cacheable(key="'categories-one-'+ #p0")//这里对应着categories-one-84
//其中#p0的意思是指加有@Cacheable注解的方法中的第一个参数
   public Category get(int id) {
      Category c= categoryDAO.findOne(id);
      return c;
   }

@Cacheable(key="'categories-page-'+#p0+ '-' + #p1")
//这里对应着categories-page-0-5,而categories-all是随着categories-page-0-5一起加//入redis数据库中的
	public Page4Navigator list(int start, int size, int navigatePages) {
    	Sort sort = new Sort(Sort.Direction.DESC, "id");
		Pageable pageable = new PageRequest(start, size,sort);
		Page pageFromJPA =categoryDAO.findAll(pageable);
		
		return new Page4Navigator<>(pageFromJPA,navigatePages);
	}

这里的categories~keys就是利用了@CacheConfig(cacheNames="categories")的categories做前缀,这个sorted set中存有springboot中将redis作为mysql缓存层_第2张图片这四个数据。

而这四个数据的名称(即key)是由@Cacheable(key="'categories-one-'+ #p0")等等决定的。

@CacheEvict(allEntries=true)可以将redis上相同cacheNames的数据清除掉(即categories~keys上的数据)。

 

注:上面涉及到的注解我从spring官方文档找到了,并整理如下,是谷歌机翻的,阅读效果不佳。

@Cacheable注释可让您指定如何通过其key属性生成密钥。您可以使用SpEL选择感兴趣的参数(或其嵌套属性),执行操作,甚至调用任意方法,而无需编写任何代码或实现任何接口。

以下示例使用各种SpEL声明(如果您不熟悉SpEL,请帮忙并阅读Spring Expression Language):

@Cacheable(cacheNames="books", key="#isbn")

public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

 

@Cacheable(cacheNames="books", key="#isbn.rawNumber")

public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

 

@Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")

public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

 

@CacheEvict需要指定一个或多个受操作影响的缓存,允许指定自定义缓存和键解析或条件,并具有一个额外的参数(allEntries),该参数指示是否需要在整个缓存范围内逐出执行

@CacheEvict(cacheNames="books", allEntries=true)

public void loadBooks(InputStream batch)

当需要清除整个缓存区域时,此选项非常有用。如前面的示例所示,而不是逐出每个条目(这会花费很长时间,因为它效率低下),而是通过一次操作删除所有条目。

你可能感兴趣的:(一个商城项目的详解,java,redis,缓存)