Spring+redis,spring-data-redis使用

本文介绍如何在Spring环境中配置和使用Spring Data Redis,包括依赖设置、配置文件详解及示例代码,帮助读者快速掌握Redis在Spring项目中的集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:spring-data-redis简介

spring-data-redis(以下简称SDR),是在jedis的基础之上,Spring继续进行了封装,SDR的依赖比较恶心,是基于Spring3.X的,查阅资料得知,需要如下的maven依赖。本人没有一个个尝试,在此仅作学习记录,原文请参考: http://hello-nick-xu.iteye.com/blog/2078547
jedis在Spring中使用学习文档: http://snowolf.iteye.com/blog/1633196

1.Spring核心包
spring-core-3.2.3.RELEASE.jar
spring-beans-3.2.3.RELEASE.jar
spring-context-3.2.3.RELEASE.jar
spring-context-support-3.2.3.RELEASE.jar
spring-expression-3.2.3.RELEASE.jar
spring-tx-3.2.3.RELEASE.jar
spring-aop-3.2.3.RELEASE.jar

2.日志依赖
commons-logging.jar
log4j-1.2.15.jar

3.jedis和连接池
jedis-2.1.0.jar
commons-pool.jar

4.SDR依赖
spring-data-redis-1.0.0.RELEASE.jar

下图反应了大体的关系:






二:需要的maven

         <!-- redis核心包 -->
         <dependency>  
        	<groupId>org.springframework.data</groupId>  
        	<artifactId>spring-data-redis</artifactId>  
        	<version>1.0.1.RELEASE</version>  
    	</dependency>  
    	<dependency>  
       	 	<groupId>redis.clients</groupId>  
        	<artifactId>jedis</artifactId>  
        	<version>2.1.0</version>  
    	</dependency> 
核心,一个spring-data-redis,一个jedis的jar。

三:Spring中配置和调用类

redis.properties
# Redis settings
redis.host	        =localhost
redis.port		=6379  
redis.maxIdle		=300
redis.default.db	=0
redis.timeout		=100000
redis.maxActive		=600
redis.maxWait		=1000
redis.testOnBorrow	=true
本地地址,端口,最大连接数,默认DB数,等待超时时间,testOnBorrow:这个是指jedis取连接池时候,若连接无效或关闭,取下一个连接,避免同一个连接而错误

spring-redis.xml
   <!--   引入多个配置文件 -->
   <bean id="configurer"  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
    	<property name="locations">
    		<list>
    			<value>classpath:conf/spring/jdbc.properties</value> 
    			<value>classpath:conf/spring/log4j.properties</value> 
    			<value>classpath:conf/spring/redis.properties</value>
    		</list>  
    	</property> 
    </bean>
  
    <!-- jedis pool配置 --> 
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
        <property name="maxIdle" value="${redis.maxIdle}" /> 
        <property name="maxActive" value="${redis.maxActive}" />  
        <property name="maxWait" value="${redis.maxWait}" />  
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
    </bean>  
      
    <!-- spring data redis -->  
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
        <property name="usePool" value="true" />  
        <property name="hostName" value="${redis.host}" />  
        <property name="port" value="${redis.port}" />  
        <!-- <property name="password" value="${redis.pass}" />  --> 
        <property name="timeout" value="${redis.timeout}" />  
        <property name="database" value="${redis.default.db}" />  
        <constructor-arg index="0" ref="poolConfig" />
    </bean>    
        
    <!--  redis模板类 -->  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
        <property name="connectionFactory"   ref="connectionFactory" />  
    </bean>
    
    <!--  redisService 实现类 -->
    <bean id="redisService" class="com.redis.service.RedisService	">
    	<property name="redisTemplate"   ref="redisTemplate" /> 
    </bean>

<bean id="configurer"  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
    	<property name="locations">
    		<list>
    			<value>classpath:conf/spring/jdbc.properties</value> 
    			<value>classpath:conf/spring/log4j.properties</value> 
    			<value>classpath:conf/spring/redis.properties</value>
    		</list>  
    	</property> 
</bean>
表示Spring加载properties配置文件。
画外音:之前我引入配置文件使用的时候是如下方式:
<context:property-placeholder location="classpath:conf/spring/redis.properties" />
当只是在一个XML文件中还好,如果多个XML文件中这样子引配置文件,然后再${}的方式去引用参数,就会报参数错误,个人认为是因为Spring是用
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
进行统计管理的,不同的XML中 以placeHode的形势引入会把Spring创建的默认的这些Bean进行了覆盖,所以有个技巧就是所有的properties文件,统一以list形式引入。

