目录
1 前言
2 Jedis客户端
2.1 jedis快速入门
2.2Jedis连接池
3 SpringDataRedis
3.1快速入门
3.2ReisTemplate配置序列化工具
3.3 StringRedisTemplate
在Redis官网中提供了各种语言的客户端,地址:https://redis.io/resources/clients/

因为前三个是官方推荐学习的,而第三个又是基于分布式的,不适合基础学习,所以重点学习前两个。
又因为Java中有前两个命令的整合,叫做Spring Data Redis,但有的企业又是只用到了第一个

所以,我们主要学习两个,Jedis和Spring Data Redis
Jedis的官网地址: GitHub - redis/jedis: Redis Java client designed for performance and ease of use.,我们先来个快速入门:
温馨提示:一下代码都是在单元测试里实现的哦~
1. 创建Maven工程
2. 导入Jedis客户端h和单元测试依赖:
redis.clients jedis 3.7.0 org.junit.jupiter junit-jupiter 5.7.0 test
3. 开始实现Jdedis客户端操作
@BeforeEachpublic void setUp(){// 1.new Jedis(ip地址,端口)jedis = new Jedis("192.168.110.128",6379);//2.输入密码 authjedis.auth("123321");//3.选择库jedis.select(0);
} //redis操作@Testpublic void testString(){String result = jedis.set("name", "Jack");System.out.println(result);String name = jedis.get("name");System.out.println(name);} //关闭资源@AfterEachpublic void tearDown(){//健壮性判断if (jedis != null){jedis.close();}} 最后运行结果:

