Spring Boot學習(9):整合Redis

目錄

引言

導入依賴

Redis配置

操作Redis

一、存取字符串

二、存取對象

三、驗證

緩存

一、配置

二、定義聲明式緩存

三、開啓聲明式緩存 

四、驗證

源碼地址 


引言

Spring Boot支持的NoSQL數據庫有Redis、MongoDB,這篇文章我們來介紹Spring Boot整合Redis,以及利用Redis做緩存(注意:本人示例代碼基於Spring Boot 2.0.3,如果Spring Boot版本不相同的話,配置可能也不盡相同,還請各位博友注意自己Spring Boot的版本)。

本文示例代碼:https://github.com/lizitaowork/SpringBoot-demo.git

導入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Redis配置

創建Java類並繼承CachingConfigurerSuport,需要註冊類RedisConnectionFactory,代碼如下(類中的其它配置會在後面講到):

@Configuration //標註此類爲配置類
@EnableCaching //開啓緩存
public class RedisConfig extends CachingConfigurerSupport {
    /**
     *
     * 自定義緩存key生成策略,若想使用這個key, 只需要將註解上keyGenerator值設置爲keyGenerator即可
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object taget, Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(taget.getClass().getName());
                sb.append(method.getName());
                for(Object obj : params){
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 構建連接工廠RedisCacheManager
     * @return
     */
    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory(){
        return new LettuceConnectionFactory();
    }

    /**
     * 構建緩存管理器RedisCacheManager
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory){
        return RedisCacheManager.create(lettuceConnectionFactory);
    }

    /**
     * 序列化RedisTemplate
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){
        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);

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(lettuceConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
}

在application.properties中配置連接Redis相關信息:

#redis數據庫索引,默認爲0
spring.redis.database=0
#redis服務器地址,默認爲localhost
spring.redis.host=localhost
#redis服務器連接端口,默認爲6379
spring.redis.port=6378
#redis服務器連接密碼,默認爲空
spring.redis.password=
#redis連接池最大阻塞等待時間,負值表示沒有限制(springBoot2.0開始,Redis 客戶端驅動現在由 Jedis變爲了 Lettuce)
spring.redis.lettuce.pool.max-wait=10ms
#redis連接池最大空閒連接
spring.redis.lettuce.pool.max-idle=8
#redis連接池中最小空閒連接
spring.redis.jedis.pool.min-idle=0
#redis連接池中最大連接數,負值表示沒有限制
spring.redis.lettuce.pool.max-active=8
#連接超時時間
spring.redis.timeout=1000ms

#設置spring緩存類型爲redis
spring.cache.type=redis

操作Redis

一、存取字符串

存取字符串很簡單,利用RedisTemplate的子類StringRedisTemplate來操作字符串類型,請看代碼:

@Service
public class StringRedisService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 保存數據到redis
     * @param key
     * @param value
     * @return
     */
    public String set(String key, String value){
        stringRedisTemplate.opsForValue().set(key,value);
        if(value.equals(stringRedisTemplate.opsForValue().get(key))){
            return "set successful";
        }
        return "set failed";
    }

    /**
     * 從redis獲取數據
     * @param key
     * @return
     */
    @Cacheable(value = "cache", key = "#key")
    public Object get(String key){
        System.out.println("get方法執行了");
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * 刪除數據
     * @param key
     * @return
     */
    public Object delete(String key){
        return stringRedisTemplate.delete(key);
    }
}

二、存取對象

存取對象,需要序列化RedisTemplate 和實體類,請看代碼:

    /**
     * 序列化RedisTemplate
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){
        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);

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(lettuceConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        //序列化Value爲Jackson2JsonRedisSerializer
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

實體類User代碼如下: 

public class User implements Serializable {
    private static final long serialVersionUID = -8499434066412998323L;
    private String name;
    private Integer age;
}

Service代碼如下:

@Service
public class UserService {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 保存User對象到redis中
     * @param key
     * @param user
     * @return
     */
    public String setUser(String key, User user){
        boolean result = redisTemplate.opsForValue().setIfAbsent(key, user);
        if(result){
            return "set user successful";
        }
        return "set user failed";
    }

    /**
     * 從redis中獲取User對象
     * @param key
     * @return
     */
    public User getUser(String key){
        System.out.println(key + "獲取數據!");
        return (User)redisTemplate.opsForValue().get(key);
    }
}

三、驗證

Controller代碼如下:

