如何在在Java中操作Redis
在Java中操作Redis
1 介绍
前面我们讲解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使用JDBC操作MySQL数据库一样。
Redis 的 Java 客户端很多,官方推荐的有三种:
- Jedis
- Lettuce
- Redisson
Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis。
2 Jedis(理解)
1.Jedis使用介绍
Jedis 是 Redis 的 Java 版本的客户端实现。
maven坐标:
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version>
</dependency>
使用 Jedis 操作 Redis 的步骤:
- 获取连接
- 执行操作
- 关闭连接
2. Jedis类常用方法
注:每个方法就是redis中的命令名,方法的参数就是命令的参数。
在每次访问Redis数据库的时候,都需要创建一个Jedis对象。每个Jedis对象似于JDBC中Connection对象,类似于mybatis中session对象。
连接和关闭 | 功能 |
---|---|
new Jedis(host, port) | 创建Jedis连接对象,参数: host: 服务器地址 port:端口号6379 |
void close() | 关闭连接 |
对string操作的方法 | 说明 |
---|---|
set(String key,String value) | 添加字符串类型的键和值 |
String get(String key) | 通过键得到字符串的值 |
del(String … keys) | 删除一个或多个键 |
对hash操作的方法 | 说明 |
---|---|
hset(String key,String field,String value) | 添加一个hash类型的键,字段和值 |
Map<String,String> hgetall(String key) | 通过一个键得到所有的字段和值,返回Map |
对list操作的方法 | 说明 |
---|---|
lpush(String key,String…values) | 从左边添加多个值到list中 |
List<String> lrange(String key,long start,long end) | 通过键得到指定范围的元素 |
对set操作的方法 | 说明 |
---|---|
sadd(String key,String…values) | 添加一个或多个元素 |
Set<String> smembers(String key) | 通过键得到集合所有的元素 |
对zset操作的方法 | 说明 |
---|---|
zadd(String key, double score, String member) | 添加一个键,分数和值 |
Set<String> zrange(String key, long start, long end) | 查询一个指定范围的元素 |
3、案例:Jedis的基本操作
目标
使用Jedis上面的方法来访问Redis,向服务器中写入字符串、hash和list类型,并且取出打印到控制台上。
操作步骤:
1.导入依赖
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version>
</dependency>
2.创建测试类,书写操作redis数据库的代码,代码一共分为三步:
【1】创建jedis对象,连接redis数据库服务器 new Jedis(host,port)
【2】 操作数据
【3】 关闭连接
【1.下面是操作字符串数据的代码】:
package com.itheima.sh.jedis_test_01;import org.junit.Test;
import redis.clients.jedis.Jedis;import java.util.List;public class JedisTest01 {/*jedis入门*/@Testpublic void test01(){//1.创建jedis对象,连接redis数据库服务器 new Jedis(host,port)Jedis jedis = new Jedis("127.0.0.1",6379);//2.操作数据//【1】字符串jedis.set("username", "柳岩");//获取String username = jedis.get("username");System.out.println("username = " + username);//一次性添加多个数据 mset(key1,value1,key2,value2,...)jedis.mset("addr", "sh", "company", "黑马");//获取所有的数据List<String> values = jedis.mget("username", "addr", "company");System.out.println("values = " + values);//3.关闭连接jedis.close();}
}
控制台输出结果:
小结:
1.一次性添加多个字符串数据,使用的方法如下:
mset(key1,value1,key2,value2,...)
2.一次性获取所有的字符串:
List<String> mget(key1,key2,key3...);
【2.下面是操作hash数据的代码】:
package com.itheima.sh.jedis_test_01;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JedisTest01 {/*jedis入门*/@Testpublic void test01(){//1.创建jedis对象,连接redis数据库服务器 new Jedis(host,port)Jedis jedis = new Jedis("127.0.0.1",6379);//2.操作数据//【2】hashjedis.hset("person", "username", "锁哥");//存储多个数据 注意这里map集合的键和值都是String类型Map<String, String> map = new HashMap<>();map.put("age", "18");map.put("height", "180");jedis.hmset("person", map);//获取hash中的所有的数据Map<String, String> map1 = jedis.hgetAll("person");System.out.println(map1);//3.关闭连接jedis.close();}
}
控制台输出结果:
小结:
1.向hash中添加一个数据:
jedis.hset(key, field, value);
2.向hash中添加多个数据:
jedis.hset(key, map集合);
3.获取hash中所有的数据:
Map<String, String> map1 = jedis.hgetAll(key);
4.3 Spring Data Redis(掌握)
4.3.1 介绍
Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。
网址:https://spring.io/projects/spring-data-redis
maven坐标:
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.4.8</version>
</dependency>
Spring Boot提供了对应的Starter,maven坐标:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对类似 Jedis 客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:
- ValueOperations:简单K-V操作(String类型)
- SetOperations:set类型数据操作
- ZSetOperations:zset类型数据操作
- HashOperations:针对hash类型的数据操作
- ListOperations:针对list类型的数据操作
4.3.2 使用方式
4.3.2.1 环境搭建
直接导入素材中的代码到idea中即可:
第一步:创建maven项目springdataredis_demo,配置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.4.5</version><relativePath/></parent><groupId>com.itheima</groupId><artifactId>springdataredis_demo</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.5</version></plugin></plugins></build>
</project>
第二步:编写启动类
package com.itheima;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class,args);}}
第三步:配置application.yml
spring:#Redis相关配置redis:host: 192.168.200.128 # 连接linux系统的redisport: 6379 # 端口号database: 0 #操作的是0号数据库
解释说明:
spring.redis.database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15。
可以通过修改Redis配置文件来指定数据库的数量。
第四步:提供测试类
package com.itheima.test;import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@SpringBootTest
public class SpringDataRedisTest {@Autowiredprivate RedisTemplate redisTemplate;}
4.3.2.2 操作字符串类型数据
需求:
1.存入数据和取出数据
2.存值并设置过期时间
3.如果存在值则不执行任何操作
/*** 操作String类型的数据*/@Testpublic void test01String(){//获取操作String类型的接口对象ValueOperations valueOperations = redisTemplate.opsForValue();//存值valueOperations.set("city123","beijing");//取值String value = (String) valueOperations.get("city123");System.out.println(value);//存值,同时设置过期时间 TimeUnit:超时时间单位/*void set(K key, V value, long timeout, TimeUnit unit);key :字段keyvalue:key对应的值timeout:超时时间TimeUnit:超时时间单位*/valueOperations.set("username","suoge",10, TimeUnit.SECONDS);//存值,如果存在则不执行任何操作Boolean aBoolean = valueOperations.setIfAbsent("city1234", "nanjing");System.out.println(aBoolean);}
上述操作完毕之后,在客户端查看键,如下所示:
因为默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别。如果我们想要存储的key是正常的key,我们可以使用如下配置类,当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象。
配置类:
package com.itheima.config;import org.springframework.cache.annotation.CachingConfigurerSupport;
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.StringRedisSerializer;/*** Redis配置类*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {/*1.RedisConnectionFactory 是获取RedisConnection对象的,RedisConnection相当于jdbc中的连接对象Connection表示和Redis进行连接*/@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {//创建Redis模板对象RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();//默认的Key序列化器为:JdkSerializationRedisSerializer//StringRedisSerializer支持字符串类型的转化,而且默认使用UTF-8编码//下面代码的意思是使用StringRedisSerializer序列化器替换默认的Key序列化器JdkSerializationRedisSerializerredisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setConnectionFactory(connectionFactory);return redisTemplate;}}
4.3.2.3 操作哈希类型数据
需求:
1.存储几个哈希类型的数据
2.获取哈希类型的数据
3.根据键获取哈希类型中的所有字段
4.获得hash结构中的所有值
/*** 操作Hash类型数据
*/
@Test
public void testHash(){//获取操作Hash类型的接口对象HashOperations hashOperations = redisTemplate.opsForHash();//存值 下面的代码相当于命令:hset person name xiaoming//pseron表示键,name表示字段名 xiaoming表示字段值hashOperations.put("person","name","xiaoming");hashOperations.put("person","age","20");hashOperations.put("person","address","bj");//取值//下面的代码相当于执行命令:hget 键 字段===》hget person age===>表示根据键和字段名获取字段值String age = (String) hashOperations.get("person", "age");System.out.println(age);//获得hash结构中的所有字段//下面的代码相当于执行命令:HKEYS 键===》HKEYS personSet keys = hashOperations.keys("person");for (Object key : keys) {System.out.println(key);}//获得hash结构中的所有值//HVALS 键List values = hashOperations.values("person");for (Object value : values) {System.out.println(value);}
}
4.3.2.4 操作列表类型数据
需求:
1.向列表中添加数据
2.查询列表中所有数据
/*** 操作List类型的数据
*/
@Test
public void testList(){//获取操作列表类型的接口对象ListOperations listOperations = redisTemplate.opsForList();//存值//命令lpush 键 元素 元素...listOperations.leftPush("mylist","a");listOperations.leftPushAll("mylist","b","c","d");//取值//命令:lrange 键 开始 结束//下面的代码是查询所有List<String> mylist = listOperations.range("mylist", 0, -1);for (String value : mylist) {System.out.println(value);}//获得列表长度 命令:llen 键Long size = listOperations.size("mylist");for (int i = 0; i < size; i++) {//出队列//命令:rpop 键//从右边删除一个元素,返回被删除的元素String element = (String) listOperations.rightPop("mylist");System.out.println(element);}
}
4.3.2.5 操作set集合类型数据
需求:
1.向set集合中添加数据
2.获取指定set集合的所有的元素
3.删除指定set集合的数据
/*** 操作Set类型的数据
*/
@Test
public void testSet(){//获取操作set类型的接口对象SetOperations setOperations = redisTemplate.opsForSet();//存值//sadd 键 元素 元素...setOperations.add("myset","a","b","c","a");//取值//smembers 键 : 得到这个集合中所有的元素Set<String> myset = setOperations.members("myset");for (String o : myset) {System.out.println(o);}//删除成员//srem 键 元素 元素...setOperations.remove("myset","a","b");//取值myset = setOperations.members("myset");for (String o : myset) {System.out.println(o);}}
4.3.2.6 操作有序集合类型数据
需求:
1.向zset中添加数据
2.从zset中取出数据
3.对某个值的分数进行加20
4.删除数据
/*** 操作ZSet类型的数据
*/
@Test
public void testZset(){//获取操作zSet类型的接口对象ZSetOperations zSetOperations = redisTemplate.opsForZSet();//存值//Boolean add(K var1, V var2, double var3) var1 表示键 var2 表示值 var3表示分数zSetOperations.add("myZset","a",10.0);//myZset 表示键 a 表示值 10.0 表示分数zSetOperations.add("myZset","b",11.0);zSetOperations.add("myZset","c",12.0);zSetOperations.add("myZset","a",13.0);//取值//命令:zrange 键 开始索引 结束索引//获取指定范围的元素,得到所有的元素,索引是0到-1Set<String> myZset = zSetOperations.range("myZset", 0, -1);for (String s : myZset) {System.out.println(s);}//修改分数//下面的方法表示在原来分数上进行加20zSetOperations.incrementScore("myZset","c",20.0);//删除成员zSetOperations.remove("myZset","a","b");//取值Set<ZSetOperations.TypedTuple> myZset = zSetOperations.rangeWithScores("myZset", 0, -1);for (ZSetOperations.TypedTuple typedTuple : myZset) {Double score = typedTuple.getScore();Object value = typedTuple.getValue();System.out.println(score+"---"+value);}
}
4.3.2.7 通用操作
需求:
1.获取Redis中所有的key
2.判断某个key是否存在
3.删除指定key
4.获取指定key对应的value的数据类型
/*** 通用操作,针对不同的数据类型都可以操作
*/
@Test
public void testCommon(){//获取Redis中所有的keySet<String> keys = redisTemplate.keys("*");for (String key : keys) {System.out.println(key);}//判断某个key是否存在Boolean itcast = redisTemplate.hasKey("itcast");System.out.println(itcast);//删除指定keyredisTemplate.delete("myZset");//获取指定key对应的value的数据类型DataType dataType = redisTemplate.type("myset");System.out.println(dataType.name());}
4.3.2.8 整合连接池(能够理解连接池参数即可)
关于redis连接池并没有什么效果,配置好之后会优化获取连接性能。
pom引入依赖:
<!-- redis创建连接池,默认不会创建连接池 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>
配置连接池:
# 配置redis环境
spring:redis:# 默认连接本地localhost,如果仅仅连接本地redis服务,则可不写host: 192.168.200.128# 默认端口是6379,则省略不写port: 6379# redis实例中分为16分片库,索引位从0~15,默认操纵的是0database: 0lettuce:pool:max-active: 8 # 连接池最大连接数(使用负值表示没有限制)max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)max-idle: 8 # 连接池中的最大空闲连接min-idle: 1 # 连接池中的最小空闲连接