SpringBoot 2.x 使用Redis作為項目數據緩存


一、添加依賴

  <!-- 添加緩存支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <!-- 添加Redis緩存支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- 工具類 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.15</version>
        </dependency>

 

二、配置Redis數據庫

spring:
  redis:
    #數據庫索引
    database: 1
    host: 192.168.2.230
    port: 6379
    password:
    jedis:
      pool:
        #最大連接數
        max-active: 8
        #最大阻塞等待時間(負數表示沒限制)
        max-wait: -1
        #最大空閑
        max-idle: 8
        #最小空閑
        min-idle: 0
    #連接超時時間
    timeout: 10000

 

三、Redis配置類

package com.hn.lz.config;

import com.hn.lz.handler.FastJsonRedisSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.lang.reflect.Method;
import java.time.Duration;

/**
 * Created by mll on 2018/7/16.
 */
@Configuration
@EnableCaching  //開啟支持緩存
public class RedisConfiguration extends CachingConfigurerSupport {

    static Logger logger = LoggerFactory.getLogger(RedisConfiguration.class);

    /**
     * 自定義生成key的規則
     *
     * @return
     */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                //格式化緩存key字符串
                StringBuilder sb = new StringBuilder();
                //追加類名
                sb.append(o.getClass().getName()).append(".");
                //追加方法名
                sb.append(method.getName());
                //遍歷參數並且追加
                for (Object obj : objects) {
                    sb.append(".");
                    sb.append(obj.toString());
                }
                System.out.println("調用Redis緩存Key : " + sb.toString());
                return sb.toString();
            }
        };
    }

    /**
     * 設置 redis 數據默認過期時間
     * 設置 Cache 序列化方式
     *
     * @return
     */
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
        configuration = configuration
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer))
                .entryTtl(Duration.ofDays(30));
        return configuration;
    }

}

  

四、自定義存入Redis數據庫值的序列化方式

package com.hn.lz.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.Charset;

/**
 * Created by mll on 2018/7/17.
 */
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    public FastJsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (null == t) {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (null == bytes || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return (T)JSON.parseObject(str, clazz);
    }

}

  

五、使用注解來緩存數據

package com.hn.lz.service;

import com.hn.lz.mapper.UserMapper;
import com.hn.lz.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by mll on 2018/6/21.
 */
@CacheConfig(cacheNames = "user")
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    // ----------------------------------  數據操作 BEGIN  --------------------------------------
    /**
     * 插入數據
     * @param data
     * @return
     */
    @Transactional
    @CachePut(key = "#data.id")
    public User insert(User data){
        userMapper.insert(data);
        return data;
    }

    /**
     * 更新數據
     * @param data
     * @return
     */
    @Transactional
    @CachePut(key = "#data.id")
    public User update(User data){
        userMapper.updateByPrimaryKeySelective(data);
        return data;
    }

    /**
     * 刪除數據
     * @param id
     * @return
     */
    @Transactional
    @CacheEvict(key = "#id")
    public int delete(String id){
        int result = userMapper.deleteByPrimaryKey(id);
        return result;
    }

    /**
     * 得到所有數據列表
     * @return
     */
    public List<User> select() {
        List<User> list = userMapper.selectAll();
        return list;
    }

    /**
     * 根據id查詢數據
     * @param id
     * @return
     */
    @Cacheable(key = "#id")
    public User query(String id){
        User data = userMapper.selectByPrimaryKey(id);
        return data;
    }
    // ----------------------------------  數據操作 END  --------------------------------------
}

  

六、要點

1、注解

  • @CacheConfig這個注解主要用於配置該類中會用到的一些公用的緩存配置。我們也可以不使用該注解,直接通過自己的注解配置緩存集的名字來定義。
@CacheConfig(cacheNames = "user")
@Service
public class UserService

  

  • @CachePut這個注解直接將返回值放入緩存中,通常用於保存和修改方法中。
  • value緩存的名稱,必須指定至少一個。
  • key緩存的 key,可以為空,如果指定要按照 SpEL(Spring Expression Language) 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合。
  • condition:緩存的條件,可以為空,使用 SpEL 編寫,返回true或者false只有為true才進行緩存。
@CachePut(value = "user", key = "#data.id", condition = "#result.username ne 'zhang'")  
public User insert(User data)  

  

  • @Cacheable這個注解在執行前先查看緩存中是不是已經存在了,如果存在,直接返回。如果不存在,將方法的返回值放入緩存。
  • value緩存的名稱,必須指定至少一個。
  • key緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合。
  • condition緩存的條件,可以為空,使用 SpEL 編寫,返回true或者false只有為true才進行緩存。
@Cacheable(value = "user", key = "#id", condition = "#id lt 10")  
public User query(Long id)  

  

  • @CacheEvict這個注解在執行方法執行成功后會從緩存中移除。
  • value緩存的名稱,必須指定至少一個。
  • key緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合。
  • condition緩存的條件,可以為空,使用 SpEL 編寫,返回true或者false只有為true才進行緩存。
  • allEntries是否清空所有緩存內容,缺省為false如果指定為true則方法調用后將立即清空所有緩存。
  • beforeInvocation是否在方法執行前就清空,缺省為false如果指定為true則在方法還沒有執行的時候就清空緩存,缺省情況下,如果方法執行拋出異常,則不會清空緩存。
@CacheEvict(value = "user", key = "#data.id", beforeInvocation = false, condition = "#result.username ne 'zhang'")  
public User delete(User data) 

  

  • @Caching這個注解組合多個Cache注解使用,並且可以自定義注解使用。
@Caching(  
        put = {  
                @CachePut(value = "user", key = "#user.id"),  
                @CachePut(value = "user", key = "#user.username"),  
                @CachePut(value = "user", key = "#user.email")  
        }  
)  
@Caching(  
        put = {  
                @CachePut(value = "user", key = "#user.id"),  
                @CachePut(value = "user", key = "#user.username"),  
                @CachePut(value = "user", key = "#user.email")  
        }  
)  
@Target({ElementType.METHOD, ElementType.TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
@Inherited  
public @interface MyCache {  
}  

@MyCache 
public User save(User data)

  

2、Spring Cache提供了一些供我們使用的SpEL上下文數據

名字 描述 示例
methodName 當前被調用的方法名 #root.methodName
method 當前被調用的方法 #root.method.name
target 當前被調用的目標對象 #root.target
targetClass 當前被調用的目標對象類 #root.targetClass
args 當前被調用的方法的參數列表 #root.args[0]
caches 當前方法調用使用的緩存列表(如@Cacheable(value={"cache1", "cache2"})),則有兩個cache #root.caches[0].name
argument name 當前被調用的方法的參數,如findById(Long id),我們可以通過#id拿到參數 #user.id
result 方法執行后的返回值(僅當方法執行之后的判斷有效,如‘unless’,'cache evict'的beforeInvocation=false) #result

3、Redis常用命令

flushdb:清空當前數據庫。
select index:選擇索引數據庫,index為索引值名,如:select 1
del key:刪除一條指定key的值。
keys *:查看數據庫內所有的key。
flushall:清空所有數據庫。
quit:退出客戶端連接。



作者:maololo
鏈接:https://www.jianshu.com/p/e67e85eb63b2
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM