Jedis
API 文档
在线文档: https://www.mklab.cn/onlineapi/jedis/
Jedis 介绍
Jedis 工作示意图
Java 程序操作Redis 的工具
示意图
Jedis 操作Redis 数据
快速入门
- 创建maven 项目
注意二步是路径配置自己想放哪里 三步是 定义包的层次结构 嫌弃麻烦的也可以不设置 然后确认就可以了
- 修改pom.xml , 增加依赖
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
- 创建Jedis_.java
public class Jedis_ {
//连接Redis
//1. 如果Redis配置了密码,则需要进行身份校验
//2. 因为需要连接到redis端口,比如6379, 就需要配置防火墙,放开端口
//3. 注意修改bind,支持远程连接.
@Test
public void con() {
Jedis jedis = new Jedis("192.168.198.135", 6379);
jedis.auth("foobared");
String res = jedis.ping();
System.out.println("连接成功 ping 返回结果=" + res);
jedis.close();//关闭当前连接,注意并没有关闭Redis
}
//key操作
@Test
public void key() {
Jedis jedis = new Jedis("192.168.198.135", 6379);
jedis.auth("foobared");
//设置key
jedis.set("k1", "v1");
jedis.set("k2", "v2");
jedis.set("k3", "v3");
//获取key
Set<String> keys = jedis.keys("*");
for (String key : keys) {
System.out.println("key==>" + key);
}
//判断key是否存在,ttl
System.out.println(jedis.exists("k1"));//T
System.out.println(jedis.ttl("k2"));//-1
System.out.println(jedis.get("k3"));//v3
//关闭连接
jedis.close();
}
//string
@Test
public void string() {
Jedis jedis = new Jedis("192.168.198.135", 6379);
jedis.auth("foobared");
//批量设置k-v
jedis.mset("k1", "jack", "k2", "scott", "k3", "hsp");
//批量获取v
List<String> mget = jedis.mget("k1", "k2");
for (String s : mget) {
System.out.println("s-->" + s);
}
jedis.close();
}
//list
@Test
public void list() {
Jedis jedis = new Jedis("192.168.198.135", 6379);
jedis.auth("foobared");
//添加list数据
jedis.lpush("name_list", "jack", "tom", "nono");
List<String> name_list = jedis.lrange("name_list", 0, -1);
for (String name : name_list) {
System.out.println("name--->" + name);
}
//关闭连接
jedis.close();
}
//set
@Test
public void set() {
Jedis jedis = new Jedis("192.168.198.135", 6379);
jedis.auth("foobared");
jedis.sadd("city", "北京", "上海");
jedis.sadd("city", "广州");
jedis.sadd("city", "深圳");
Set<String> smembers = jedis.smembers("city");
for (String city : smembers) {
System.out.println("city-->" + city);
}
jedis.close();
}
//hash
@Test
public void hash() {
Jedis jedis = new Jedis("192.168.198.135", 6379);
jedis.auth("foobared");
//设置
jedis.hset("hash01", "name", "李白");
jedis.hset("hash01", "age", "30");
//获取
String name = jedis.hget("hash01", "name");
System.out.println("name=>" + name);
//先构建一个map,然后加入
Map<String, String> maps = new HashMap<String, String>();
maps.put("job", "java工程师");
maps.put("name", "smith");
maps.put("email", "smith@qq.com");
jedis.hset("hash02", maps);
//取出看看
List<String> person =
jedis.hmget("hash02", "job", "name", "email");
for (String s : person) {
System.out.println("s===>" + s);
}
jedis.close();
}
//zset-有序集合
@Test
public void zset() {
Jedis jedis = new Jedis("192.168.198.135", 6379);
jedis.auth("foobared");
//添加
jedis.zadd("hero", 1, "关羽");
jedis.zadd("hero", 2, "张飞");
jedis.zadd("hero", 5, "黄忠");
jedis.zadd("hero", 3, "赵云");
jedis.zadd("hero", 4, "马超");
//取出
Set<String> heroes = jedis.zrange("hero", 0, -1);//按照评分从小到大
//Set<String> heroes = jedis.zrevrange("hero", 0, -1);//按照评分从大到小
for (String hero : heroes) {
System.out.println("hero= " + hero);
}
jedis.close();
}
}
连接Redis 注意事项
1、确保ip:6379 是连通的, 注意打开防火墙的6379 端口
● 设置开放的端口号
firewall-cmd --add-port=6379/tcp --permanent
● 重启防火墙
firewall-cmd --reload
● 查看防火墙
firewall-cmd --list-all
2、如果redis 你设置了密码, 需要执行jedis.auth(“密码”);进行权限验证
Spring Boot2 整合Redis
需求分析/图解
- 在springboot 中, 整合redis
- 可以通过RedisTemplate 完成对redis 的操作, 包括设置数据/获取数据
- 比如添加和读取数据
注意redis存储汉字是以16进制存储的
具体整合实现
创建maven web 项目
流程和上面一样这里就不截图了
修改pom.xml - 引入相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hspedu</groupId>
<artifactId>redis_springboot</artifactId>
<version>1.0-SNAPSHOT</version>
<name>redis_springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<!--不要带版本号,防止冲突, 使用版本仲裁即可-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置
application.properties
– 完成redis 的基本配置
#Redis 服务器地址
spring.redis.host=192.168.198.130
#Redis 服务器连接端口
spring.redis.port=6379
#Redis 如果有密码,需要配置, 没有密码就不要写
spring.redis.password=hspedu
#Redis 数据库索引(默认为0)
spring.redis.database=0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
redis 配置类
1、是对要使用的RedisTemplate bean 对象的配置, 可以理解成是一个常规配置.
2、这个和 Spring中的JdbcTemplate,设计理念类似 如果感兴趣可以去专栏主流框架里面的JdbcTemplate博客看看
3、如果不配置, springboot 会使用默认配置, 这个默认配置, 会出现一些问题, 比如:redisTemplate 的key 序列化等, 问题所以通常我们需要配置
4、创建config\RedisConfig.java
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template =
new RedisTemplate<>();
System.out.println("template=>" + template);//这里可以验证..
RedisSerializer<String> redisSerializer =
new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer =
new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
注意事项和细节
1、如果没有提供RedisConfig 配置类, springboot 会使用默认配置, 也可以使用下面测试方法的t3方法先不注销请求看看 然后在注销看看就可以验证了
2、如果没有提供RedisConfig 配置类, springboot 会使用默认配置, 但是会存在问题,比如redisTemplate 模糊查找key 数据为空
3、Unrecognized token ‘beijing’: was expecting (‘true’, ‘false’ or ‘null’)看报错,是jason 转换异常,实际上是因为redisTemplate 在做数据存储的时候会把存储的内容序列化,所以,redisTemplate 读取的时候也会反序列化,而在redis 客户端set 的时候并不会做序列化,因此set 的进去的值在用redisTemplate 读的时候就会报类型转换异常了 这个可以使用下面测试 t2 和t4 来验证 如果直接请求t4会报下面的错误 但是如果我们先请求t3 在请求t4就不会报错
4、解决方案: 最简单的就是用程序重新set 一遍即可 就是执行一次set语句 然后在get
控制器-提供API 接口
@RestController
@RequestMapping("/redisTest")
public class RedisTestController {
//编写第一个测试方法
//演示设置数据和获取数据
@GetMapping("/t1")
public String t1() {
//设置值到redis
redisTemplate.opsForValue().set("book", "天龙八部~");
//从redis获取值
String book = (String) redisTemplate.opsForValue().get("book");
return book;
}
//编写方法,演示如何操作list,hash,set,zset
@GetMapping("/t2")
public String t2() {
//list-存
redisTemplate.opsForList().leftPush("books", "笑傲江湖");
redisTemplate.opsForList().leftPush("books", "hello,java");
//list-取出
List books = redisTemplate.opsForList().range("books", 0, -1);
String booksList = "";
for (Object book : books) {
System.out.println("book-->" + book.toString());
booksList += book.toString() + " ";
}
//hash
//redisTemplate.opsForHash()
//set
//redisTemplate.opsForSet()
//zset
//redisTemplate.opsForZSet()
return booksList;
}
//编写一个方法,获取所有的key
@GetMapping("/t3")
public String t3() {
Set keys = redisTemplate.keys("*");
for (Object key : keys) {
System.out.println("key--->" + key.toString());
}
return "OK";
}
//编写方法,获取通过客户端添加的数据-会出现异常
//需要保持一致,比如RedisTemplate读取的数据,应当是RedisTemplate存放的数据
@GetMapping("/t4")
public String t4() {
String val = (String) redisTemplate.opsForValue().get("book");
System.out.println("val= " + val);
return val;
}
}
2、说明: 可以通过debug/输出对象, 验证该文件的redisTemplate 对象, 就是配置类RedisConfig 的Bean redisTemplate, 并且已经进行了相关序列化的配置.