前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring-Data-Redis

Spring-Data-Redis

作者头像
爱撒谎的男孩
发布2019-12-31 15:43:24
5660
发布2019-12-31 15:43:24
举报
文章被收录于专栏:码猿技术专栏

文章目录

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
代码语言:javascript
复制
<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的配置信息
代码语言:javascript
复制
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数据库
代码语言:javascript
复制
<!-- 加载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事务,只需要添加如下一条语句即可

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

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

代码语言:javascript
复制
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的工具类,如下:
代码语言:javascript
复制
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);   //删除所有的键值
	}
	
}

文档

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring-Data-Redis
    • 添加依赖
      • 配置RedisTemplate
        • 序列化问题
          • RedisTemplate
            • 常用的类
          • spring中处理Redis的事务
            • 工具类
              • 文档
              相关产品与服务
              文件存储
              文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档