当前位置: 首页 > news >正文

Jedis,SpringDataRedis

快速入门

导入依赖

        <!--jedis--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version></dependency><!--单元测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.7.0</version><scope>test</scope></dependency>

测试代码

package com.example;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;public class JedisTest {private Jedis jedis;@BeforeEachvoid setUp() {jedis = new Jedis("192.168.168.168", 6379);jedis.auth("123456");jedis.select(0);}@Testvoid test() {String name = jedis.get("name");System.out.println(name);}@AfterEachvoid tearDown() {if(jedis != null){jedis.close();}}
}

jedis连接池

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

package com.example.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;public class JedisConnectionFactory {private static 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.168.168", 6379, 1000, "123456");}//连接超时时间 1000毫秒public static Jedis getJedis() {return jedisPool.getResource();}
}

修改后这样获取jedis对象

    @BeforeEachvoid setUp() {jedis = JedisConnectionFactory.getJedis();jedis.auth("123456");jedis.select(0);}

SpringDataRedis

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:Spring Data Redis

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

快速入门

导入依赖

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

配置redis

spring:data:redis:host: 192.168.168.168port: 6379password: 123456database: 0lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100ms

测试

package com.example;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
public class RedisTemplateTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void test01() {redisTemplate.opsForValue().set("name","lihua");System.out.println(redisTemplate.opsForValue().get("name"));}
}

自定义序列化

jdk序列化(默认的序列化方式)的问题

 进行如上测试后,发现并没有修改key为name的值为lihua,而是出现了这样的结果

原因如下

RedisTemplate可以接收任意Object作为值写入Redis:

只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:


缺点:
- 可读性差
- 内存占用较大

***************************************************

自定义序列化方式为json序列化

首先写一个RedisTemplate的配置

package com.example.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;@Configuration
public class RedisTemplateConfig {@Bean//RedisConnectionFactory是spring内置的,在项目启动时会自动装配,因此作为参数传入即可public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {//创建RedisTemplate对象RedisTemplate<String, Object> template = new RedisTemplate<>();//设置连接工厂template.setConnectionFactory(factory);//创建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();//设置key的序列化   RedisSerializer是redis的一个序列化器template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());//设置value的序列化template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);//返回return template;}
}

在springboot项目启动时,这个bean就会被加载

重新测试

    @Testpublic void test01() {redisTemplate.opsForValue().set("name","zhaosi");System.out.println(redisTemplate.opsForValue().get("name"));}

测试结果如下

 

符合我们的预期

*********************************

也可以存入自定义对象

    @Testpublic void test02() {User u1 = new User(1, "laoda", 24);redisTemplate.opsForValue().set("user:001", u1);}@Testpublic void test03() {User user = (User) redisTemplate.opsForValue().get("user:001");System.out.println(user);}

测试结果如下

整体可读性有了很大提升,并且能将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。这会带来额外的内存开销。  (我们将用StringRedisTemplate进行改进)

SpringRedisTemplate 

为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器(这样value就不用存储对象的字节码文件了),要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。

因为存入和读取时的序列化及反序列化都是我们自己实现的,SpringDataRedis就不会将class信息写入Redis了。

这种用法比较普遍,因此SpringDataRedis就提供了RedisTemplate的子类:StringRedisTemplate,它的key和value的序列化方式默认就是String方式。

导入jackson依赖

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

省去了我们自定义RedisTemplate的序列化方式的步骤,而是直接使用就好了

@SpringBootTest
public class StringRedisTemplateTest {@Autowiredprivate StringRedisTemplate stringRedisTemplate;private static final ObjectMapper mapper = new ObjectMapper();@Testpublic void test() throws JsonProcessingException {User u1 = new User(2, "赵四", 25);//手动序列化String json = mapper.writeValueAsString(u1);System.out.println("序列化后的json字符串:"+json);//写入数据stringRedisTemplate.opsForValue().set("user:002",json);//获取数据String jsonUser = stringRedisTemplate.opsForValue().get("user:002");//反序列化User user = mapper.readValue(jsonUser, User.class);System.out.println("反序列化得到的结果:"+user);}
}

可以看到,里面是没有对象的字节码的

http://www.lryc.cn/news/434856.html

相关文章:

  • 增量模型的优点例题
  • 求绝对值
  • AlphaNovel的身份验证失败了..........
  • Sapiens:人类视觉模型的基础
  • “健康中国 医路无忧——公益联盟”积极响应,国内首支公益陪诊师志愿队伍正式成立
  • Java 创建对象方法的演变
  • Netty中用到了哪些设计模式
  • 第67期 | GPTSecurity周报
  • Chrome 浏览器插件获取网页 window 对象(方案三)
  • 动态规划-分割回文串ⅡⅣ
  • Python编码系列—Python项目维护与迭代:持续进化的艺术
  • 【鸿蒙开发工具报错】Build task failed. Open the Run window to view details.
  • k8s集群部署:容器运行时
  • PHP7 的内核结构
  • JVM合集
  • tomcat端口被占用解决方法
  • 全新的训练算法:Reflection 70B进入大众的视野
  • 静态标注rtk文件参数解析
  • TensorFlow和PyTorch小知识
  • Java证书信息收集
  • flink写入hudi MOR表
  • 智能工厂程序设计 之-2 (Substrate) :三个世界--“存在的意义”-“‘我’的价值的实现” 之2
  • 概要设计例题
  • 注册表模式:使用注册表和装饰器函数的模块化设计
  • 怎样将vue项目 部署在ngixn的子目录下
  • FPGA开发:Verilog数字设计基础
  • 哈希表,算法
  • Java数组的定义及遍历
  • 【电路笔记】-反相运算放大器
  • 【电子通识】半导体工艺——刻蚀工艺