“Spring-data-redis 的使用实践”的版本间差异

来自Wikioe
跳到导航 跳到搜索
(建立内容为“category:Redis == 关于 == 无论是 Jedis 还是 JedisPool,都只是完成对 Redis 操作的极为基础的 API,在不依赖任何中间件的开发…”的新页面)
 
第70行: 第70行:


== 配置 spring-redis.xml ==
== 配置 spring-redis.xml ==
使用 spring-data-redis 库的步骤:
# '''配置依赖''':
# 的第一步是,要在 Maven 的 pom 文件中加上 spring-data-redis 库的依赖,具体如下:
#: <syntaxhighlight lang="xml" highlight="">
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${springboot}</version>
</dependency>
</syntaxhighlight>
# 配置:连接池实例、RedisTemplate模板实例;(均为 spring bean)
#: 这是两个 spring bean,可以配置在项目统一的 spring xml 配置文件中,也可以编写一个独立的 springredis.xml 配置文件。
#:(以下采用第二种方式:)
#: <syntaxhighlight lang="xml" highlight="">
<!--加载配置文件 -->
<context:property-placeholder location="classpath:redis.properties"/>
<!--redis 数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大空闲数 -->
<property name="maxIdle" value="${redis.maxIdle}"/>
<!--最大空连接数 -->
<property name="maxTotal" value="${redis.maxTotal}"/>
<!--最大等待时间 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
<!--连接超时的时候是否阻塞,true表示阻塞,直到超过maxWaitMillis, 默认为true -->
<property name="blockWhenExhausted" value="${redis.blockWhenExhausted}"/>
<!--获取连接时,检测连接是否成功 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean>
<!-- Spring-redis 连接池管理工厂 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<!-- IP地址 -->
<property name="hostName" value="${redis.host}"/>
<!--端口号 -->
<property name="port" value="${redis.port}"/>
<!--连接池配置引用 -->
<property name="poolConfig" ref="poolConfig"/>
<!--usePool:是否使用连接池 -->
<property name="usePool" value="true"/>
</bean>
<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"></property>
</bean>
<!--将 redisTemplate 封装成通用服务-->
<bean id="springRedisService" class="com.crazymakercircle.redis.springJedis.CacheOperationService">
<property name="redisTemplate" ref="redisTemplate"/>
</bean>
<!-- 省略其他的spring-redis.xml配置,具体参见源代码 -->
<!-- . . . -->
</syntaxhighlight>
spring-data-redis 库在 JedisPool 提供连接池的基础上封装了自己的连接池—— '''RedisConnectionFactory''' 连接工厂;并且 spring-data-redis 封装了一个短期、非线程安全的连接类,名为 '''RedisConnection''' 连接类。
RedisConnection 类和 Jedis 库中的 Jedis 类原理一样,提供了与 Redis 客户端命令一对一的 API 函数,用于操作远程 Redis 服务。
在使用 spring-data-redis 时,虽然没有直接用到 Jedis 库,但是 '''spring-data-redis 库底层对 Redis 服务的操作还是调用 Jedis 库完成的'''。也就是说,spring-data-redis 库从一定程度上使大家更好地使用 Jedis 库。
RedisConnection 的 API 命令操作的对象都是'''字节级别'''的 Key 键和 Value 值。为了更进一步地减少开发的工作,spring-data-redis 库在 RedisConnection 连接类的基础上,针对不同的缓存类型,设计了'''五大数据类型的命令 API 集合''',用于完成不同类型的数据缓存操作,并封装在 RedisTemplate 模板类中。
== 使用 RedisTemplate 模板 API ==

2021年11月7日 (日) 02:28的版本


关于

无论是 Jedis 还是 JedisPool,都只是完成对 Redis 操作的极为基础的 API,在不依赖任何中间件的开发环境中,可以使用它们。但是,一般的 Java 开发,都会使用了 Spring 框架,可以使用 spring-data-redis 开源库来简化 Redis 操作的代码逻辑,做到最大程度的业务聚焦。


CRUD 中应用缓存的场景

在普通 CRUD 应用场景中,很多情况下需要同步操作缓存,推荐使用 Spring 的 spring-data-redis 开源库。

  • 注:CRUD 是指 Create(创建),Retrieve(查询),Update(更新)和 Delete(删除)。
  1. 创建缓存
    在创建(Create)一个 POJO 实例的时候,对 POJO 实例进行分布式缓存,一般以“缓存前缀+ID”为缓存的 Key 键,POJO 对象为缓存的 Value 值,直接缓存 POJO 的二进制字节。
    • 前提是:POJO 必须可序列化,实现 java.io.Serializable 空接口。如果 POJO 不可序列化,也是可以缓存的,但是必须自己实现序列化的方式,例如使用 JSON 方式序列化。
  2. 查询缓存
    在查询(Retrieve)一个 POJO 实例的时候,首先应该根据 POJO 缓存的 Key 键,从 Redis 缓存中返回结果。
    • 如果不存在,才去查询数据库,并且能够将数据库的结果缓存起来。
  3. 更新缓存
    在更新(Update)一个 POJO 实例的时候,既需要更新数据库的 POJO 数据记录,也需要更新 POJO 的缓存记录。
  4. 删除缓存
    在删除(Delete)一个 POJO 实例的时候,既需要删除数据库的 POJO 数据记录,也需要删除 POJO 的缓存记录。


