Spring-Data-Redis

文章目录

1. Spring-Data-Redis

1.1. 添加依赖

1.2. 配置RedisTemplate

1.3. 序列化问题

1.4. RedisTemplate

1.4.1. 常用的类

1.5. spring中处理Redis的事务

1.6. 工具类

1.7. 文档

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数据库
<!-- 加载redis.properties,其中定义了数据库的配置信息 -->
	<util:properties id="redisConfig" location="classpath:redis.properties" />

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

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

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

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


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

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

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

	</bean>

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

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

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

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

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

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

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

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

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

		<!-- 配置key的序列化 一般都会使用stringRedisSerializer,默认使用的是JdkSerializationRedisSerializer -->
		<property name="keySerializer" ref="stringRedisSerializer"></property>
		
		<!-- 配置JdkSerializationRedisSerializer序列化 -->
		<property name="valueSerializer" ref="jdkSerializationRedisSerializer"></property>
		
		<!-- 配置hashkey的序列化,就是field -->
		<property name="hashKeySerializer" ref="stringRedisSerializer"></property>
		
		<!-- 配置hashvalue的值的序列化 -->		
		<property name="hashValueSerializer" ref="jdkSerializationRedisSerializer"></property>
        <!-- 开始redis事务,使用mulit和exec即可实现事务的操作和回滚 -->
		<property name="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);   //删除所有的键值
	}
	
}

文档

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Redis总结

    爱撒谎的男孩
  • 分布式锁-redis实现

    爱撒谎的男孩
  • Thread初探

    爱撒谎的男孩
  • Redis相关命令

    OPice
  • Redis命令总结及其基础知识讲述

      Redis拥有其他数据库不具备的数据结构,又拥有内存存储(这使得redis的速度非常快),远程操作(使得redis可以与多个客户端和服务器进行连接)、持久化...

    那一叶随风
  • 认识redis数据类型

    Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。

    老雷PHP全栈开发
  • 京东毫秒级热key探测框架设计与实践,已完美支撑618大促

    在拥有大量并发用户的系统中,热key一直以来都是一个不可避免的问题。或许是突然某些商品成了爆款,或许是海量用户突然涌入某个店铺,或许是秒杀时瞬间大量开启的爬虫用...

    天涯泪小武
  • redis

    1)Redis:REmote DIctionary Server(远程字典服务器)

    用户2337871
  • 【Redis】Redis常用命令

    expire key seconds 当超过过期时间,会自动删除,key在seconds秒后过期 expireat key timest...

    用户5522200
  • redis 学习(3)-- String 类型

    当我们通过 id 查找相关信息,redis 做中间层,当数据缓存在 redis 中时,我们直接返回该数据,如果 redis 中不存在,就到 MYSQL 中查...

    希希里之海

扫码关注云+社区

领取腾讯云代金券