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>
/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>
Key-Value
的序列号,在使用 RedisTemplate
对象是默认使用 JdkSerializationRedisSerializer
实现。还提供了其它的序列化实现如: Jackson2JsonRedisSerializer
, JacksonJsonRedisSerializer
, GenericToStringSerializer
, StringRedisSerializer
, OxmSerializer
。 JdkSerializationRedisSerializer
,但是我们的 key
使用的是 StringRedisSerializer
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 约束 |
1、spring的事务管理器一定要使用注解方式的,不能使用aop方式的
2、需要在spring-data-redis中开启redis事务,只需要添加如下一条语句即可
<!-- 开始redis事务,使用mulit和exec即可实现事务的操作和回滚 --> <property name="enableTransactionSupport" value="true"></property>
3、在spring中使用 RedisTemplate.multi
和 exec
方法即可完成事务的控制
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
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); //删除所有的键值 } }