转载

Spring-Data-Redis

  • 需要spring的版本为 4.xxx
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.9.0</version>
	<type>jar</type>
	<scope>compile</scope>
</dependency>

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>1.8.9.RELEASE</version>
</dependency>

配置RedisTemplate

  • /src/main/resource 文件夹下新建一个 redis.properties 文件,其中设置redis的配置信息
hostName=39.105.123.197  
port=6379
timeout=15000
usePool=true
maxIdle=80
minIdle=80
maxWaitMillis=500
minEvictableIdleTimeMillis=300000
numTestsPerEvictionRun=3
timeBetweenEvictionRunsMillis=60000
testOnBorrow=true
testOnReturn=false
testOnCreate=false
  • src/main/resource 文件夹下新建一个文件 spring-redis.xml
    JedisPoolConfig
    JedisConnectionFactory
    RedisTemplate
    
<!-- 加载redis.properties,其中定义了数据库的配置信息 -->
	<util:propertiesid="redisConfig"location="classpath:redis.properties"/>

	<!-- 配置Redis的连接池 -->
	<beanid="jedisPoolConfig"class="redis.clients.jedis.JedisPoolConfig">
		<!-- 配置最大空闲连接数,当空闲连接超过该值时就挨个关闭多余的连接,但不能小于minldle -->
		<propertyname="maxIdle"value="#{redisConfig.maxIdle}"></property>

		<!-- 配置最小空闲连接数 -->
		<propertyname="minIdle"value="#{redisConfig.minIdle}"></property>

		<!-- 验证连接是否有效 -->

		<!-- 设置获取连接的时候测试连接是否可用,默认为false -->
		<propertyname="testOnBorrow"value="#{redisConfig.testOnBorrow}"></property>
		<!-- 新建连接的时候测试连接是否可用,默认为false -->
		<propertyname="testOnCreate"value="#{redisConfig.testOnCreate}"></property>
		<!-- 将连接释放回连接池的时候测试连接 默认为false -->
		<propertyname="testOnReturn"value="#{redisConfig.testOnReturn}"></property>
		<!-- 设置等待获取连接池连接的时间,一旦超过这个时间,抛出异常 单位毫秒 -->
		<propertyname="maxWaitMillis"value="#{redisConfig.maxWaitMillis}"></property>


		<!-- 连接空闲多久从池中去除,单位为毫秒 <=0表示禁用 -->
		<propertyname="minEvictableIdleTimeMillis"value="#{redisConfig.minEvictableIdleTimeMillis}"></property>

		<!-- 设置每次测试多少空闲连接 <=0表示禁用 -->
		<propertyname="numTestsPerEvictionRun"value="#{redisConfig.numTestsPerEvictionRun}"></property>

		<!-- 设置定时测试时间,单位毫秒 <=0表示禁用 -->
		<propertyname="timeBetweenEvictionRunsMillis"value="#{redisConfig.timeBetweenEvictionRunsMillis}"></property>

	</bean>

	<beanid="jedisConnFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
		<!-- 设置是否使用连接池,默认为true -->
		<propertyname="usePool"value="#{redisConfig.usePool}"/>

		<!-- 设置连接池,使用上面配置好的连接池jedisPoolConfig -->
		<propertyname="poolConfig"ref="jedisPoolConfig"></property>

		<!-- 设置远程的IP地址 -->
		<propertyname="hostName"value="#{redisConfig.hostName}"/>

		<!-- 设置端口号,默认为6379 -->
		<propertyname="port"value="#{redisConfig.port}"></property>

		<!-- 设置获取连接的超时时间 -->
		<propertyname="timeout"value="#{redisConfig.timeout}"></property>
	</bean>

	<!-- 配置 StringRedisSerializer序列化 -->
	<beanid="stringRedisSerializer"
		class="org.springframework.data.redis.serializer.StringRedisSerializer" />

	<beanid="jdkSerializationRedisSerializer"
		class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />

	<!-- 配置RedisTemplate,其中封装了操作Redis的各种方法 -->
	<beanid="redisTemplate"class="org.springframework.data.redis.core.RedisTemplate">

		<!-- 配置Jedis的连接工厂,引用上面 -->
		<propertyname="connectionFactory"ref="jedisConnFactory"/>

		<!-- 配置key的序列化 一般都会使用stringRedisSerializer,默认使用的是JdkSerializationRedisSerializer -->
		<propertyname="keySerializer"ref="stringRedisSerializer"></property>
		
		<!-- 配置JdkSerializationRedisSerializer序列化 -->
		<propertyname="valueSerializer"ref="jdkSerializationRedisSerializer"></property>
		
		<!-- 配置hashkey的序列化,就是field -->
		<propertyname="hashKeySerializer"ref="stringRedisSerializer"></property>
		
		<!-- 配置hashvalue的值的序列化 -->		
		<propertyname="hashValueSerializer"ref="jdkSerializationRedisSerializer"></property>
        <!-- 开始redis事务,使用mulit和exec即可实现事务的操作和回滚 -->
		<propertyname="enableTransactionSupport"value="true"></property>
	</bean>

