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);
    }
}

 

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