<!-- jedis pool配置 --> 
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
        <property name="maxIdle" value="${redis.maxIdle}" /> 
        <property name="maxActive" value="${redis.maxActive}" />  
        <property name="maxWait" value="${redis.maxWait}" />  
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
    </bean>  
jedis连接池,这里貌似使用了一种设计模式,池-工厂-模板,不懂,不过Spring好像很多都是这样配置的,待学习设计模式! 疑问

<!-- spring data redis -->  
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
        <property name="usePool" value="true" />  
        <property name="hostName" value="${redis.host}" />  
        <property name="port" value="${redis.port}" />  
        <!-- <property name="password" value="${redis.pass}" />  --> 
        <property name="timeout" value="${redis.timeout}" />  
        <property name="database" value="${redis.default.db}" />  
        <constructor-arg index="0" ref="poolConfig" />
    </bean>    
连接工厂,从jedis池子中取redis连接的实例对象,我这里redis没密码。

<!--  redis模板类 -->  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
        <property name="connectionFactory"   ref="connectionFactory" />  
    </bean>
redis模板类,Spring-data-redis包提供。

<!--  redisService 实现类 -->
    <bean id="redisService" class="com.redis.service.RedisService	">
    	<property name="redisTemplate"   ref="redisTemplate" /> 
    </bean>
set方式注入我们自己写的类,redisService。指明成员,redisTemplate。


自己定义一个pojo,如下:
Student.java
package com.test.dao;

import java.io.Serializable;

public class Student implements Serializable{
	
	private static final long serialVersionUID = 1L;  
    private String id;  
    private String name;
    private int money;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}  
}
没什么可说的。

RedisService.java
package com.redis.service;

import java.io.Serializable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import com.test.dao.Student;

/**
 * redis读写数据Demo,注意要点
 * 1.jsp到redis 需要序列化   redisTemplate.getStringSerializer().serialize(XXXXX)
 * 2.redis数据读出来,需要反序列化,才能保证中文等不乱码   redisTemplate.getStringSerializer().deserialize(XXXXX)
 * @author Sww
 *
 */
public class RedisService{
	 
	private RedisTemplate<Serializable, Serializable> redisTemplate;
	
	public void setRedisTemplate(
			RedisTemplate<Serializable, Serializable> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	/**  
        * 新增学生ID,姓名              
        * @param student 
        * @return 
        */  
	public void save(final Student student) {
		redisTemplate.execute(new RedisCallback<Object>() {
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				connection.set(
						//请注意加前缀表示命名空间  例如student.uid
						redisTemplate.getStringSerializer().serialize(
								"student.uid:" + student.getId()),
						//需要序列化操作
						redisTemplate.getStringSerializer().serialize(
								student.getName())
				);
				return null;
			}
		});
	}
	
	/**
	* 根据ID查询学生姓名                 
	* @param id
	* @return
	*/
	public Student select(final String id){
		return redisTemplate.execute(new RedisCallback<Student>() {
			public Student doInRedis(RedisConnection connection)
					throws DataAccessException {
				byte[] key = redisTemplate.getStringSerializer().serialize(
						"student.uid:" + id);
				if (connection.exists(key)) {  
	                byte[] value = connection.get(key);  
	                //从redis中取出的需要反序列化--- deserialize
	                String name = redisTemplate.getStringSerializer()  
	                        .deserialize(value);  
	                Student student = new Student();  
	                student.setId(id);  
	                student.setName(name);  
	                return student;  
	            }  
		    return null;
			}
		});
	}
	
	/**
	 * 根据学生ID删除学生信息
	 * @param id
	 */
	public void delete(final String id){
		redisTemplate.execute(new RedisCallback<Object>() {
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				connection.del(redisTemplate.getStringSerializer().serialize(  
	                    "student.uid:" + id)); 
				return null;
			}
		});
	}
}
如上的写法,我也是在模仿中,不熟,这是一种内部类的写法吧,又是设计模式 尴尬,亟待学习这方面啊。要点:
1.加前缀,表示简单的区分,防止不同空间相同的key覆盖。
2.jsp到redis 需要序列化   redisTemplate.getStringSerializer().serialize(XXXXX),这样子中文写在redis中不会乱码
3.redis数据读出来,需要反序列化,才能保证中文等不乱码   redisTemplate.getStringSerializer().deserialize(XXXXX)
4.进行查操作前,最好判断下key是否存在,提高查询效率。
5.其实connection.set也就是放一对键值对到redis中。connection.get(key)则是根据key取出value值。而connection.get(key)则是直接根据key值删除。

