1、介绍
Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。
Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。
与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。
本文通过使用springDataRedis来实现对Redis的访问交互,对于下层springDataRedis封装好了Jedis、Lettuce等的API操作去访问Redis数据。对于上层的开发人员,我们只需要学习如何使用springDataRedis就可,无需关心Jedis、Lettuce等的API操作。
2、整合Redis
本文基于脚手架系列第二篇的基础上进行改造整合,有需要的同学可以根据需求自取:
springBoot+dubbo整合MyBatis-Plus - 脚手架系列(二)
本文是脚手架系列的第三篇,有兴趣的同学可以进入导航页进行学习:
如果还没搭建Redis环境,快速部署可以参考下列文章:
项目分为dubbo-api,dubbo-provide,dubbo-consumer这几个模块
dubbo-api: 公共服务接口
dubbo-provide: 服务提供者
dubbo-consumer: 服务消费者
2.1 dubbo-consumer添加依赖及配置
2.1.1 pom
<?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>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubbo-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<!--给子模块添加父项目,需要给出父项目pom文件路径-->
<parent>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubboparent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<!--添加api依赖-->
<dependency>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Redis相关 start -->
<!-- 实现对 Spring Data Redis 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 去掉对 Lettuce 的依赖,因为 Spring Boot 优先使用 Lettuce 作为 Redis 客户端 -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入 Jedis 的依赖,这样 Spring Boot 实现对 Jedis 的自动化配置 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- 等会示例会使用 fastjson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.61</version>
</dependency>
<!-- Spring Data Redis 默认使用 Jackson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Redis相关 end-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.5</version>
</dependency>
<!-- 引入 Spring Boot 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 实现对 Dubbo 的自动化配置 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.4.1</version>
</dependency>
<!-- 使用 Nacos 作为注册中心 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>2.7.4.1</version>
</dependency>
</dependencies>
</project>
2.1.2 application.yml
spring:
application:
name: dubbo-consumer
# 对应 RedisProperties 类
redis:
host: 127.0.0.1
port: 6379
password: 876543 # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
database: 0 # Redis 数据库号,默认为 0 。
timeout: 0 # Redis 连接超时时间,单位:毫秒。
# 对应 RedisProperties.Jedis 内部类
jedis:
pool:
max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。
max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。
min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。
max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。
server:
port: 8082
# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
# Dubbo 应用配置
application:
name: user-service-consumer # 应用名
# Dubbo 注册中心配置
registry:
address: nacos://127.0.0.1:8848 # 注册中心地址
# Dubbo 消费者配置
consumer:
timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒
TestService:
version: 1.0.0
2.2 dubbo-provider添加依赖及配置
2.2.1 pom
<?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>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubbo-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<!--给子模块添加父项目,需要给出父项目pom文件路径-->
<parent>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubboparent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<!--添加api依赖-->
<dependency>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Redis相关 start -->
<!-- 实现对 Spring Data Redis 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 去掉对 Lettuce 的依赖,因为 Spring Boot 优先使用 Lettuce 作为 Redis 客户端 -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入 Jedis 的依赖,这样 Spring Boot 实现对 Jedis 的自动化配置 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- 等会示例会使用 fastjson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.61</version>
</dependency>
<!-- Spring Data Redis 默认使用 Jackson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Redis相关 end-->
<!-- mybatis-plus相关 start -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>
<!-- 实现对数据库连接池的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency> <!-- 本示例,我们使用 MySQL -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!-- 实现对 MyBatis Plus 的自动化配置 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!-- mybatis-plus相关 end -->
<!-- 方便等会写单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Dubbo Spring Cloud Starter -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- 实现对 Dubbo 的自动化配置 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.4.1</version>
</dependency>
<!-- 使用 Nacos 作为注册中心 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>2.7.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
2.2.2 application.yml
server:
port: 8081
# datasource 数据源配置内容
spring:
application:
name: dubbo-provider
datasource:
url: jdbc:mysql://127.0.0.1:3306/dubbo_master?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
# 对应 RedisProperties 类
redis:
host: 127.0.0.1
port: 6379
password: 876543 # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
database: 0 # Redis 数据库号,默认为 0 。
timeout: 0 # Redis 连接超时时间,单位:毫秒。
# 对应 RedisProperties.Jedis 内部类
jedis:
pool:
max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。
max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。
min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。
max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。
# mybatis-plus 配置内容
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: auto # ID 主键自增
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.dubboscaffold.dubboapi.entity
# logging
logging:
level:
# dao 开启 debug 模式 mybatis 输入 sql
cn:
iocoder:
springboot:
lab12:
mybatis:
mapper: debug
# dubbo 配置项,对应 DubboConfigurationProperties 配置类
dubbo:
# Dubbo 应用配置
application:
name: user-service-provider # 应用名
# Dubbo 注册中心配
registry:
address: nacos://127.0.0.1:8848 # 注册中心地址
# Dubbo 服务提供者协议配置
protocol:
port: -1 # 协议端口。使用 -1 表示随机端口。
name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档
# Dubbo 服务提供者配置
provider:
timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒
TestService:
version: 1.0.0
# 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者
scan:
base-packages: com.dubboscaffold.dubboprovider.service.impl
2.3 dubbo-api添加依赖及配置
pom
<?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>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<!--给子模块添加父项目,需要给出父项目pom文件路径-->
<parent>
<groupId>com.dubboscaffold</groupId>
<artifactId>dubboparent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>
<!-- Redis相关 start -->
<!-- 实现对 Spring Data Redis 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 去掉对 Lettuce 的依赖,因为 Spring Boot 优先使用 Lettuce 作为 Redis 客户端 -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入 Jedis 的依赖,这样 Spring Boot 实现对 Jedis 的自动化配置 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- 等会示例会使用 fastjson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.61</version>
</dependency>
<!-- Spring Data Redis 默认使用 Jackson 作为 JSON 序列化的工具 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Redis相关 end-->
<!-- 实现对 MyBatis Plus 的自动化配置 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
JSONUtil
/**
* JSON 工具类
*/
public class JSONUtil {
public static <T> T parseObject(String text, Class<T> clazz) {
return JSON.parseObject(text, clazz);
}
public static String toJSONString(Object javaObject) {
return JSON.toJSONString(javaObject);
}
public static byte[] toJSONBytes(Object javaObject) {
return JSON.toJSONBytes(javaObject);
}
}
2.4 自定义Redis配置序列化方式
我们在dubbo-api中添加配置类
RedisConfiguration
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 创建 RedisTemplate 对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置 RedisConnection 工厂。
template.setConnectionFactory(factory);
// 使用 String 序列化方式,序列化 KEY 。
template.setKeySerializer(RedisSerializer.string());
// 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
template.setValueSerializer(RedisSerializer.json());
return template;
}
}
配置 GenericJackson2JsonRedisSerializer 作为 VALUE 的序列化方式。
2.5 连接Redis测试
新增RedisController
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate redisTemplate;
@RequestMapping("/setKeyByRedis")
public void setKeyByRedis(){
stringRedisTemplate.opsForValue().set("redis", "hello");
}
/**
* 测试redis序列化
*/
@RequestMapping("/setEntityJsonByRedis")
public void setEntityJsonByRedis(){
User user = new User();
user.setId(1);
user.setUsername("redis");
user.setDeleted(0);
String key = String.format("user:%d", user.getId());
redisTemplate.opsForValue().set(key, user);
}
@RequestMapping("/getEntityJsonByRedis")
public Object getEntityJsonByRedis() {
String key = String.format("user:%d", 1);
Object value = redisTemplate.opsForValue().get(key);
System.out.println(value);
return value;
}
}
测试
能查到值就说明和redis的整合没问题了,剩下的两个大家可以试试,接下来我们把redis的基本读写操作封装。
2.6 dubbo-api新增redis接口
User selectByIdRedis(Integer id);
void insertByIdRedis(Integer id,User user);
2.7 dubbo-provider添加redisDao,及实现方法
RedisDao
@Repository
public class RedisDao {
@Resource(name = "redisTemplate")
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
private ValueOperations<String, String> operations;
private static final String KEY_PATTERN = "user:%d";
private static String buildKey(Integer id) {
return String.format(KEY_PATTERN, id);
}
public User get(Integer id) {
String key = buildKey(id);
String value = operations.get(key);
return JSONUtil.parseObject(value, User.class);
}
public void set(Integer id, User user) {
String key = buildKey(id);
String value = JSONUtil.toJSONString(user);
operations.set(key, value);
}
}
UserServiceImpl
@Autowired
private RedisDao redisDao;
@Override
public User selectByIdRedis(Integer id) {
return redisDao.get(id);
}
@Override
public void insertByIdRedis(Integer id,User user) {
redisDao.set(id,user);
}
2.8 dubbo-consumer添加redis测试入口
UserController
@RequestMapping("/selectByIdRedis")
public User selectByIdRedis(Integer id){
return userService.selectByIdRedis(id);
}
@RequestMapping("/insertByIdRedis")
public void insertByIdRedis(String username,Integer id){
User user = new User();
user.setUsername(username);
user.setPassword("123");
user.setCreateTime(new Date());
user.setDeleted(0);
user.setId(id);
userService.insertByIdRedis(user.getId(),user);
}
3、测试
这样就完成了redis的新增及查询 。