序列化问题

  • Spring Data Redis提供了对 Key-Value 的序列号,在使用 RedisTemplate 对象是默认使用 JdkSerializationRedisSerializer 实现。还提供了其它的序列化实现如: Jackson2JsonRedisSerializerJacksonJsonRedisSerializerGenericToStringSerializerStringRedisSerializerOxmSerializer
  • 各种序列化的方式有各种的优点,需要自己权衡使用
  • 上面我们使用的是 JdkSerializationRedisSerializer ,但是我们的 key 使用的是 StringRedisSerializer
  • 实体类需要实现序列化接口

RedisTemplate

  • 这个封装了redis中的所有命令,只需要我们调用即可
  • API文档

常用的类

Key类型操作
ValueOperations Redis String/Value 操作
ListOperations Redis List 操作
SetOperations Redis Set 操作
ZSetOperations Redis Sort Set 操作
HashOperations Redis Hash 操作
Value约束操作
BoundValueOperations Redis String/Value key 约束
BoundListOperations Redis List key 约束
BoundSetOperations Redis Set key 约束
BoundZSetOperations Redis Sort Set key 约束
BoundHashOperations Redis Hash key 约束

spring中处理Redis的事务

1、spring的事务管理器一定要使用注解方式的,不能使用aop方式的

2、需要在spring-data-redis中开启redis事务,只需要添加如下一条语句即可

<!-- 开始redis事务,使用mulit和exec即可实现事务的操作和回滚 -->
<property name="enableTransactionSupport" value="true"></property>

3、在spring中使用 RedisTemplate.multiexec 方法即可完成事务的控制

public Object addUser(User user)throws Exception {
		userMapper.insertSelective(user);
		System.out.println(user.getId());
		template.opsForValue().set("user:"+user.getId(), user);
		System.out.println(10/0);
		return null;
	}

4、参考文章: https://blog.csdn.net/qq_34021712/article/details/75949756

工具类

  • 通过项目中的使用,自己总结了redis的工具类,如下:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.stereotype.Component;

import com.sun.corba.se.impl.oa.poa.ActiveObjectMap.Key;
import com.techwells.teammission.domain.User;

/**
 * redis的工具类
 * @author chenjiabing
 */
public class RedisUtils{
	private  RedisTemplate<String, Object> template;
	public final RedisTemplate<String, Object> getTemplate(){
		return template;
	}
	public final void setTemplate(RedisTemplate<String, Object> template){
		this.template = template;
	}
	/**
	 * 向redis中添加对象,string类型的对象
	 * @param object   需要存储的对象
	 * @param key  存储的键
	 * @throws Exception  出现异常信息
	 */
	public void addStringObject(String key,Object object)throws Exception{
		template.opsForValue().set(key,object);
	}
	
	/**
	 * 添加指定的key到Redis中
	 * @param key 指定的Ke
	 * @param object  数据
	 * @param timeout  过期时间
	 * @param unit    时间单位
	 * @throws Exception
	 */
	public void addStringObject(String key,Object object,Long timeout,TimeUnit unit)throws Exception{
		this.addStringObject(key, object);
		template.expire(key, timeout, unit);
	}
	
	/**
	 * 根据键值从redis中获取对象 string类型的对象
	 * @param key  key
	 * @return   返回对象
	 * @throws Exception 抛出的异常
	 */
	public Object getStringObject(String key)throws Exception{
		Object object=template.opsForValue().get(key);
		return object;
	}
	
