SpringBoot和redis的使用

9 篇文章 0 订阅
6 篇文章 0 订阅

spring-boot-starter-data-redis

SpringBoot提供了对redis继承的组件包:spring-boot-starter-data-redis,依赖于spring-data-redis和lettuce,SpringBoot1.0默认使用的是Jedis客户端,2.0换成了Lettuce。

  • Lettuce:是一个可伸缩线程安全的Redis客户端,多个线程共享同一个RedisConnection,它利用优秀Netty NIO框架来有效管理多个连接;
  • Spring Data:是Spring框架中的一个重要项目,目的是为了简化构建基于Spring框架应用过的数据访问。
  • Spring Data Redis:是SpringData项目中一个主要模块,实现对Redis客户端API的高度封装;

相关配置

相关配置
引入依赖包
 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

commons-pool2在使用Lettuce的时候用来创建Redis连接池

application配置
# Redis 数据库索引(默认为 0)
spring.redis.database=0
# Redis 服务器地址
spring.redis.host=localhost
# Redis 服务器连接端⼝
spring.redis.port=6379 
# Redis 服务器连接密码(默认为空)
spring.redis.password=
# 连接池最⼤连接数(使⽤负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池最⼤阻塞等待时间(使⽤负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最⼤空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最⼩空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0
缓存配置

在这里可以为Redis设置一些全局配置,比如配置主键的生产策略KeyGenerator,如不配置会默认使用参数名作为主键。

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    
    @Override
    @Bean
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object param : params) {
                    sb.append(param.toString());
                }
                return sb.toString();
            }
        }
    }
}
测试使用

在单元测试中注入RedisTemplate,String是一种最常用的数据类型,普通的key/value存储都可以归为此类,value不仅是String,也可以是数字。

@RunWith(SpringRunner.class)
@SpringBootTest
class RedisConfigTest {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Test
    public void testString(){
        redisTemplate.opsForValue().set("Hello","world");
        Assert.assertEquals("world",redisTemplate.opsForValue().get("Hello"));
    }
}
redis各种数据类型实践
实体
@Test
    public void testObj(){
        User user = new User("111212@qq.com", "LiMing", "smile", 18);
        ValueOperations<String,User> valueOperations = redisTemplate.opsForValue();
        valueOperations.set("com.example",user);
        User u = valueOperations.get("com.example");
        System.out.println("user: "+u.toString());
    }

在这里插入图片描述

超时失效

Redis在存入每一个数据的时候都可以设置一个超时时间,过了这个时间就会自动删除数据,这种特性非常适合我们对阶段数据的缓存。

 @Test
    public void testExpire() throws InterruptedException {
        User user = new User("111212@qq.com", "LiMing", "smile", 18);
        ValueOperations<String,User> valueOperations = redisTemplate.opsForValue();
        valueOperations.set("com.example",user,100, TimeUnit.MILLISECONDS);
        Boolean exists;
        Thread.sleep(50);
        exists = redisTemplate.hasKey("com.example");
        System.out.println(exists?"it is exists":"it is not exists");
        Thread.sleep(1000);
        exists = redisTemplate.hasKey("com.example");
        System.out.println(exists?"it is exists":"it is not exists");

    }

在这里插入图片描述

删除数据
redisTemplate.delete("deletekey");
Hash

一般我们存储一个键,很自然的就会使用get/set去存储,实际上这并不很好的做法,redis存储一个key会有一个很小的内存,不管你存的这个键有多小,都不会低于这个内存,因此合理的使用Hash可以帮我们节省很多内存。

Hash Set就在哈希表Key中的域的值设为value,如果Key不存在,一个新的哈希表被创建并进行HSET操作,如果域存在于哈希表,旧值将被覆盖。

 @Test
    public void testHash(){
        HashOperations<String,Object,Object> hash = redisTemplate.opsForHash();
        hash.put("hash","hello","world");
        String value =(String) hash.get("hash", "hello");
        System.out.println("hash value :"+value);
    }
List

使用List可以轻松实现一个队列,List典型的应用场景就是消息队列,可以利用List和Push操作,将任务存在List中,然后工作线程再用POP操作将任务取出进行执行。

 @Test
    public void testList(){
        ListOperations<String,String> list = redisTemplate.opsForList();
        list.leftPush("list","it");
        list.leftPush("list","you");
        list.leftPush("list","know");
        String value = (String) list.leftPop("list");
        System.out.println(value.toString());

    }

List 还有很多操作API
Redis List的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用这个数据结构。

Set

当你需要一个存储列表数据,又不希望出现重复数据时,Set是一个很好地选择,并且Set提供了判断某个成员是否在一个Set集合内的重要接口,这个也是List不能提供的。

 @Test
    public void testSet(){
        String key = "set";
        SetOperations<String,String> set = redisTemplate.opsForSet();
        set.add(key,"it");
        set.add(key,"you");
        set.add(key,"you");
        set.add(key,"know");
        Set<String> members = set.members(key);
        for (String member : members) {
            System.out.println("set value :" + member);
        }
    }

在这里插入图片描述
差集

 @Test
    public void testSet(){
        String key1 = "setMore1";
        String key2 = "setMore2";
        SetOperations<String,String> set = redisTemplate.opsForSet();
        set.add(key1,"it");
        set.add(key1,"you");
        set.add(key1,"you");
        set.add(key1,"know");
        set.add(key2,"xx");
        set.add(key2,"know");
        Set<String> members = set.difference(key1,key2);
        Set<String> members1 = set.difference(key2,key1);
        for (String member : members) {
            System.out.println("set value :" + member);
        }
        for (String member : members1) {
            System.out.println("set value :" + member);
        }
    }
ZSet

Redis Sorted Set的使用场景与Set类似,区别是Set不是自动有序的,而Sorted Set可以通过用户额外提供一个优先级参数来为成员排序,并且是插入有序,即自动排序。

可以实现有权重的队列;

 @Test
    public void testSet(){
        String key1 = "zset";
        ZSetOperations<String,String> set = redisTemplate.opsForZSet();
        set.add(key1,"it",1);
        set.add(key1,"you",3);
        set.add(key1,"you",2);
        set.add(key1,"know",0);
        set.add(key1,"xx",1);
        set.add(key1,"know",6);

        Set<String> zsets = set.range(key1, 0, 3);
        for (String zset : zsets) {
            System.out.println("zset value: "+zset);
        }
        System.out.println("******************************");
        Set<String> zsetb = set.rangeByScore(key1, 0, 3);
        for (String s : zsetb) {
            System.out.println("zsetB value: "+s);
        }
    }

Redis Sorted Set 的内部使⽤ HashMap 和跳跃表(SkipList)来保证数据的存储和有序,HashMap ⾥
放的是成员到 Score 的映射,⽽跳跃表⾥存放的是所有的成员,排序依据是 HashMap ⾥存的 Score,
使⽤跳跃表的结构可以获得⽐较⾼的查找效率,并且在实现上⽐较简单。

封装

在实际使用过程中,不会给每一个使用的类都注入redisTemplate来直接使用,一般都会对业务进行简单包装,最后提供出来对外使用。

封账简单插入操作:

@Service
public class RedisService {
    @Autowired
    private RedisTemplate redisTemplate;
    
    // 封装set操作
    public boolean set(final String key,Object value){
        boolean result = false;
        try {
            ValueOperations<Serializable,Object> operation = redisTemplate.opsForValue();
            operation.set(key,value);
            result = true;
        }catch (Exception e){
            // 日志打印
        }
        return result;
    }
    
    // 匹配格式删除
    public void removePattern(final String pattern){
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size()>0){
            redisTemplate.delete(keys);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值