SpringBoot整合redis

知識點

1.Redis的應用場景?
    1.Token令牌的生成
    2.短信驗證碼的code
    3.可以實現緩存查詢數據 a. 減輕我們的數據庫的訪問壓力 Redis與mysql數據庫不同步的問題
    4.Redis幫助實現計數器
    5.分佈式鎖
    6.延遲操作  分佈式消息中間件

注意:Redis官方是沒有windows版本的,只有linux,這時候因爲 在nio中epoll只有linux操作系統獨有

2.Redis線程模型?
    Redis的採用NIO的IO多路複用原則,也就是一個線程維護多個不同的Redis客戶端連接,從而提高處理
        併發效率和保證線程安全問題.底層採用linux操作系統的epoll技術避免空輪詢.
        
3.Redis數據結構?
    String類型、Hsh類型、List類型、Set類型 、Sorted-Sets
    String: 存儲 set key value ; 獲取 get key
       Hsh: 存儲 hmset key  zhang 28  li 27  liu 23;  獲取  hget key zhang/li/liu
      list: 存儲 lpush key  xiaomi xiaojun xiaoqiang ;獲取 lrange key 0(開始位置) 3(結束)
            移出第一個元素並獲得: lpop key 
       set: 存儲 sadd key xiao1 xiao2 xiao3 xiao3(不能重複,無序) 存儲3個元素
            獲取 smembers key
   sortset:    存儲 zadd key 1 zhang  zadd key 2 li  zadd key 3 zhang
            (序號 值 ;有序的,值不能重複,重複存入,序號會覆蓋之前序號,取值按照序號排序)
            獲取 zrange key 0 10 withscores(帶上此參數,取值包含序號)

4.SpringBoot整合redis使用注意事項:    
        1.使用對象必須序列化 implements Serializable
        2. private RedisTemplate<String ,Object> redisTemplate;使用@Resource注入,
            不能使用@Autowired,因爲按照類型找的autoWired找不到這種泛型類

demo地址:鏈接:https://pan.baidu.com/s/1PKxK4waUF0jfuofqx1Ajxw 
提取碼:fsh3 

 

Springboot整合redis 使用(實體類必須實現序列化)

1.pom.xml依賴

<!--SpringBoot整合redis-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--springboot整合 mybatis -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!--mysql依賴-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.1.46.sec06</version>
		</dependency>

2.application.properties配置文件

server.port=8080
spring.application.name=redis

spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.redis.host=127.0.0.1
spring.redis.password=zsq2170
spring.redis.port=6379
spring.redis.database=1
#連接池最大連接數(使用負值表示沒有限制)
spring.redis.lettuce.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=-1ms
# 連接池中的最大空閒連接
spring.redis.jedis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.jedis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.lettuce.shutdown-timeout=5000ms

3.編寫工具類  這裏redis存Json字符串工具類

@Component
public class RedisUtils {

    @Autowired
    private StringRedisTemplate redisTemplate;

     //不設置超時時間
    public void setString(String key ,String value){
        setString(key,value,null);
    }

    //設置超時時間,單位秒
     public void setString(String key ,String value ,Long timeOut){
         if(null!=timeOut&&timeOut>0){
             redisTemplate.opsForValue().set(key,value);
             redisTemplate.expire(key,timeOut, TimeUnit.SECONDS);
         }else {
             redisTemplate.opsForValue().set(key,value);
         }
     }

     public String getString(String key){
        return redisTemplate.opsForValue().get(key);
     }
}

4.這裏是redis存二進制工具類

@Component
public class RedisObjectUtils {

    @Resource  //此處不可使用@Autowired註解(會找不到redisTemplate)  實則redisTemplate已經初始化,且使用@Autowired會找不到此泛型類
    private RedisTemplate<String ,Object> redisTemplate;

    //不設置超時時間
    public void setObject(String key ,Object value){
        setObject(key,value,null);
    }

    //設置超時時間,單位秒
    public void setObject(String key ,Object value ,Long timeOut){
        if(null!=timeOut&&timeOut>0){
            redisTemplate.opsForValue().set(key,value);
            redisTemplate.expire(key,timeOut, TimeUnit.SECONDS);
        }else {
            redisTemplate.opsForValue().set(key,value);
        }
    }

    public Object getObject(String key){
        return redisTemplate.opsForValue().get(key);
    }
}

5.編寫測試接口

@RestController
public class RedisController {

    @Autowired
    private RedisUtils redisUtils; //redis存字符串工具類

    @Autowired
    private RedisObjectUtils redisObjectUtils; //redis存二進制工具類

    //存json字符串
    @GetMapping("/addUser")
    public String addUser(UserEntity userEntity){
        String json = JSON.toJSONString(userEntity);
        redisUtils.setString("userEntity",json,300L);
        return "存儲成功";
    }

