Redis学习 --redis的Java客户端(SpringDataRedis)

概述:SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis

特点:

  1. 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  2. 提供了RedisTemplate统一API来操作Redis
  3. 支持Redis的发布订阅模型
  4. 支持Redis哨兵和Redis集群
  5. 支持基于Lettuce的响应式编程
  6. 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
  7. 支持基于Redis的JDKCollection实现

 

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中,常用的API如下:

API 返回值类型 说明
redisTemplate.opsForValue() ValueOperations 操作String类型数据
redisTemplate.opsForHash() HashOperations 操作Hash类型数据
redisTemplate.opsForList() ListOperations 操作List类型数据
redisTemplate.opsForSet() SetOperations 操作Set类型数据
redisTemplate.opsForZSet() ZSetOperations 操作SortedSet类型数据
redisTemplate   通用的命令

 

一:RedisTemplate使用的入门案例:

1、创建一个SpringBoot工程

 

2、引入依赖

<!--redis依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--common-pool依赖-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
<!--testng依赖-->
<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.1.0</version>
</dependency>

3、编写连接配置文件application.yml

spring:
  redis:
    host: 192.168.80.132
    port: 6379
    password: root
    lettuce:
      pool:
        max-active: 8 #最大连接数
        max-idle: 8 #最大空闲连接
        max-wait: 100 #连接等待时间
        min-idle: 0 #最小空闲连接

4、在测试类中进行测试。

package com.lrc;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class RedisSpringdataApplicationTests {

    //注入RedisTemplate
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void testString(){
        //插入一条string类型的数据
        redisTemplate.opsForValue().set("name","李四");
        //读取一条string类型数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name="+name);

    }


}

5、运行得到结果:

 

二、RedisTemplate的序列化机制

引入:在上述入门案例中,我们向redis插入了一条{"name":"李四"}的数据,但是我们在redis可视化界面看到插入的数据显示为如下图:

可以看到,在redis中存储我们上述案例插入的数据并不是按照我们预期的结果展示,这是因为:RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化。所以我们可以采用自定义序列化方式改成我们想要的样式。

自定义序列化步骤:

1、引入JackSon依赖,处理序列化操作

<!--Jackson依赖-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

2、在redis.config包下新建一个RedisConfig配置类

package com.lrc.redis.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

/**
 * @param
 * @author lrc
 * @create 2022/4/4
 * @return
 * @description
 **/

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String ,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //创建一个redisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        //设置序列化工具
        GenericJackson2JsonRedisSerializer jonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //key和hashkey采用String序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //value和hashValue采用JSON序列化
        template.setValueSerializer(RedisSerializer.json());
        template.setHashValueSerializer(RedisSerializer.json());
        return template;
    }
}

3、测试自定义序列化机制后的结果

package com.lrc;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class RedisSpringdataApplicationTests {

    //注入RedisTemplate
    @Autowired
    private RedisTemplate<String ,Object> redisTemplate;

    @Test
    void testString(){
        //插入一条string类型的数据
        redisTemplate.opsForValue().set("name","李四");
        //读取一条string类型数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name="+name);

    }


}

 

 

 

下面我们验证下向Redis写入对象的结果:

1、在redis.pojo包下新建一个实体类User:

package com.lrc.redis.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @param
 * @author lrc
 * @create 2022/4/4
 * @return
 * @description
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private Integer age;
}

2、测试下向redis插入一个对象数据的结果:

@Test
void testAddUser(){
    //写入数据
    redisTemplate.opsForValue().set("user:100",new User("王五",21));
    //读取数据
    User user = (User) redisTemplate.opsForValue().get("user:100");
    System.out.println("user="+user);
}

3、执行测试

出现这种结果的原因是因为:RedisTemplate存在一个自动反序列机制,那么它就需要存起反序列化的对象才能知道对哪个对象进行反序列化,显然这种结果往往我们也不想要,因为会有很大的内存开销,下面我们再进行一个优化方案。

 

Spring默认还提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去了我们自定义RedisTemplate的过程。

使用步骤:

1、测试类中注入StringRedisTemplate

@Autowired
private StringRedisTemplate stringRedisTemplate;

2、new一个序列化工具:

// JSON工具
private static final ObjectMapper mapper = new ObjectMapper();

3、手动编写序列化操作:

@Test
void testAddUserMyself() throws JsonProcessingException {
    //创建对象
    User user=new User("Tom",29);
    //手动序列化
    String json = mapper.writeValueAsString(user);
    //写入数据
    stringRedisTemplate.opsForValue().set("user:300",json);
    //读取数据
    String s = stringRedisTemplate.opsForValue().get("user:300");
    //进行反序列化
    User user1 = mapper.readValue(s, User.class);
    System.out.println("user1="+user1);
}

4、执行测试

在使用看来,还是使用StringRedisTemplate比较符合我们的实际应用场景。

 

 

三:使用StringRedisTemplate操作其他数据类型练习

1、操作Hash类型

(1)使用put方法逐条村数据

@Test
void testHash(){
    //存数据
    stringRedisTemplate.opsForHash().put("user:400","name","hashName");
    stringRedisTemplate.opsForHash().put("user:400","age","hashAge");
    stringRedisTemplate.opsForHash().put("user:400","handsome","hashYes");
    //取数据
    Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:400");
    System.out.println("entries="+entries);
}

(2)使用putAll方法批量存数据

@Test
void testHash02(){
    //准备一个HashMap数据
    HashMap<Object,Object> map=new HashMap<>();
    map.put("name","lrc");
    map.put("age","18");
    map.put("description","很晒气的小伙子");

    //存入上述hashMap数据
    stringRedisTemplate.opsForHash().putAll("user:500",map);
    //取数据
    Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:500");
    System.out.println("entries="+entries);
}

 

2、操作List类型数据

(1)逐条插入数据leftPush或者rightPush

@Test
void testList(){
    //存数据
    stringRedisTemplate.opsForList().leftPush("aKey","aValue");
    stringRedisTemplate.opsForList().leftPush("bKey","bValue");
    //取数据
    String aKey = stringRedisTemplate.opsForList().leftPop("aKey");
    String bKey = stringRedisTemplate.opsForList().leftPop("bKey");
    System.out.println("akey="+aKey+"\n"+"bKey="+bKey);
}

(2)、一次插入一个ArrayList集合数据

@Test
void testList02(){
    //创建一个ArrayList
    ArrayList list=new ArrayList();
    list.add("张三");
    list.add("李四");
    list.add("王五");
    list.add("赵六");
    //存数据
    stringRedisTemplate.opsForList().leftPushAll("student",list);
    //读数据
    for (int i=0;i<list.size();i++){
        String student = stringRedisTemplate.opsForList().leftPop("student");
        System.out.println("student="+student);
    }
}

 

3、操作Set类型

@Test
void testSet(){
    stringRedisTemplate.opsForSet().add("setData","data1","data2","data3","data4");
    Set<String> setData = stringRedisTemplate.opsForSet().members("setData");
    System.out.println("setData="+setData);
}

 

 

4、操作SortedSet类型

@Test
void testSortSet(){
    //存数据
    stringRedisTemplate.opsForZSet().add("key","value1",80);
    stringRedisTemplate.opsForZSet().add("key","value2",90);
    stringRedisTemplate.opsForZSet().add("key","value3",95);
    stringRedisTemplate.opsForZSet().add("key","value4",98);
    //取数据
    Set<String> key = stringRedisTemplate.opsForZSet().range("key", 0, 2);
    System.out.println("key="+key);
}

posted @ 2022-04-04 20:17  筱筱创  阅读(232)  评论(0编辑  收藏  举报