# 一、POM ```xml org.springframework.boot spring-boot-starter-data-redis ``` # 二、使用注解 + 配置redis ```java //开启基于注解的配置 @EnableCaching @Configuration public class RedisConfig { /** * redis数据库自定义key的命名空间 */ public static final String REDIS_DATABASE_KEY="tmall_springboot"; public static final String REDIS_CATEGORY_KEY="category"; public static final String REDIS_ORDER_ITEM_KEY="orderItem"; public static final String REDIS_ORDER_KEY="order"; public static final String REDIS_PRODUCT_KEY="product"; public static final String REDIS_PROPERTY_KEY="property"; public static final String REDIS_PROPERTY_VALUE_KEY="propertyValue"; public static final String REDIS_REVIEW_KEY="review"; public static final String REDIS_USER_KEY="user"; public static final String REDIS_PRODUCT_IMAGE_KEY="productImage"; /** * 自动配置的redisTemplate,存在序列化问题,会导致存入redis数据库中的数据,不容易看清所以需要自己配置 */ /** * 配置自定义redisTemplate * @return */ @Bean RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory,RedisSerializer redisSerializer) { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 设置键(key)的序列化采用StringRedisSerializer。 redisTemplate.setKeySerializer(new StringRedisSerializer()); // 设置值(value)的序列化采用Jackson2JsonRedisSerializer。 redisTemplate.setValueSerializer(redisSerializer); // 设置hashKey的序列化 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(redisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 配置json序列化器(我们使用jackson的序列化器) */ @Bean public RedisSerializer redisSerializer(){ Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); return jackson2JsonRedisSerializer; } /** * 配置redis缓存管理器,管理注解版的缓存 */ @Bean public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory,RedisSerializer redisSerializer) { RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); //设置Redis缓存有效期为10分钟 RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) //ttl .entryTtl(Duration.ofHours(2)); return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration); } } ``` + @Cacheable 先从redis数据库中 按照当前key查找,有没有。如果redis中有,是不会走当前该方法的,如果没有再调用方法返回结果,如果结果不为null将其缓存到数据库中(一般用于find) ```java @Cacheable(value = RedisConfig.REDIS_DATABASE_KEY, key = "'user-'+#p0", unless = "#result==null") @Override public User getUserByName(String name) { UserExample example = new UserExample(); example.createCriteria().andNameEqualTo(name); List users = userMapper.selectByExample(example); if(users.size()==0){ return null; } return users.get(0); } ``` value:key的一部分(前缀),主要是指明数据放在那个key范围 key:key的主体,#p0:指明取出第一个参数 #p1:指明取出第二个参数。。。依此类推 unless:结果为true,将当前的数据结果不保存到redis,#result:指明取出数据库中返回的结果 condition 结果如果为true,将当前数据保存到redis + @CachePut 主要用于向数据库中插入数据,向数据中插入数据的时候,会将返回的int类型,放入redis中缓存,当然是有选择性的(一般用于insert) ```java @CachePut(value = RedisConfig.REDIS_DATABASE_KEY,key = "'user-insert-'+#p0.id",unless = "#result==0") @Override public int insert(User record) { return userMapper.insert(record); } ``` value:key的一部分,命名空间 key:指定key的名称 unless:满足条件,则不将返回的结果放入redis condition: 满足条件,则将返回的结果放入redis + @CacheEvict 满足条件则移除当前key在redis中的数据(一般用于update/delete) ```java @CacheEvict(value = RedisConfig.REDIS_DATABASE_KEY,key = "'user-'+#p0.id",condition = "#result==1") @Override public int updateByPrimaryKey(User record) { return userMapper.updateByPrimaryKey(record); } ``` value: 同理命名空间 key: key名称 condition:满足什么条件从缓存中移除指定的key AllEntries:true/false 是否移除命名空间下的所有key # 三、硬编码 使用StringRedisTemplate