springdata操作redis(两种方式)
一、spring data 整合redis(Maven 项目)
maven项目结构:
1. 导入依赖
<?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>
<groupId>org.example</groupId>
<artifactId>SpringDataJpa_redis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.4.6</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
</project>
2. 编写spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--配置jedis连接池信息-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="30"></property>
<property name="maxIdle" value="20"></property>
<property name="minIdle" value="10"></property>
</bean>
<!--配置jedis连接工厂-->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="192.168.184.128"></property>
<property name="port" value="6379"></property>
<property name="poolConfig" ref="jedisPoolConfig"></property>
</bean>
<!-- springdata 提供redisTemplate-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"></property>
<!--指定键和值采用的序列化器-->
<property name="keySerializer" >
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer" >
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
</bean>
</beans>
3. 测试
实体类:
package com.hdit.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @基本功能:
* @ClassName: Teacher
* @Description: TODO
* @Author: lijiaming
* @Date: 2021/3/29 15:42
* @Version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
private Integer tid;
private String tname;
}
测试类:
package com.hdit;
import com.hdit.domain.Teacher;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.junit.Test;
import java.util.List;
/**
* @基本功能:
* @ClassName: Test
* @Description: TODO
* @Author: lijiaming
* @Date: 2021/3/29 14:28
* @Version 1.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-redis.xml")
public class springData_redisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test01() {
// 键和值需要实现序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations operations = redisTemplate.opsForValue();
operations.set("xinjiang", "mianhua");
Object xinjiang = operations.get("xinjiang");
System.out.println(xinjiang);
}
@Test
public void test02() {
// 字符串序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Teacher>(Teacher.class));
ValueOperations operations = redisTemplate.opsForValue();
Teacher t = new Teacher(1003, "李嘉明");
operations.set("t2003", t);
Teacher t2003 = (Teacher) operations.get("t2003");
System.out.println(t2003);
}
@Test
public void test03() {
// 字符串序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());//哈希键为字符串
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Teacher>(Teacher.class));//hash值为json字符串
HashOperations operations = redisTemplate.opsForHash();
// 添加数据
operations.put("tchMap", "1", new Teacher(1, "张三1"));
operations.put("tchMap", "2", new Teacher(2, "张三2"));
operations.put("tchMap", "3", new Teacher(3, "张三3"));
operations.put("tchMap", "4", new Teacher(4, "张三4"));
// 删除
operations.delete("tchMap",1);
// 获取
Teacher teacher = (Teacher) operations.get("tchMap", "1");
System.out.println(teacher);
}
@Test
public void test04() {
// 字符串序列!!!
redisTemplate.setKeySerializer(new StringRedisSerializer());//键值为stirng类型
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Teacher>(Teacher.class));//值类型为json字符串
ListOperations listOperations = redisTemplate.opsForList();
// 插入的实体对象Teacher要实现序列化接口Serializable
// 化任何存储都需要序列化。只不过常规你在用DB一类存储的时候,
// 这个事情DB帮你在内部搞定了(直接把SQL带有类型的数据转换成内部序列化的格式,存储;读取时再解析出来)。
// 而Redis并不会帮你做这个事情。
Teacher t1 = new Teacher(3001, "lisi01");
Teacher t2 = new Teacher(3002, "lisi02");
Teacher t3 = new Teacher(3003, "lisi03");
// leftPush将数据添加到key对应的现有数据的左边,也就是头部,
// rightPush是将现有数据添加到现有数据的右边,也就是尾部,可以根据业务的不同进行对应的添加
// leftPush插入顺序----->>>>> 已插入数据 <<<<<<------rightPush插入顺序
listOperations.leftPush("tch", t1);
listOperations.leftPush("tch", t2);
listOperations.leftPush("tch", t3);
// 删除,一次删除一条信息,leftPop从左边删除,rightPop从右边删除
listOperations.leftPop("tch");
// 获取
Long size = listOperations.size("tch");
System.out.println(size);
// List<V> range(K key, long start, long end);
List tch = listOperations.range("tch", 3, size);
// 遍历集合list,打印信息
tch.forEach(tch1 -> {
System.out.println(tch1);
});
}
}
总结一:序列化问题
(1)RedisSerializer<T>
这是redis提供的序列化器,有几个常用实现类:
//序列化成xml
OxmSerializer (org.springframework.data.redis.serializer)
//序列化成字节数组
ByteArrayRedisSerializer (org.springframework.data.redis.serializer)
//序列化成json(可反序列化)
GenericJackson2JsonRedisSerializer (org.springframework.data.redis.serializer)
//序列化成字符串(可反序列化)
GenericToStringSerializer (org.springframework.data.redis.serializer)
//序列化成字符串
StringRedisSerializer (org.springframework.data.redis.serializer)
//序列化成二进制
JdkSerializationRedisSerializer (org.springframework.data.redis.serializer)
//序列化成json格式
Jackson2JsonRedisSerializer (org.springframework.data.redis.serializer)
默认采用JdkSerializationRedisSerializer。
(2)实体类必须 implements Serializable
实现序列化接口。
(3)设置序列化
方式1:spring配置文件中添加下列代码:
<!--springdata 提供 redisTemplate-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"></property>
<!--指定键和值采用的序列化器-->
<property name="keySerializer" >
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer" >
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
</bean>
方式2:代码中指定(常用,比较方便)
// java代码:指定采用的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Teacher>(Teacher.class));
总结二:RedisTemplate对五种类型的操作方式
RedisTemplate对五种类型的操作方式如下:
redisTemplate.opsForValue(); //操作字符串
redisTemplate.opsForHash(); //操作hash
redisTemplate.opsForList(); //操作list
redisTemplate.opsForSet(); //操作set
redisTemplate.opsForZSet();//操作有序set
二、springdata整合redis(springboot项目)
1. 创建springboot项目(Java项目)
项目结构:
2. 导入依赖
<?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 https://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.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hdit</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot_springdata_redis</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</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
3. 配置application.peopertires
#配置redis
# Redis数据库索引(默认为0)
#spring.redis.database=0
# Redis服务器地址
spring.redis.host=192.168.184.128
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
#spring.redis.password=root
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=1000000
4.测试(springboot中已经自动实现序列化问题,不需要再配置)
学生类,一定要实现序列化接口:
package com.hdit.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @基本功能:
* @ClassName: Student
* @Description: TODO
* @Author: lijiaming
* @Date: 2021/3/29 20:59
* @Version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
private Integer sid;
private String sname;
}
测试类:
package com.hdit;
import com.hdit.domain.Student;
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.ListOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.List;
@SpringBootTest
class SpringBootSpringdataRedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void test01() {
ValueOperations operations = redisTemplate.opsForValue();
operations.set("zhangsan","I'm zhangsan!");
System.out.println(operations.get("zhangsan"));
}
@Test
void test02() {
ListOperations studentList = redisTemplate.opsForList();
Student stu1=new Student(1001,"lisi01");
Student stu2=new Student(1002,"lisi02");
Student stu3=new Student(1003,"lisi03");
Student stu4=new Student(1004,"lisi04");
studentList.leftPush("student",stu1);
studentList.leftPush("student",stu2);
studentList.rightPush("student",stu3);
studentList.rightPush("student",stu4);
Long size = studentList.size("student");
List students= studentList.range("student", 0, size);
students.forEach(student -> System.out.println(student));
}
@Test
void test03(){
ListOperations listOperations = redisTemplate.opsForList();
listOperations.rightPop("student");
List students = listOperations.range("student", 0, listOperations.size("student"));
students.forEach(student-> System.out.println(student));
}
}