大家好我是苏麟 , 今天聊聊Redis在Java中的应用 .
前面我们了解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使用JDBC操作MySQL数据库一样。
Redis 的 Java 客户端很多,常用的几种:
Jedis
Lettuce
Spring Data Redis
Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis。
我们重点学习Spring Data Redis。
Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。
?
Spring Data Redis中提供了一个高度封装的类:RedisTemplate,对相关api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:
ValueOperations:string数据操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:hash类型的数据操作
ListOperations:list类型的数据操作
引入依赖
<!--springbot 整合 redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Redis配置 端口号默认6379 库默认0
#redis 配置
spring:
redis:
port: 6379
database: 0
host: localhost
编写配置类,创建RedisTemplate对象
package com.sky.config;
import lombok.extern.slf4j.Slf4j;
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;
@Configuration
@Slf4j
public class RedisConfiguration {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
log.info("开始创建redis模板对象...");
RedisTemplate redisTemplate = new RedisTemplate();
//设置redis的连接工厂对象
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置redis key的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
解释说明:
当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象,但是默认的key序列化器为
JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别,故设置为
StringRedisSerializer序列化器。
或者不写这个配置,写一个序列化器
/**
* 序列化 让JDK原生序列化转成JSON
*/
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> objectObjectRedisTemplate = new RedisTemplate<>();
objectObjectRedisTemplate.setConnectionFactory(redisConnectionFactory);
//设置KEY 序列化使用 String 字符串
objectObjectRedisTemplate.setKeySerializer(RedisSerializer.string());
objectObjectRedisTemplate.setHashKeySerializer(RedisSerializer.string());
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//设置Value 序列化 格式
objectObjectRedisTemplate.setValueSerializer(jsonRedisSerializer);
objectObjectRedisTemplate.setHashValueSerializer(jsonRedisSerializer);
return objectObjectRedisTemplate;
}
}
连接池使用 也可以自己配置连接池?
<!--common-pool-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!--springbot 整合 redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
?yml配置连接池
spring:
redis:
host: localhost
port: 6379
password: root
database: 1
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 100ms
通过RedisTemplate对象操作Redis
在test下新建测试类
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.*;
@SpringBootTest
public class SpringDataRedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedisTemplate(){
System.out.println(redisTemplate);
//string数据操作
ValueOperations valueOperations = redisTemplate.opsForValue();
//hash类型的数据操作
HashOperations hashOperations = redisTemplate.opsForHash();
//list类型的数据操作
ListOperations listOperations = redisTemplate.opsForList();
//set类型数据操作
SetOperations setOperations = redisTemplate.opsForSet();
//zset类型数据操作
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
}
}
1). 操作字符串类型数据 ?
/**
* 操作字符串类型的数据
*/
@Test
public void testString(){
// set get setex setnx
redisTemplate.opsForValue().set("name","小明");
String city = (String) redisTemplate.opsForValue().get("name");
System.out.println(city);
redisTemplate.opsForValue().set("code","1234",3, TimeUnit.MINUTES);
redisTemplate.opsForValue().setIfAbsent("lock","1");
redisTemplate.opsForValue().setIfAbsent("lock","2");
}
2). 操作哈希类型数据 ?
/**
* 操作哈希类型的数据
*/
@Test
public void testHash(){
//hset hget hdel hkeys hvals
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.put("100","name","tom");
hashOperations.put("100","age","20");
String name = (String) hashOperations.get("100", "name");
System.out.println(name);
Set keys = hashOperations.keys("100");
System.out.println(keys);
List values = hashOperations.values("100");
System.out.println(values);
hashOperations.delete("100","age");
}
3). 操作列表类型数据 ?
/**
* 操作列表类型的数据
*/
@Test
public void testList(){
//lpush lrange rpop llen
ListOperations listOperations = redisTemplate.opsForList();
listOperations.leftPushAll("mylist","a","b","c");
listOperations.leftPush("mylist","d");
List mylist = listOperations.range("mylist", 0, -1);
System.out.println(mylist);
listOperations.rightPop("mylist");
Long size = listOperations.size("mylist");
System.out.println(size);
}
4). 操作集合类型数据 ?
/**
* 操作集合类型的数据
*/
@Test
public void testSet(){
//sadd smembers scard sinter sunion srem
SetOperations setOperations = redisTemplate.opsForSet();
setOperations.add("set1","a","b","c","d");
setOperations.add("set2","a","b","x","y");
Set members = setOperations.members("set1");
System.out.println(members);
Long size = setOperations.size("set1");
System.out.println(size);
Set intersect = setOperations.intersect("set1", "set2");
System.out.println(intersect);
Set union = setOperations.union("set1", "set2");
System.out.println(union);
setOperations.remove("set1","a","b");
}
5). 操作有序集合类型数据 ?
/**
* 操作有序集合类型的数据
*/
@Test
public void testZset(){
//zadd zrange zincrby zrem
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
zSetOperations.add("zset1","a",10);
zSetOperations.add("zset1","b",12);
zSetOperations.add("zset1","c",9);
Set zset1 = zSetOperations.range("zset1", 0, -1);
System.out.println(zset1);
zSetOperations.incrementScore("zset1","c",10);
zSetOperations.remove("zset1","a","b");
}
6). 通用命令操作 ?
/**
* 通用命令操作
*/
@Test
public void testCommon(){
//keys exists type del
Set keys = redisTemplate.keys("*");
System.out.println(keys);
Boolean name = redisTemplate.hasKey("name");
Boolean set1 = redisTemplate.hasKey("set1");
for (Object key : keys) {
DataType type = redisTemplate.type(key);
System.out.println(type.name());
}
redisTemplate.delete("mylist");
}
或者以下操作
/**
* 目标 : 在JAVA中操作redis spring date redis
* spring date redis 中提供了一个高度封装了的一个类 RedisTemple 针对jedis客户端api进行了分类封装,将同一种类型封装成Operation接口
* ValueOperation : 简单K-V操作
* SetOperation : set类型数据操作
* ZSetOperation : zset类型数据操作
* HashOperation : Hash类型数据操作
* ListOperation : List类型数据操作
*/
@SpringBootTest
class ItslRedisApplicationTests {
@Autowired
RedisTemplate redisTemplate;
/**
* 目标 : 对5中不同类型数据进行操作
* opsForValue
* opsForHash
* opsForList
* opsForSet
* opsForZSet
*/
/**
* 操作String类型数据
*/
@Test
void testString() {
//set操作
redisTemplate.opsForValue().set("sl", "sl");
//get操作
System.out.println(redisTemplate.opsForValue().get("sl"));
//setex操作 命令为指定的 key 设置值及其过期时间。
//如果 key 已经存在, SETEX 命令将会替换旧的值。
redisTemplate.opsForValue().set("ty", "sl", 100, TimeUnit.SECONDS);
//setnx操作 命令在指定的 key 不存在时,为 key 设置指定的值。
Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("ty", "ty");
System.out.println(aBoolean);
}
/**
* 目标 : 操作Hash数据类型
*/
@Test
void testHash() {
HashOperations hashOperations = redisTemplate.opsForHash();
//存值
hashOperations.put("002", "name", "sl");
hashOperations.put("002", "age", 20);
//取值
System.out.println(hashOperations.get("002", "age"));
System.out.println(hashOperations.get("002", "name"));
//获得hash结构中的所有字段
Set keys = hashOperations.keys("002");
for (Object key : keys) {
System.out.println(key);
}
//获得hash结构中的所有值
List values = hashOperations.values("002");
for (Object value : values) {
System.out.println(value);
}
}
/**
* 目标 : 操作List数据类型
*/
@Test
void testList() {
ListOperations listOperations = redisTemplate.opsForList();
//存值
listOperations.leftPush("ykList", "a");
listOperations.leftPushAll("ykList", "s", "b", "s", "t");
//取值
List ykList = listOperations.range("ykList", 0, -1);
for (Object o : ykList) {
System.out.println(o);
}
//获取长度
int size = ykList.size();
for (int i = 0; i < size; i++) {
//出队
Object ykList1 = listOperations.rightPop("ykList");
System.out.println("出队的是 : " + ykList1);
}
}
/**
* 目标 : 操作Set数据类型
*/
@Test
void testSet() {
SetOperations setOperations = redisTemplate.opsForSet();
//存值
setOperations.add("ty", "a", "b", "v", "b");
//取值
Set ty = setOperations.members("ty");
for (Object o : ty) {
System.out.println("删除前 : " + o);
}
//删除成员
setOperations.remove("ty", "a");
//取值
Set tys = setOperations.members("ty");
for (Object o : tys) {
System.out.println("删除后 : " + o);
}
}
/**
* 目标 : 操作ZSet数据类型
*/
@Test
void testZSet() {
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
//存值
zSetOperations.add("myZset", "a", 10.1);
zSetOperations.add("myZset", "b", 11.1);
zSetOperations.add("myZset", "c", 12.1);
zSetOperations.add("myZset", "d", 13.1);
//取值
Set myZset = zSetOperations.range("myZset", 0, -1);
for (Object o : myZset) {
System.out.println("删除前 : " + o);
}
//修改分数
zSetOperations.incrementScore("myZset", "d", 25.4);
//删除成员
zSetOperations.remove("myZset", "a", "b");
//取值
Set myZsets = zSetOperations.range("myZset", 0, -1);
for (Object os : myZsets) {
System.out.println("删除后 : " + os);
}
}
/**
* 目标 : 通用操作
*/
@Test
void testCommon() {
//获取Redis中所有的key
Set<String> keys = redisTemplate.keys("*");
for (String key : keys) {
System.out.println(key);
}
//判断某个key是否存在
Boolean itcast = redisTemplate.hasKey("key");
System.out.println(itcast);
//删除指定key
redisTemplate.delete("key");
//获取指定key对应的value的数据类型
DataType dataType = redisTemplate.type("001");
System.out.println(dataType.name());
}
}
这期就到这里 , 下期见!