@RestController
@RequestMapping("/redis")
public class RedisController {
    @Resource
    private StringRedisService stringRedisService;
    @Resource
    private UserService userService;

    @RequestMapping("/set")
    public String set(){
        return stringRedisService.set("testSet","hello world!");
    }

    @RequestMapping("/get/{key}")
    public Object get(@PathVariable(value = "key") String key){
        return stringRedisService.get(key);
    }

    @RequestMapping("/delete/{key}")
    public Object delete(@PathVariable(value = "key") String key){
        return stringRedisService.delete(key);
    }

    @RequestMapping(value = "/set/user", method = RequestMethod.POST)
    public String setUser(@RequestBody RedisRequestVO<User> param) {
        return userService.setUser(param.getKey(),param.getData());
    }

    @RequestMapping(value = "/get/user/{key}")
    public User setUser(@PathVariable(value = "key") String key) {
        return userService.getUser(key);
    }

 驗證結果如下:

緩存

一、配置

構建緩存管理器RedisCacheManager:

    /**
     * 構建緩存管理器RedisCacheManager
     * @param lettuceConnectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory){
        return RedisCacheManager.create(lettuceConnectionFactory);
    }

自定義緩存key生成策略,若想使用這個key,只需要將註解上KeyGenerator值設置爲keyGenerator即可:

    /**
     * 自定義緩存key生成策略,若想使用這個key, 只需要將註解上keyGenerator值設置爲keyGenerator即可
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object taget, Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(taget.getClass().getName());
                sb.append(method.getName());
                for(Object obj : params){
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

二、定義聲明式緩存

Spring提供了四個註解來定義緩存規則(基於AOP),如下表。

註解 解釋
@Cacheable 在方法執行前先查看緩存中是否有數據,如果有,則直接返回緩存數據;如果沒有,調用方法並將方法返回值放入緩存。
@CachePut 無論怎麼,都將方法的返回值放入緩存中,一般用於更新數據的操作。
@CacheEvict 將一條或多條數據從緩存中刪除。
@Caching 組合多個註解策略在一個方法上。

代碼演示如下:

@Service
public class CacheService {
    private Map<Integer, String> map = new HashMap<>();

    @PostConstruct
    public void init(){
        map.put(1,"張三");
        map.put(2,"李四");
    }

    /**
     * 查找,如果沒有緩存,查詢並做緩存;
     * 如果有緩存,直接拿緩存
     * @param key
     * @return
     */
    @Cacheable(value = "generator", key = "'map_'+#key")
    public String get(int key){
        System.out.println(key + "獲取數據!");
        return map.get(key);
    }

    /**
     * 插入或更新數據
     * 插入或更新成功,緩存到generator,如果緩存已存在則更新緩存
     * @param key
     * @param value
     * @return
     */
    @CachePut(value = "generator", key = "'map_'+#key")
    public String put(int key, String value){
        System.out.println(key + "更新數據爲:"+value);
        map.put(key, value);
        return map.get(key);
    }

    /**
     * 刪除數據並刪除緩存
     * @param key
     * @return
     */
    @CacheEvict(value = "generator", key = "'map_'+#key")
    public String remove(int key){
        System.out.println(key + "刪除數據");
        map.remove(key);
        return "remove success";
    }

    /**
     * 自定義key
     * @param key
     * @return
     */
    @Cacheable(value = "keyGenerator",keyGenerator = "keyGenerator")
    public String cacheOfKeyGenerator(int key){
        System.out.println(key + "獲取數據!");
        return map.get(key);
    }
}

三、開啓聲明式緩存 

在使用聲明式緩存之前,需要開啓聲明式緩存,開啓聲明式緩存的方法非常簡單,只需要在配置類上加上@EnableCaching即可。

四、驗證

同樣的,我們用web方式來驗證,Controller代碼如下:

@RestController
@RequestMapping("/cache")
public class CacheController {
    @Resource
    private CacheService cacheService;

    @RequestMapping("/get")
    public String get(int key){
        return cacheService.get(key);
    }

    @RequestMapping("/put")
    public String put(int key, String value){
        return cacheService.put(key, value);
    }

    @RequestMapping("/remove")
    public String remove(int key){
        return cacheService.remove(key);
    }

    @RequestMapping("/get/generator")
    public String cacheOfKeyGenerator(int key){
        return cacheService.cacheOfKeyGenerator(key);
    }

}

驗證結果如下(僅演示@Cacheable效果,各位博友可自行驗證其他):

源碼地址 

https://github.com/lizitaowork/SpringBoot-demo.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章