	/**
	 * 根据key删除指定的值
	 * @param key  key
	 * @throws Exception 异常信息
	 */
	public void deleteObject(String key)throws Exception{
		template.delete(key);
	}
	
	
	/**
	 * 批量删除对象
	 * @param keys key的集合
	 */
	public void deleteObjectBatch(Collection<String> keys)throws Exception{
		template.delete(keys);
	}
	/**
	 * 根据key更新值
	 * @param key  key
	 * @param object  value
	 * @throws Exception  异常信息
	 */
	public void modifyStringObject(String key,Object object)throws Exception{
		this.addStringObject(key, object);
	}

	
	/**
	 * 添加数据在Hash中
	 * @param key  key
	 * @param field  指定的域
	 * @param object  数据
	 */
	public void addHashObject(String key,String field,Object object)throws Exception{
		template.opsForHash().put(key, field, object);
	}
	
	
	/**
	 * 向hash中添加数据,并且设置过期的时间
	 * @param key  key
	 * @param field  域
	 * @param object  数据
	 * @param timeout  过期时间
	 * @param unit    单位
	 * @throws Exception
	 */
	public void addHashObject(String key,String field,Object object,Long timeout,TimeUnit unit)throws Exception{
		this.addHashObject(key, field, object);
		this.setExpireTimeForKey(key, timeout, unit);
	}
	
	
	/**
	 * 批量添加数据到指定的hash中
	 * @param key  key
	 * @param map  需要添加的数据  Map<field,value>
	 * @param expireTime  过期时间,单位秒,如果为null,默认永远不过期
	 */
	public void addHashObjectBatch(String key,Map<Object, Object> map,Long expireTime,TimeUnit unit)throws Exception{
		template.opsForHash().putAll(key,map);
		if (expireTime!=null) {
			this.setExpireTimeForKey(key, expireTime,unit);  //设置过期时间
		}
	}
	
	
	
	
	
	/**
	 * 为指定的key设置过期时间
	 * @param key  key
	 * @param timeout  过期时间
	 * @param unit   指定时间的单位
	 */
	public void setExpireTimeForKey(String key,Long timeout,TimeUnit unit){
		template.expire(key, timeout, unit);
	}
	
	
	/**
	 * 删除指定的key
	 * @param key
	 */
	public void deleteKey(String key){
		template.delete(key);
	}
	
	
	/**
	 * 根据key,field从hash中获取数据
	 * @param key
	 * @param field
	 * @return  Object对象
	 */
	public Object getHashObject(String key,String field)throws Exception{
		return template.opsForHash().get(key, field);
	}
	
	
	/**
	 * 修改指定key,field中的数据
	 * @param key  
	 * @param field
	 * @param object
	 */
	public void modifyHashObject(String key,String field,Object object)throws Exception{
		this.addHashObject(key, field, object);
	}
	
	/**
	 * 删除指定的key和field中的数据
	 * @param key
	 * @param field
	 */
	public void deleteHashObject(String key,String field)throws Exception{
		this.deleteHashObjectBatch(key, new Object[]{field});
	}
	
	/**
	 * 根据key和fields批量获取其中的数据
	 * @param key  key
	 * @param fields  {@link Collection<Object> }
	 * @throws Exception
	 */
	public void getHashObjectBatch(String key,Collection<Object> fields)throws Exception{
		template.opsForHash().multiGet(key, fields);
	}
	
	/**
	 * 批量删除指定key和fields的数据
	 * @param key  key
	 * @param fields  需要删除的域
	 * @throws Exception
	 */
	public void deleteHashObjectBatch(String key,Object[] fields)throws Exception{
		template.opsForHash().delete(key,fields);
	}
	
	
	/**
	 * 添加数据到ZSet中
	 * @param key    指定的key
	 * @param value  指定的value
	 * @param score  指定的score
	 */
	public void addZSetObject(String key,String value,double score)throws Exception{
		template.opsForZSet().add(key, value, score);
	}
	
	
	/**
	 * 批量添加数据到Zset中
	 * @param key  指定的key
	 * @param typedTuple  {@link TypedTuple}
	 */
	public void addZSetObjectBatch(String key,Set<TypedTuple<Object>> typedTuple){
		template.opsForZSet().add(key, typedTuple);
	}
	
	/**
	 * 根据key获取start--end之间的数据
	 * @param key  指定key
	 * @param start 开始索引,从0开始
	 * @param end  结束索引
	 * @return  {@link Set<Object>}
	 */
	public Set<Object> getZSetObject(String key,Long start,Long end){
		return template.opsForZSet().range(key, start, end);
	}
	
	
	/**
	 * 根据Score的范围获取数据
	 * @param key  指定的key值
	 * @param min  score的最小值
	 * @param max score的最大值
	 * @return  {@link Set<Object>}
	 */
	public Set<Object> getZSetObjectRangeByScore(String key,Long min,Long max){
		return template.opsForZSet().rangeByScore(key, min, max);
	}
	
