Redis的Java客户端使用
🚀Jedis快速入门
引入依赖
:
<dependencies> <!--Redis的Java客户端:Jedis 相关依赖--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>4.3.0</version> </dependency> <!--单元测试依赖--> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.9.2</version> <scope>test</scope> </dependency> </dependencies>
测试Java客户端操作Redis
:
测试代码:
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import redis.clients.jedis.Jedis; import java.util.Map; /** * @author .29. * @create 2023-05-08 20:24 */ public class JedisTest { private Jedis jedis; //链接Redis @BeforeEach void setUp(){ //1.建立连接 jedis = new Jedis("192.168.88.128",6379);//参数:ip地址、端口号 //2.设置密码 jedis.auth("123456"); //3.选择库 jedis.select(0); } //测试java客户端操作Redis(String类型操作) @Test public void test1(){ //存入数据 String result = jedis.set("name", ".29."); System.out.println("result = "+result); //获取数据 String name = jedis.get("name"); System.out.println("name = "+name); } //测试java客户端操作Redis(Hash类型操作) @Test public void test2(){ //存入数据 jedis.hset("user:1","name","Little29"); jedis.hset("user:1","age","19"); //获取数据 Map<String, String> result = jedis.hgetAll("user:1"); System.out.println(result); } //关闭资源 @AfterEach void tearDown(){ if(jedis != null){ jedis.close(); } } }
测试结果:
⚪—操作String类型—⚪
⚪—操作hash类型—⚪
🚀Jedis连接池
为什么使用Jedis连接池
:
- Jedis本身是线程不安全 的,并且频繁创建和销毁连接会有性能损耗 ,因此推荐大家使用Jedis连接池代替Jedis的直连 方式。
Jedis连接池——配置工具类
:
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.time.Duration; /** * @author .29. * @create 2023-05-08 20:47 */ public class JedisConnectionFactory { //jedis连接池对象 private static final JedisPool jedisPool; static { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); //最大连接 jedisPoolConfig.setMaxTotal(8); //最大空闲连接 jedisPoolConfig.setMaxIdle(8); //最小空闲连接 jedisPoolConfig.setMinIdle(0); //设置最长等待时间,单位ms jedisPoolConfig.setMaxWait(Duration.ofMillis(1000)); //jedisPoolConfig.setMaxWaitMillis(1000);//较早版本方式 //参数:连接池配置、ip地址、端口号、超时时间、密码 jedisPool = new JedisPool(jedisPoolConfig, "192.168.88.128", 6379,1000,"123456"); } //获取Jedis对象 public static Jedis getJedis(){ return jedisPool.getResource(); } }
🚀SpringDataRedis快速入门
SpringDataRedis简介
:
- SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做
SpringDataRedis
,官网网址:https://spring.io/projects/spring-data-redis - 功能介绍:
- 提供了对不同Redis客户端的整合(Lettuce和Jedis);
- 提供RedisTemplate统一API来操作Reids;
- 支持Redis的发布订阅模型;
- 支持Reids哨兵和Redis集群;
- 支持基于Lettuce的响应式编程;
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化和反序列化;
- 支持基于Redis的JDKCollection实现;
引入依赖(需要是SpringBoot工程)
:
<!--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>
application.yml配置
spring: redis: host: 192.168.88.128 password: 123456 port: 6379 lettuce: pool: max-active: 8 #最大连接 max-idle: 8 #最大空闲连接 max-wait: 100 #连接等待时间 min-idle: 0 #最小空闲连接
注入RedisTemplate,编写测试
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 SpringDataRedisDemoApplicationTests { //注入 @Autowired private RedisTemplate redisTemplate; @Test void contextLoads() { //写入一条String数据 redisTemplate.opsForValue().set("age",19); //获取String数据 Object age = redisTemplate.opsForValue().get("age"); System.out.println("age = "+age); } }
SpringDataRedis的序列化方式
:
- RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化成字节形式,默认是采用JDK序列化。
- 但是此方式得到的结果:可读性差;内存占用大;(缺点)
🚀自定义RedisTemplate的序列化方式
自定义序列化
:
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; /** * @author .29. * @create 2023-05-09 16:12 */ @Configuration public class RedisConfig { @Bean @ConditionalOnSingleCandidate public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){ //创建RedisTemplate对象 RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>(); //设置连接工厂 redisTemplate.setConnectionFactory(connectionFactory); //创建JSON序列化工具 GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); //设置Key序列化(String类型) redisTemplate.setKeySerializer(RedisSerializer.string()); redisTemplate.setHashKeySerializer(RedisSerializer.string()); //设置value序列化(JSON格式) redisTemplate.setValueSerializer(jsonRedisSerializer); redisTemplate.setHashValueSerializer(jsonRedisSerializer); //返回 return redisTemplate; } }
注意
:
- 需要导入SpringMVC依赖或Jackson依赖
Jackson依赖(SpringBoot项目,无须手动指定版本号):
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>
测试
:
@SpringBootTest class SpringDataRedisDemoApplicationTests { //注入 @Resource private RedisTemplate<String,Object> redisTemplate; //测试操作Redis @Test void contextLoads() { //写入一条String数据 redisTemplate.opsForValue().set("age",19); redisTemplate.opsForValue().set("name","自定义姓名"); //获取String数据 Object age = redisTemplate.opsForValue().get("age"); Object name = redisTemplate.opsForValue().get("name"); System.out.println("age = "+age); System.out.println("name = "+name); } }
注意
:
- JSON的序列化方式满足我们的需求,单仍然存在问题:为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。
- 为了节省空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只存储String类型的key和value。当需要存储java对象时,手动完成对象的序列化和反序列化。
🚀StringRedisTemplate序列化
- Spring默认提供了一个StringRedisTemplate类,它的key和value的系列化默认方式为String方式,省去自定义RedisTemplate的过程。
示例
:
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; 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; import org.springframework.data.redis.core.StringRedisTemplate; import javax.annotation.Resource; import java.util.Map; @SpringBootTest class RedisDemoApplicationTests { //使用StringRedisTemplate,手动进行序列化与反序列化 @Resource private StringRedisTemplate stringRedisTemplate; //JSON工具 private static final ObjectMapper mapper = new ObjectMapper(); @Test public void StringRedisTemplateTest() throws JsonProcessingException { //设置对象 User user = new User("name3", 29); //手动序列化 String set = mapper.writeValueAsString(user); //向Redis写入数据 stringRedisTemplate.opsForValue().set("user:3",set); //向Redis获取数据 String get = stringRedisTemplate.opsForValue().get("user:3"); //手动反序列化 User value = mapper.readValue(get, User.class); System.out.println("user:3 = "+value); } @Test public void testHash(){ //向Redis存入Hash键值对 stringRedisTemplate.opsForHash().put("user:4","HashName","name4"); //向Redis获取Hash键值对 Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:4"); System.out.println(entries); } }