四:测试

RedisMain.java
package com.test.controller.main;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.redis.service.RedisService;
import com.test.dao.Student;


/**
 * redis 测试类
 * @author Sww
 *
 */
public class RedisMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//1.获取RedisService实例对象
		BeanFactory factory = new ClassPathXmlApplicationContext("classpath:conf/spring/spring-redis.xml");  
		RedisService test = (RedisService) factory.getBean("redisService"); 
		Student student = new Student();
		//2.新增操作
		student.setId("302");
		student.setName("302value");
		test.save(student);
		//3.查询新增
		String name = test.select("302").getName();
		System.out.println("id:302对应的学生名:" + name);
		//4.删除新增
		//test.delete("302");
        System.out.println("-----------执行结束-------------");
	}
}
因为删除就没有了,我把delete那一行注释掉了。望知晓。

console日志:


redis上结果:































### Spring Boot 中 `spring-boot-data-redis` 和 `spring-boot-starter-data-redis` 的区别 #### 定义与用途 `sprng-boot-starter-data-redis` 是一个启动器(Starter),它包含了构建基于 Redis 数据存储的应用程序所需的所有依赖项。这个 Starter 自动引入了核心库,例如 `spring-data-redis` 和底层的 Redis 驱动程序(如 Jedis 或 Lettuce)。通过这种方式简化了项目的配置过程[^1]。 另一方面,`spring-boot-data-redis` 并不是一个独立的模块名称,而是通常指代由 `spring-boot-starter-data-redis` 提供的核心功能之一——即对 Redis 数据访问的支持能力。换句话说,它是 `spring-boot-starter-data-redis` 所封装的功能的一部分[^2]。 #### 主要差异总结 以下是两者的主要区别: 1. **命名含义** - `spring-boot-starter-data-redis`: 这是一个完整的 Starter 模块,用于快速集成 Redis 功能到 Spring Boot 应用中。 - `spring-boot-data-redis`: 更像是描述性的术语,表示 Spring Boot 对数据层 Redis 支持的整体概念,而不是具体的 Maven/Gradle 依赖项[^3]。 2. **依赖关系** - 当你在项目中添加 `spring-boot-starter-data-redis` 时,会自动拉取多个必要的子依赖项,其中包括但不限于: - `spring-data-redis`: 实现 Redis 数据操作的核心抽象接口。 - `lettuce-core` 或 `jedis`: Redis Java 客户端驱动程序的选择,默认情况下可能会优先选用其中之一作为默认实现。 3. **自动化配置** - 使用 `spring-boot-starter-data-redis` 后,Spring Boot 将提供一系列开箱即用的自动化配置选项来管理 Redis 连接池以及序列化策略等高级特性。这些都无需开发者额外编写繁琐的手动代码即可完成初始化工作[^2]。 4. **实际应用中的体现** 下面展示了一个简单的测试案例片段,其中展示了如何利用 `RedisTemplate` 来保存键值对并设置过期时间: ```java @SpringBootTest class CodeApplicationTests { @Autowired private RedisTemplate<String, Object> redisTemplate; @Test public void testRedisOperations(){ // 设置 key-value 到缓存里,并指定存活时间为60redisTemplate.opsForValue().set("testKey","value"); redisTemplate.expire("testKey",60L, TimeUnit.SECONDS); String result = (String) redisTemplate.opsForValue().get("testKey"); Assertions.assertEquals(result,"value"); } } ``` 此代码段表明,在成功注入 `RedisTemplate` 后可以非常方便地执行各种针对 Redis 缓存的操作命令[^3]。 #### 结论 综上所述,“`spring-boot-data-redis`”更多是指向于一种逻辑上的表述形式,而 “`spring-boot-starter-data-redis`”才是具体可被加入工程文件里的组件包名。如果希望在自己的应用程序里面轻松接入 Redis,则应该直接引用后者。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值