二,Redis的Java客户端

124 阅读4分钟

一,Redis的Java客户端介绍

Java操作Redis的客户端有如下图几种:

image-20231121220932411

Spring Data Redis是规范日志,可以兼容Jedis和Letture

二,Jedis

2.1 快速入门

  1. 引入依赖

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.7.0</version>
    </dependency>
    
  2. 建立连接

    private Jedis jedis;
    
    @BeforeEach
    void setUp() {
        //1.建立连接
        jedis=new Jedis("172.21.35.53",6379);
        //2.设置密码
        jedis.auth("123456");
        //3.选择库
        jedis.select(0);
    }
    
  3. 测试string

    @Test
    void testString() {
        //存入数据
        String result = jedis.set("name", "张三");
        System.out.println("result= "+result);
        //获取数据
        String name = jedis.get("name");
        System.out.println("name= "+name);
    }
    
  4. 释放资源

    @AfterEach
    void tearDown() {
    if(jedis!=null){
        jedis.close();
    	}
    }
    

jedis只需要知道redis的命令即可直接按照上述操作过程操作redis数据库了。

2.2 Jedis连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此推荐使用**]edis连接池**代替Jedis的直连方式。

举例:创建一个工具类,使用工具类配置好的方法来获取Jedis连接对象。

public class JedisConnectionFactory {
    private static JedisPool jedisPool;

    static{
        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
        //最大连接数
        jedisPoolConfig.setMaxTotal(8);
        //最大空闲连接
        jedisPoolConfig.setMaxIdle(8);
        //最小空闲连接
        jedisPoolConfig.setMinIdle(0);
        //设置最长等待时间
        jedisPoolConfig.setMaxWaitMillis(200);
        jedisPool =new JedisPool(jedisPoolConfig,"172.21.35.53",6379,1000,"123456");
    }
    //获取Jedis对象
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

三,SpringDataRedis

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

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

3.1 SpringDataRedis快速入门

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

image-20240630133957837

  1. 引入依赖

    <!--redis依赖-->
    <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>
    
  2. 配置文件

    spring:
      data:
        redis:
          host: 42.192.219.41 #ip
          port: 6379 #端口
          password: yz2763000 #密码
          timeout: 10000ms # 超时时间
          lettuce:
            pool:
              max-active: 8 #最大连接数
              max-idle: 8 #最大空闲连接数
              min-idle: 0 #最小空闲连接数
              max-wait: 100ms #最大等待时间
    

    pool有jedis和lettuce两种,默认采用的是lettuce,如果需要用jedis就需要导入jedis依赖并且排除掉lettuce依赖。

  3. 注入RedisTemplate

    @Autowired
    private RedisTemplate redisTemplate;
    
  4. 编写测试类

    @Test
    public void test(){
        redisTemplate.opsForValue().set("name","normaling");
        Object o = redisTemplate.opsForValue().get("name");
        System.out.println(o);
    }
    

3.2 SpringDataRedis自定义序列化方式

image-20240630140446501

解决方法:RedisTemplate对key和value默认采用的是JdkSerializationRedisSerializer序列化工具的

image-20240630141311000

我们将其key指定初始化为:StringRedisSerializer。将value初始化工具指定为GenericJackson2JsonRedisSerializer即可

  • StringRedisSerializer专门用来处理字符串的序列化工具
  • GenericJackson2JsonRedisSerializer专门用来将转化为Json字符串的序列化工具

操作过程:

  1. 编写配置类

    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)throws Exception {
            //1.创建Template
            RedisTemplate<String,Object> template = new RedisTemplate<>();
            //2.设置连接工厂
            template.setConnectionFactory(redisConnectionFactory);
            //3.key和hashKey都采用String序列化
            template.setKeySerializer(RedisSerializer.string());
            template.setHashKeySerializer(RedisSerializer.string());
            //4.创建json序列化工具
            GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer=
                    new GenericJackson2JsonRedisSerializer();
            //5.设置value和hashValue都采用json序列化
            template.setValueSerializer(genericJackson2JsonRedisSerializer);
            template.setHashValueSerializer(genericJackson2JsonRedisSerializer);
            //6.返回template
            return template;
        }
    
    }
    
  2. 测试类

    @SpringBootTest
    class SpringRedisDemoApplicationTests {
        @Autowired
        private RedisTemplate<String,Object> redisTemplate;
        @Test
        public void test(){
            redisTemplate.opsForValue().set("name","normaling");
            Object o = redisTemplate.opsForValue().get("name");
            System.out.println(o);
        }
    
    }
    

redisTemplate这样配置好后可以自动帮我们序列化和反序列化Java对象

3.3 手动序列化与反序列化

image-20240630143853593

image-20240630144109723

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

@SpringBootTest
class SpringRedisDemoApplicationTests {
    @Autowired
    private StringRedisTemplate redisTemplate;
    //这个是Spring提供的对象序列化工具,也可以用其他序列化工具,随意
    private static final ObjectMapper objectMapper=new ObjectMapper();


    @Test
    public void test() throws JsonProcessingException {
        //1.创建对象
        User data=new User("normaling", 18, new Living(1000, 10));
        //2.序列化对象
        String json = objectMapper.writeValueAsString(data);
        //3.写入数据
        redisTemplate.opsForValue().set("redisTest",json);
        //4.读取数据
        String jsonData =  redisTemplate.opsForValue().get("redisTest");
        //5.反序列化
        User o = objectMapper.readValue(jsonData, User.class);
        System.out.println(o);
    }

}

3.4 SpringDataRedis操作Hash类型案例

SpringDataRedis中操作Hash类型的操作更接近java的map的操作

@Test
public void test() throws JsonProcessingException {
    //用put代替了Hset
    redisTemplate.opsForHash().put("key1","hashKey2","hashValue2");
    Map<String,String> map=new HashMap<>();
    map.put("hashKey1","hashValue1");
    map.put("hashKey2","hashValue2");
    //用putAll代替了Hmset
    redisTemplate.opsForHash().putAll("key1",map);
    //这个是Hget
    Object o = redisTemplate.opsForHash().get("key1", "hashKey2");
    //获取key1里面的所有hashKey
    Set<Object> key1s = redisTemplate.opsForHash().keys("key1");
    //获取key1里面的所有hashValue
    List<Object> values = redisTemplate.opsForHash().values("key1");
    //获取key1里面的所有hashKey和hashValue
    Map<Object, Object> entries = redisTemplate.opsForHash().entries("key1");
}