Redis的Java客户端

学习Redis第二天

在Redis官网中提供了各种语言的客户端,地址:https://redis.io/clients
在这里插入图片描述
学习Redis的Java客户端的使用:
Jedis
SpringDataRedis



前言

主要内容:
1、Java客户端的种类;
2、Jedis的快速入门;
3、Jedis的连接池;
4、认识SpringDataRedis;
5、RedisTemplate快速入门;
6、RedisTemplate的RedisSerializer(序列化工具);
7、StringRedisTemplate;(序列化工具)


1、Java客户端的种类;

  1. Jedis :以Redis命令作为方法名称,学习成本低,简单实用。但是Jedis实例是线程不安全的,多线程环境下需要基于连接池使用。
  2. lettuce:lettuce是基于Netty实现的,支持同步、异步和响应式编程,并且是线程安全的。支持Redis的哨兵模式、集群模式和管道模式。(Spring默认兼容的客户端)
  3. Redisson:Redisson是一个基于Redis实现的分布式、可伸缩的Java数据结构集合、包含了诸如Map、Queue、Lock、Semaphore、AtomicLong等强大功能;
  4. Spring整合了Jedis和lettuce----Spring Data Redis。

2、Jedis的快速入门;

Jedis的官网地址:https://github.com/redis/jedis
快速入门(5步):
1.先创建一个Maven工程:
在这里插入图片描述
2.在pom.xml中导入Jedis依赖:(引入junit是为了方便测试)
在这里插入图片描述

3.建立与Redis的连接:

public class JedisTest {
    //先创建Jedis对象
    private Jedis jedis;
    @BeforeEach
    void setUp(){
        //建立连接,ip地址是自己虚拟机的ip地址
       jedis = new Jedis("192.168.152.25",6379);

        //密码,自己的密码
        this.jedis.auth("123456");

        //选择数据库(0-15),默认0号库
        this.jedis.select(0);

    }

4.测试:以操作String为例

   @Test
    void testString(){
        //存入数据
        String result = jedis.set("name", "xiaoxin");
        System.out.println("result = " + result);
        String name = jedis.get("name");
        System.out.println("name = " + name);
    }

测试结果:

在这里插入图片描述
证明连接成功并且可以成功写入数据;也可以看出Jedis所使用的对数据操作的命令是和Redis一模一样的。
5.关闭资源

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

3、Jedis的连接池;

Jedis直接连接的缺点:Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此可以使用Jedis连接池代替Jedis直连方式。
创建连接池的方法:
1.可以创建一个工具包然后在里面创建一个连接工厂:

public class JedisConnectionFactory {
    private static final JedisPool jedisPool;

    static{
        //配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
       //最大连接数
        poolConfig.setMaxTotal(8);
        //最大空闲连接
        poolConfig.setMaxIdle(8);
        //最小空闲连接,一段时间没有连接则自动释放
        poolConfig.setMinIdle(0);
        //当连接池没有连接可用,等待时间的设置,超过则报错
        poolConfig.setMaxWaitMillis(1000);
        //创建连接池对象
        jedisPool = new JedisPool(poolConfig,
                "192.168.152.25", 6379, 1000, "123456");
    }
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

2.测试:
把直接连接修改为使用Jedis连接池连接

       //建立连接
       //jedis = new Jedis("192.168.152.25",6379);

        //使用连接池连接
        jedis = JedisConnectionFactory.getJedis();

测试:

