SpringBoot集成redis + spring cache

Spring Cache集成redis的运行原理:

Spring缓存抽象模块通过CacheManager来创建、管理实际缓存组件,当SpringBoot应用程序引入spring-boot-starter-data-redi依赖后吗,容器中将注册的是CacheManager实例RedisCacheManager对象,RedisCacheManager来负责创建RedisCache作为缓存管理组件,由RedisCache操作redis服务器实现缓存数据操作。实际测试发现默认注入的RedisCacheManager操作缓存用的是RedisTemplate<Object, Object>,因此我们需要自定义cacheManager,替换掉默认的序列化器。

实现代码:

添加mybatis和redis依赖:

复制代码
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
复制代码

添加mapper映射:

复制代码
 1 @Mapper
 2 public interface ProductMapper {
 3     @Select("select * from tb_product where product_id=#{id}")
 4     Product getProductById(Long id);
 5 
 6     @Update("update tb_product set product_name=#{productName},product_desc=#{productDesc} WHERE product_id=#{productId}")
 7     int updateProduct(Product product);
 8 
 9     @Delete("delete from tb_product where product_id=#{id}")
10     void deleteProductById(Long id);
11 
12     @Select("select * from tb_product where product_name=#{productName}")
13     Product getProductByName(String productName);
14 }
复制代码

Service:

复制代码
 1 package com.sl.cache.service;
 2 import com.sl.cache.entity.Product;
 3 import com.sl.cache.mapper.ProductMapper;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.cache.annotation.CacheConfig;
 6 import org.springframework.cache.annotation.CacheEvict;
 7 import org.springframework.cache.annotation.CachePut;
 8 import org.springframework.cache.annotation.Cacheable;
 9 import org.springframework.cache.annotation.Caching;
10 import org.springframework.stereotype.Service;
11 
12 @Service
13 @CacheConfig(cacheNames = "product")
14 public class ProductService {
15     @Autowired
16     private ProductMapper productMapper;
17 
18     @Cacheable(cacheNames = "product1",key = "#root.methodName+'['+#id+']'")
19     //@Cacheable(cacheNames = {"product1","product2"})// 默认key为参数,多个参数SimpleKey [arg1,arg2]
20     //@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'")
21     //@Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")
22     //@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'",condition="#a0>10",unless = "#a0==11") //或者condition="#id>10")
23     public Product getProductById(Long id){
24        Product product =productMapper.getProductById(id);
25        System.out.println(product);
26        return product;
27     }
28 
29     @CachePut(value="product",key = "#result.productId",condition = "#result!=null")
30     public  Product updateProduct(Product product){
31         int count = productMapper.updateProduct(product);
32         System.out.println("影响行数:"+count);
33         if(count>0){
34             return product;
35         }else{
36             return null;
37         }
38     }
39 
40     //@CacheEvict(value="product",key="#id")
41     //@CacheEvict(value="product",allEntries = true) //清楚所有缓存
42     @CacheEvict(value="product",allEntries = true,beforeInvocation = true) //清楚所有缓存
43     public boolean deleteProductById(Long id) {
44         productMapper.deleteProductById(id);
45         return true;
46     }
47 
48     //含有CachePut注解,所以执行这个方法时一定会查询数据库,及时有cacheable注解
49     @Caching(
50             cacheable = {@Cacheable(value="product",key="#productName")},
51             put = {
52                     @CachePut(value="product",key="#result.productId"),
53                     @CachePut(value="product",key="#result.productName")
54             }
55     )
56     public  Product getProductByName(String productName){
57 
58         Product product =productMapper.getProductByName(productName);
59 
60          return product;
61     }
62 }
复制代码

Controller:

复制代码
package com.sl.cache.controller;
import com.sl.cache.entity.Product;
import com.sl.cache.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping("/product/{id}")
    public Product getProduct(@PathVariable("id") Long id) {

        Product product = productService.getProductById(id);
        return product;
    }

    //prooduct?productid=1&productName= &
    @GetMapping("/product")
    public Product updateProduct(Product product) {
        productService.updateProduct(product);
        return product;
    }

    @GetMapping("/delproduct")
    public String delProduct(@RequestParam(value="id") Long id) {

        productService.deleteProductById(id);
        return "ok";
    }

    @GetMapping("/product/name/{productName}")
    public Product getEmpByLastName(@PathVariable("productName") String productName){
        return productService.getProductByName(productName);
    }
}
复制代码

自定义cacheManager实现:

复制代码
 1 package com.sl.cache.config;
 2 import com.sl.cache.entity.Product;
 3 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 4 import org.springframework.cache.CacheManager;
 5 import org.springframework.cache.config.CacheManagementConfigUtils;
 6 import org.springframework.context.annotation.Bean;
 7 import org.springframework.context.annotation.Configuration;
 8 import org.springframework.context.annotation.Primary;
 9 import org.springframework.data.redis.cache.RedisCacheConfiguration;
10 import org.springframework.data.redis.cache.RedisCacheManager;
11 import org.springframework.data.redis.cache.RedisCacheWriter;
12 import org.springframework.data.redis.connection.RedisConnectionFactory;
13 import org.springframework.data.redis.core.RedisTemplate;
14 import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
15 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
16 import org.springframework.data.redis.serializer.RedisSerializationContext;
17 import org.springframework.data.redis.serializer.RedisSerializer;
18 import org.springframework.data.redis.serializer.StringRedisSerializer;
19 
20 import java.net.UnknownHostException;
21 import java.time.Duration;
22 
23 @Configuration
24 public class MyRedisConfig {
25 
26     @Bean(name = "redisTemplate")
27     public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
28 
29         RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
30 
31         redisTemplate.setConnectionFactory(redisConnectionFactory);
32         redisTemplate.setKeySerializer(keySerializer());
33         redisTemplate.setHashKeySerializer(keySerializer());
34         redisTemplate.setValueSerializer(valueSerializer());
35         redisTemplate.setHashValueSerializer(valueSerializer());
36         return redisTemplate;
37     }
38 
39     @Primary
40     @Bean
41     public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
42         //缓存配置对象
43         RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
44 
45         redisCacheConfiguration = redisCacheConfiguration.entryTtl(Duration.ofMinutes(30L)) //设置缓存的默认超时时间:30分钟
46                 .disableCachingNullValues()             //如果是空值,不缓存
47                 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))         //设置key序列化器
48                 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer((valueSerializer())));  //设置value序列化器
49 
50         return RedisCacheManager
51                 .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
52                 .cacheDefaults(redisCacheConfiguration).build();
53     }
54     private RedisSerializer<String> keySerializer() {
55         return new StringRedisSerializer();
56     }
57 
58     private RedisSerializer<Object> valueSerializer() {
59         return new GenericJackson2JsonRedisSerializer();
60     }
61 }
复制代码

启用缓存,添加mybatis Mapper映射扫描:

复制代码
 1 @MapperScan("com.sl.cache.mapper")
 2 @SpringBootApplication
 3 @EnableCaching
 4 public class SpringbootCacheApplication {
 5 
 6     public static void main(String[] args) {
 7         SpringApplication.run(SpringbootCacheApplication.class, args);
 8 
 9     }
10 }
复制代码
原文地址:https://www.cnblogs.com/weizhxa/p/12066452.html