    @GetMapping("/getUser")
    public UserEntity getUser(String key){
        String s = redisUtils.getString(key);
        return JSON.parseObject(s, UserEntity.class);
    }

    //存二進制
    @GetMapping("/addUserBinary")
    public String addUserBinary(UserEntity userEntity){
        redisObjectUtils.setObject("userEntity",userEntity,300L);
        return "存儲成功";
    }

    @GetMapping("/getUserBinary")
    public UserEntity getUserBinary(String key){
        return (UserEntity)redisObjectUtils.getObject(key);
    }
}

6.調用接口測試.注意事項,實體對象一定要實現序列化

 

SpringBoot 整合Redis  註解形式

1.依賴和配置文件一樣 ,添加redis配置類信息

@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport{

    /**
     * 配置自定義redisTemplate
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.setValueSerializer(jackson2JsonRedisSerializer());
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setStringSerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    //json序列化
    @Bean
    public RedisSerializer<Object> jackson2JsonRedisSerializer() {
        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        return serializer;
    }

    /**
     * 配置緩存管理器
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 生成一個默認配置,通過config對象即可對緩存進行自定義配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        // 設置緩存的默認過期時間,也是使用Duration設置 單位分鐘
        config = config.entryTtl(Duration.ofMinutes(10))
                // 設置 key爲string序列化
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                // 設置value爲json序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))
                // 不緩存空值
                .disableCachingNullValues();
        // 使用自定義的緩存配置初始化一個cacheManager
        return RedisCacheManager
                .builder(redisConnectionFactory)
                .cacheDefaults(config)
                .transactionAware()
                .build();
    }

    /**
     * 定製化key生成器
     * 設置  全限定類名 + 方法名 + 參數名 共同組成 key
     * @return key生成器
     * @date 2019/4/12 14:09
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return (Object target, Method method, Object... params) -> {
            StringBuilder sb = new StringBuilder(16);
            sb.append(target.getClass().getName());
            sb.append("_");
            sb.append(method.getName());
            sb.append("_");
            for (int i = 0; i < params.length; i++) {
                sb.append(params[i]);
                if (i < params.length - 1) {
                    sb.append(",");
                }
            }
            return sb.toString();
        };
    }

}

2.測試接口

@RestController
public class MemberController {

    @Autowired
    private MemberMapper memberMapper;

    @Cacheable(cacheNames = "members" ,key = "'getListMember'")
    @GetMapping("/getListMember")
    public List<MemberEntity> getListMember(){
       return memberMapper.fandAll();
    }

    /**
     * Cacheable:可用於類或方法上;在目標方法執行前,會根據key先去緩存中查詢看是否有數據,有就直接
     *  返回緩存中的key對應的value值。不再執行目標方法;無則執行目標方法,並將方法的返回值
     *  作爲value,並以鍵值對的形式存入緩存
     *  condition: 緩存註解檢查緩存中是否有對應的key-value 在 運行目標方法之前,
     */
    @Cacheable(cacheNames = "members" ,key = "'getMemberById'+#id" , condition = "#id !=null")
    @GetMapping("/getMemberById1")
    public MemberEntity getMemberById1(Long id){
        return memberMapper.getMemberById(id);
    }

    /**
     * CachePut:可用於類或方法上;在執行完目標方法後,並將方法的返回值作爲value,並以鍵值對的形式存入緩存中
     */
    @CachePut(cacheNames = "members" ,key = "'getMemberById'+#id")
    @GetMapping("/getMemberById2")
    public MemberEntity getMemberById2(Long id){
        return memberMapper.getMemberById(id);
    }

    /**
     * CacheEvict:可用於類或方法上;在執行完目標方法後,清除緩存中對應key的數據(如果緩存
     *             中有對應key的數據緩存的話)
     * beforeInvocation:此屬性主要出現在@CacheEvict註解中, 默認false 表示先執行方法後結束後刪除緩存
     *                   true->表示方法執行前生效,先刪除緩解再執行方法,不存在緩存沒被刪除情況
     */
    @CacheEvict(cacheNames = "members" ,key = "'getMemberById'+#id" , beforeInvocation = true)
    @GetMapping("/getMemberById3")
    public MemberEntity getMemberById3(Long id){
        return memberMapper.getMemberById(id);
    }

    /**
     * 不指定key , 使用redisCacheConfig裏面的KeyGenerator生成策略 生成key
     * unless : 功能是:是否令註解(在方法執行後的功能)不生效;若unless的結果爲true,則(方法執行後的功能)不生效;
     *                                                          若unless的結果爲false,則(方法執行後的)功能生效。
     */
    @Cacheable(cacheNames = "KeyGenerator" , unless="#result == null")
    @GetMapping("/getMemberById4")
    public MemberEntity getMemberById4(Long id){
        return memberMapper.getMemberById(id);
    }
}

 

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