  @Test
    void testString(){
        //存入数据
        String result = jedis.set("test", "xiaoxin");
        System.out.println("result = " + result);
        String test = jedis.get("test");
        System.out.println("test = " + test);
    }

-结果–
在这里插入图片描述

4、认识SpringDataRedis

简介:
SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis
内容:
1.提供了对不同Redis客户端的整合(Lettuce和Jedis);
2.提供了RedisTemplate统一API来操作Redis;
3.支持Redis的发布订阅模型;
4.支持基于Lettuce的响应式编程;
5.支持Redis哨兵和Redis集群;
6.支持基于JDK、JSON、字符串、Spring对象的数据序列化和反序列化;
7.支持基于Redis的JDKCollection实现。

5、SpringDataRedis快速入门:

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作,并且将不同的数据类型的操作API封装到了不同的类型中:
在这里插入图片描述
SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单:
1、创建SpringBoot工程:
在这里插入图片描述
勾选上SpringDataRedis:
在这里插入图片描述

2、导入依赖:
勾选之后会自动导入依赖:(里面一些其他的依赖是因为勾选了一些工具后也自动导入了)

  <dependencies>
        <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>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

其中最重要的依赖是Redis依赖和连接池依赖:
在这里插入图片描述
3、配置文件:
在resources目录下创建一个application.yaml文件,里面配置一些关于连接Redis的信息(如ip地址,密码,连接池信息等)
在这里插入图片描述

4、注入RedisTemplate

@Autowired
    private RedisTemplate redisTemplate;

5、编写测试

@SpringBootTest
class ReidsDemoApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void testString() {
        //写入一条数据
        redisTemplate.opsForValue().set("name","小飞");
        //获取写入数据的值
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
    }

测试结果:
在这里插入图片描述

6、RedisTemplate的RedisSerializer(序列化工具)

RedisTemplate的序列化问题:
在使用RedisTemplate来操作数据时,默认的操作方式是把数据都当成一个对象进行写入,如key-value都是Object类型:
在这里插入图片描述
这就会导致存储在Redis中存储的数据都是经过RedisTemplate序列化之后在存储进去的,当我们在Redis中查看数据时会发现:
在这里插入图片描述
在name中存储的是一个经过序列化的字符串。
这个问题的缺点:
·可读性差
·内存占用较大
解决方法:改变RedisTemplate的序列化方式。
自定义RedisTemplate的序列化方式,代码如下:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
        //创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();

        //设置连接工厂
        template.setConnectionFactory(connectionFactory);
        //创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //设置value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        //返回
        return template;
    }
}

测试写入一个对象:
先创建一个对象:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private Integer age;
}

写入对象:

 @Test
    void testSaveUser(){
        redisTemplate.opsForValue().set("MyObject",new User("小飞",21));
        User o = (User) redisTemplate.opsForValue().get("MyObject");
        System.out.println("o = " + o);
    }

控制台打印的结果:
在这里插入图片描述

在图形化工具查看结果:
在这里插入图片描述
可以看到已经成功写入,并且在获取结果打印到控制台时,还能反序列化成User对象。
如何反序列化的:可以看到在写入对象时,还写入了Class这个属性,对应的就是对象的字节码名称,在反序列化才能读取到这个类的名称,然后再反序列化。

7、StringRedisTemplate;(序列化工具)

问题:虽然这样的序列化方式可以满足需求,但是在反序列化的过程中为了要知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。

解决方案:为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。如图:

在这里插入图片描述
这样的话又要重新定义StringRedisTemplate,好消息是,Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式,省去了我们自定义RedisTemplate的过程,直接注入StringredisTemplate就可以使用了:

 @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //JSON工具,作用就是把一个对象转JSON
    private static final ObjectMapper mapper = new ObjectMapper();
    @Test
    void testSaveUser() throws JsonProcessingException {
        //创对象
        User user = new User("小兔子", 12);
        //手动序列化对象
        String json = mapper.writeValueAsString(user);
        //写入数据
        stringRedisTemplate.opsForValue().set("name",json);
        //取出数据
        String jsonUser = stringRedisTemplate.opsForValue().get("name");
        //反序列化
        User user1 = mapper.readValue(jsonUser, User.class);
        System.out.println("user1 = " + user1);

    }

图形化工具查看结果:
在这里插入图片描述

控制台打印的结果:
在这里插入图片描述
总结两种方案:
在这里插入图片描述

总结

学习了Redis的java客户端Jedis和SpringDataRedis的使用,并解决了一些用法上的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值