	/**
	 * 根据Score的范围获取数据,分页获取
	 * @param key  指定的key
	 * @param min  最小值
	 * @param max  最大值
	 * @param offset  偏移量
	 * @param count  数量
	 * @return
	 */
	public Set<Object> getZSetObjectRangeByScore(String key,Long min,Long max,Long offset,Long count){
		return template.opsForZSet().rangeByScore(key, min, max, offset, count);
	}
	
	/**
	 * 向List中添加元素,从表头添加
	 * @param key
	 * @param value
	 */
	public void addLeftListObject(String key,Object value){
		template.opsForList().leftPush(key, value);
	}
	
	/**
	 * 向List中添加元素,从表尾添加
	 * @param key
	 * @param value
	 */
	public void addRightListObject(String key,Object value){
		template.opsForList().rightPush(key, value);
	}
	
	/**
	 * 向List中添加元素,从表头添加
	 * @param key
	 * @param value
	 * @param timeOut  过期时间
	 * @param unit  单位
	 */
	public void addLeftListObject(String key,Object value,Long timeOut,TimeUnit unit){
		template.opsForList().leftPush(key, value);
		this.setExpireTimeForKey(key, timeOut, unit);   //设置过期时间
	}
	
	/**
	 * 批量从表头添加数据
	 * @param key
	 * @param timeout : 过期时间  如果为null表示永久不过期
	 * @param timeUnit : 时间单位
	 * @param values  {@link Collection<Object>}
	 */
	public void addLeftListObjectBatch(String key,Collection<Object> values,Long timeout,TimeUnit unit){
		template.opsForList().leftPushAll(key, values);
		if (timeout!=null) {
			this.setExpireTimeForKey(key, timeout, unit);
		}
	}
	
	/**
	 * 批量从表尾添加数据
	 * @param key
	 * @param values {@link Collection<Object>}
	 */
	public void addRigthListObjectBatch(String key,Collection<Object> values,Long timeout,TimeUnit unit){
		template.opsForList().rightPushAll(key, values);
		if (timeout!=null) {
			this.setExpireTimeForKey(key, timeout, unit);
		}
	}
	
	/**
	 * 获取指定范围内的数据
	 * @param key  
	 * @param i  开始的索引 从0开始
	 * @param j   结束的索引,-1 表示结尾
	 * @return   {@link List<Object>}
	 */
	public List<Object> getRangeListObject(String key,int i,int j){
		return template.opsForList().range(key, i, j);
	}
	
	
	/**
	 * 根据实体类的key和指定的查询参数、方法名称获取指定的key
	 * @param domainKey  实体类指定的key
	 * @param params  参数 Map<String,Object>
	 * @param functionName : 方法的名称
	 * @return
	 */
	public static String getRedisKey(String domainKey,String functionName,PagingTool pagingTool)throws Exception{
		StringBuilder builder=new StringBuilder();
		Map<String,Object> params=pagingTool.getParams();
		builder.append(domainKey+"_"+functionName+"_"+pagingTool.getStartNum()+"_"+pagingTool.getPageSize()+"_");
		for (String key : params.keySet()) {
			builder.append(key+"="+params.get(key)+"_");
		}
		return builder.toString();
	}
	
	/**
	 * 将Collection<?extend Object>的集合转换成Collection<Object>
	 * @param list 需要转换的集合
	 * @return   Collection<Object>
	 * @throws Exception
	 */
	public static Collection<Object> convertToCollection(Collection<? extends Object> list)throws Exception{
		List<Object> arrayList=new ArrayList<Object>(list.size());
		for (Object object : list) {
			arrayList.add(object);
		}
		return arrayList;
	}
	
	/**
	 * 将指定的List集合中的元素逆向
	 * @param objects  List<? extends Object>
	 */
	public static void reverse(List<? extends Object> objects){
		Collections.reverse(objects);
	}
	
	
	/**
	 * 删除所有的键值
	 */
	public void delteAllKeys(){
		Set<String> keys=template.keys("*");  //获取所有的key
		template.delete(keys);   //删除所有的键值
	}
	
}

文档

  • RedisTemplate API
  • 优质博文
  • https://blog.csdn.net/u010690828/article/details/77141083
原文  http://chenjiabing666.github.io/2018/09/02/Spring-Data-Redis/
正文到此结束
Loading...