完整代码如下:
package com.itheima.test;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;/*** @Author 华子* @Date 2022/11/19 11:15* @Version 1.0*/
public class JedisTest {private Jedis jedis;//建立连接@BeforeEachpublic void setUp(){// 1.new Jedis(ip地址,端口)jedis = new Jedis("192.168.110.128",6379);//2.输入密码 authjedis.auth("123321");//3.选择库jedis.select(0);}//redis操作@Testpublic void testString(){String result = jedis.set("name", "Jack");System.out.println(result);String name = jedis.get("name");System.out.println(name);}//关闭资源@AfterEachpublic void tearDown(){//健壮性判断if (jedis != null){jedis.close();}}}
因为Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。
连接池创建方法如下代码:
package com.itheima.jedis.util;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisFactory;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;/*** @Author 华子* @Date 2022/11/19 11:41* @Version 1.0*/
public class JedisConnectFactory {private static final JedisPool jedisPool;static {//1.配置连接池JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();//设置最大连接池数量jedisPoolConfig.setMaxTotal(8);//设置最大空闲连接jedisPoolConfig.setMaxIdle(8);//设置最小空闲连接jedisPoolConfig.setMinIdle(0);//设置最大等待时间(当没有空闲连接时,等待的时间)jedisPoolConfig.setMaxWaitMillis(1000);//2.建立连接池(配置参数,ip地址,端口,等待时间,密码)jedisPool = new JedisPool(jedisPoolConfig,"192.168.110.128",6379,1000,"123321");}//3.提供对外调用方法public static Jedis getJedis(){return jedisPool.getResource();}
}
这样连接池就创建成功啦~
而我们Jedis快速入门的时候,建立连接就变为调用这个静态类的getJedis方法了
如图:

整体代码:
package com.itheima.test;import com.itheima.jedis.util.JedisConnectFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;/*** @Author 华子* @Date 2022/11/19 11:15* @Version 1.0*/
public class JedisTest {private Jedis jedis;//建立连接@BeforeEachpublic void setUp(){// 1.new Jedis(ip地址,端口)//jedis = new Jedis("192.168.110.128",6379);jedis = JedisConnectFactory.getJedis();//2.输入密码 authjedis.auth("123321");//3.选择库jedis.select(0);}//redis操作@Testpublic void testString(){String result = jedis.set("name", "Jack");System.out.println(result);String name = jedis.get("name");System.out.println(name);}//关闭资源@AfterEachpublic void tearDown(){//健壮性判断if (jedis != null){jedis.close();}}}
这里提一嘴,关闭资源依然是jedis.close 方法,但是,底层变成了归还线程池

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:Spring Data Redis
提供了对不同Redis客户端的整合(Lettuce和Jedis)
提供了RedisTemplate统一API来操作Redis
支持Redis的发布订阅模型
支持Redis哨兵和Redis集群
支持基于Lettuce的响应式编程
支持基于JDK.JSON.字符串.Spring对象的数据序列化及反序列化
支持基于Redis的JDKCollection实现
SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单:
1.导入依赖坐标
4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.7 com.heima redis-demo 0.0.1-SNAPSHOT redis-demo Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 com.fasterxml.jackson.core jackson-databind org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok
2. 配置( redis springboot中的application.yaml文件 )
spring:redis:host: 192.168.110.128port: 6379password: 123321lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 1000ms
3. 测试代码
@SpringBootTest
class RedisDemoApplicationTests {//注入RedisTemplate@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString() {// 写入一条String数据redisTemplate.opsForValue().set("name", "虎哥");// 获取string数据Object name = redisTemplate.opsForValue().get("name");System.out.println("name = " + name);}
}
RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:

其实这个就是之前写入的 name:虎哥,只不过被序列化成了这个样子。
为了方便我们的可读性,还有释放内存空间,我们要对RedisTemplate进行配置序列化方式
代码如下:
package com.itheima.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;/*** @Author 华子* @Date 2022/11/19 19:47* @Version 1.0*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){//1.创建RedisTemplateRedisTemplate redisTemplate = new RedisTemplate<>();//2.设置连接工厂redisTemplate.setConnectionFactory(connectionFactory);//3.创建序列化工具GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();//4.设置序列化工具//设置keyredisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());//设置valueredisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);//5.返回return redisTemplate;}
}
这样我们在重新运行,就会正常啦~
那么,问题来了,如果传入的是Java对象呢?能不能可以正常的序列化?
直接试一试:
新建一个实体类User
package com.itheima.redis.pojo;import lombok.Data;/*** @Author 华子* @Date 2022/11/19 19:57* @Version 1.0*/@Data
public class User {private String name;private Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}public User() {}
}
传入User对象
@Testvoid testObject(){User user = new User("华子",21);redisTemplate.opsForValue().set("user:100",user);User userInfo = (User) redisTemplate.opsForValue().get("user:100");System.out.println(userInfo);}
依然可以成功序列化Json对象,并且里面还有一个参数,实体类标识,这是用于读取的时候反序列化Java对象的~

尽管JSON的序列化方式可以满足我们的需求,但依然存在一些问题,如图:

为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。
为了减少内存的消耗,我们可以采用手动序列化的方式,换句话说,就是不借助默认的序列化器,而是我们自己来控制序列化的动作,同时,我们只采用String的序列化器,这样,在存储value时,我们就不需要在内存中就不用多存储数据,从而节约我们的内存空间
代码就变成了如下方式(添加了手动序列化和反序列化)
package com.itheima;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.itheima.redis.pojo.User;
import net.minidev.json.JSONObject;
import net.minidev.json.JSONValue;
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;@SpringBootTest
class StringRedisTemplateTest {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Testvoid testString() {stringRedisTemplate.opsForValue().set("name","小帅");String name = stringRedisTemplate.opsForValue().get("name");System.out.println(name);}private static final ObjectMapper mapper = new ObjectMapper();@Testvoid testSaveUser() throws JsonProcessingException {// 创建对象User user = new User("虎哥", 21);// 手动序列化String json = mapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("user:200", json);// 获取数据String jsonUser = stringRedisTemplate.opsForValue().get("user:200");// 手动反序列化User user1 = mapper.readValue(jsonUser, User.class);System.out.println("user1 = " + user1);}}
这样就可以不用占内存啦~

上一篇:第二个词是什么是手臂成语
下一篇:深度学习和神经网络的介绍(一)