为了演示 CRUD 场景下 Redis 的缓存操作

首先定义一个简单的 POJO 实体类:聊天系统的用户类。
此类拥有一些简单的属性,例如 uid 和 nickName,且这些属性都具备基本的 getter 和 setter 方法:
package com.crazymakercircle.im.common.bean;
//...
import java.io.Serializable;
@Slf4j
public class User implements Serializable {
	String uid;
	String devId;
	String token;
	String nickName;
	//....省略 getter setter toString等方法
}
然后定义一个完成 CRUD 操作的 Service 接口,定义三个方法:
  1. saveUser完成创建(C)、更新操作(U)。
  2. getUser完成查询操作(R)。
  3. deleteUser完成删除操作(D)。
Service接口的代码如下:
package com.crazymakercircle.redis.springJedis;
import com.crazymakercircle.im.common.bean.User;
public interface UserService {
	/**
	* CRUD 的创建/更新
	* @param user 用户
	*/
	User saveUser(final User user);
    
	/**
	* CRUD 的查询
	* @param id id
	* @return 用户
	*/
	User getUser(long id);
    
	/**
	* CRUD 的删除
	* @param id id
	*/
	void deleteUser(long id);
}

定义完了 Service 接口之后,接下来就是定义 Service 服务的具体实现。不过,这里聚焦的是:如何通过 spring-data-redis 库,使 Service 实现带缓存的功能?

配置 spring-redis.xml

使用 spring-data-redis 库的步骤:

  1. 配置依赖
  2. 的第一步是,要在 Maven 的 pom 文件中加上 spring-data-redis 库的依赖,具体如下:
    <dependency>
    	<groupId>org.springframework.data</groupId>
    	<artifactId>spring-data-redis</artifactId>
    	<version>${springboot}</version>
    </dependency>
    
  3. 配置:连接池实例、RedisTemplate模板实例;(均为 spring bean)
    这是两个 spring bean,可以配置在项目统一的 spring xml 配置文件中,也可以编写一个独立的 springredis.xml 配置文件。
    (以下采用第二种方式:)
    <!--加载配置文件 -->
    <context:property-placeholder location="classpath:redis.properties"/>
    
    <!--redis 数据源 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
    	<!--最大空闲数 -->
    	<property name="maxIdle" value="${redis.maxIdle}"/>
    	<!--最大空连接数 -->
    	<property name="maxTotal" value="${redis.maxTotal}"/>
    	<!--最大等待时间 -->
    	<property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
    	<!--连接超时的时候是否阻塞,true表示阻塞,直到超过maxWaitMillis, 默认为true -->
    	<property name="blockWhenExhausted" value="${redis.blockWhenExhausted}"/>
    	<!--获取连接时,检测连接是否成功 -->
    	<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
    </bean>
    
    <!-- Spring-redis 连接池管理工厂 -->
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    	<!-- IP地址 -->
    	<property name="hostName" value="${redis.host}"/>
    	<!--端口号 -->
    	<property name="port" value="${redis.port}"/>
    	<!--连接池配置引用 -->
    	<property name="poolConfig" ref="poolConfig"/>
    	<!--usePool:是否使用连接池 -->
    	<property name="usePool" value="true"/>
    </bean>
    
    <!-- redis template definition -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    	<property name="connectionFactory" ref="jedisConnectionFactory"/>
    	
    	<property name="keySerializer">
    		<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    	</property>
    	<property name="valueSerializer">
    		<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
    	</property>
    	<property name="hashKeySerializer">
    		<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    	</property>
    	<property name="hashValueSerializer">
    		<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
    	</property>
    	
    	<!--开启事务 -->
    	<property name="enableTransactionSupport" value="true"></property>
    </bean>
    
    <!--将 redisTemplate 封装成通用服务-->
    <bean id="springRedisService" class="com.crazymakercircle.redis.springJedis.CacheOperationService">
    	<property name="redisTemplate" ref="redisTemplate"/>
    </bean>
    
    
    <!-- 省略其他的spring-redis.xml配置,具体参见源代码 -->
    <!-- . . . -->
    


spring-data-redis 库在 JedisPool 提供连接池的基础上封装了自己的连接池—— RedisConnectionFactory 连接工厂;并且 spring-data-redis 封装了一个短期、非线程安全的连接类,名为 RedisConnection 连接类。

RedisConnection 类和 Jedis 库中的 Jedis 类原理一样,提供了与 Redis 客户端命令一对一的 API 函数,用于操作远程 Redis 服务。
在使用 spring-data-redis 时,虽然没有直接用到 Jedis 库,但是 spring-data-redis 库底层对 Redis 服务的操作还是调用 Jedis 库完成的。也就是说,spring-data-redis 库从一定程度上使大家更好地使用 Jedis 库。
RedisConnection 的 API 命令操作的对象都是字节级别的 Key 键和 Value 值。为了更进一步地减少开发的工作,spring-data-redis 库在 RedisConnection 连接类的基础上,针对不同的缓存类型,设计了五大数据类型的命令 API 集合,用于完成不同类型的数据缓存操作,并封装在 RedisTemplate 模板类中。


使用 RedisTemplate 模板 API