java代码操作Redis,需要使用Jedis,也就是redis支持java的第三方类库 注意:Jedis2.7以上的版本才支持集群操作
新建SpringBoot2.0.3的WEB工程,在MAVEN的pom.xml文件中加入如下依赖
<dependencies> <!--默认是lettuce客户端--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- redis依赖commons-pool 这个依赖一定要添加 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!-- 测试库依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
spring:
redis:
port: 6379
password: 123456
host: 192.168.20.135
lettuce:
pool:
max-active: 8 # 连接池大连接数(使用负值表示没有限制)
max-idle: 8 # 连接池中的大空闲连接
min-idle: 0 # 连接池中的小空闲连接
max-wait: 1000 # 连接池大阻塞等待时间(使用负值表示没有限制)
shutdown-timeout: 100 # 关闭超时时间
JdbcTemplate-->JDBC 进一步封装。 RedisTemplate-->redis进行了进一步封装 (lettuce)
编写缓存配置类RedisCon?g用于调优缓存默认配置,RedisTemplate<String, Object>的类型兼容性更高
大家可以看到在redisTemplate()这个方法中用JacksonJsonRedisSerializer更换掉了Redis默认的序列化方 式:JdkSerializationRedisSerializer spring-data-redis中序列化类有以下几个:
GenericToStringSerializer:可以将任何对象泛化为字符创并序列化 Jackson2JsonRedisSerializer:序列化 Object对象为json字符创(与JacksonJsonRedisSerializer相同) JdkSerializationRedisSerializer:序列化java 对象 StringRedisSerializer:简单的字符串序列化 JdkSerializationRedisSerializer序列化被序列化对象必须实现Serializable接口,被序列化除属性内容还有其他 内容,长度长且不易阅读,默认就是采用这种序列化方式
存储内容如下:
"\xac\xed\x00\x05sr\x00!com.oreilly.springdata.redis.User\xb1\x1c \n\xcd\xed%\xd8\x02\x00\x02I\x00\x03ageL\x00\buserNamet\x00\x12Ljava/lang/String;xp\x00\x00\x00\ x14t\x00\x05user1"
<artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
spring: redis: port: 6379 password: guoweixin host: 192.168.20.135 lettuce: pool: max-active: 8 # 连接池大连接数(使用负值表示没有限制) max-idle: 8 # 连接池中的大空闲连接 min-idle: 0 # 连接池中的小空闲连接 max-wait: 1000 # 连接池大阻塞等待时间(使用负值表示没有限制) shutdown-timeout: 100 # 关闭超时时间
JacksonJsonRedisSerializer序列化,被序列化对象不需要实现Serializable接口,被序列化的结果清晰,容易阅 读,而且存储字节少,速度快
存储内容如下:
"{"userName":"guoweixin","age":20}" StringRedisSerializer序列化
一般如果key、value都是string字符串的话,就是用这个就可以了
RedisCon?g 类
1 package com.xq.redis; 2 3 import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 import com.fasterxml.jackson.annotation.PropertyAccessor; 5 import com.fasterxml.jackson.databind.ObjectMapper; 6 import org.springframework.cache.CacheManager; 7 import org.springframework.cache.annotation.CachingConfigurerSupport; 8 import org.springframework.cache.interceptor.KeyGenerator; 9 import org.springframework.context.annotation.Bean; 10 import org.springframework.context.annotation.Configuration; 11 import org.springframework.data.redis.cache.RedisCacheConfiguration; 12 import org.springframework.data.redis.cache.RedisCacheManager; 13 import org.springframework.data.redis.cache.RedisCacheWriter; 14 import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; 15 import org.springframework.data.redis.core.RedisTemplate; 16 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 17 import org.springframework.data.redis.serializer.StringRedisSerializer; 18 19 import java.lang.reflect.Method; 20 21 @Configuration 22 public class RedisConfig extends CachingConfigurerSupport { 23 /** 24 * 自定义缓存key的生成策略。默认的生成策略是看不懂的(乱码内容) 通过Spring 的依赖注入特性进行自定义的 配置注入并且此类是一个配置类可以更多程度的自定义配置 25 * 26 * @return 27 */ 28 @Bean 29 @Override 30 public KeyGenerator keyGenerator() { 31 return new KeyGenerator() { 32 @Override 33 public Object generate(Object target, Method method, Object... params) { 34 StringBuilder sb = new StringBuilder(); 35 sb.append(target.getClass().getName()); 36 sb.append(method.getName()); 37 for (Object obj : params) { 38 sb.append(obj.toString()); 39 } 40 return sb.toString(); 41 } 42 }; 43 } 44 45 /** 46 * 47 * 缓存配置管理器 48 */ 49 @Bean 50 public CacheManager cacheManager(LettuceConnectionFactory factory) { 51 //以锁写入的方式创建RedisCacheWriter对象 52 RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory); 53 //创建默认缓存配置对象 54 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); 55 RedisCacheManager cacheManager = new RedisCacheManager(writer, config); 56 return cacheManager; 57 } 58 59 @Bean 60 public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory factory) { 61 RedisTemplate<String, Object> template = new RedisTemplate<>(); 62 template.setConnectionFactory(factory); 63 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 64 ObjectMapper om = new ObjectMapper(); 65 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 66 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 67 jackson2JsonRedisSerializer.setObjectMapper(om); 68 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 69 // 在使用注解@Bean返回RedisTemplate的时候,同时配置hashKey与hashValue的序列化方式。 70 // key采用String的序列化方式 71 template.setKeySerializer(stringRedisSerializer); 72 // value序列化方式采用jackson 73 template.setValueSerializer(jackson2JsonRedisSerializer); 74 // hash的key也采用String的序列化方式 75 template.setHashKeySerializer(stringRedisSerializer); 76 // hash的value序列化方式采用jackson 77 template.setHashValueSerializer(jackson2JsonRedisSerializer); 78 template.afterPropertiesSet(); 79 return template; 80 } 81 }
测试String 类型
package com.xq.serviceImpl; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.util.concurrent.TimeUnit; @Service public class RedisServiceImpl { @Autowired private RedisTemplate<String, Object> redisTemplate; private static org.apache.log4j.Logger log = Logger.getLogger(RedisServiceImpl.class); /** * 普通缓存放入 * * @param key 键 * @return true成功 false失败 */ public String getString(String key) { if (redisTemplate.hasKey(key)) { log.info("Redis中查询"); return (String) redisTemplate.opsForValue().get(key); } else { String val = "lcoil"; redisTemplate.opsForValue().set(key, val); log.info("数据库中查询的"); return val; } } /** * 普通缓存放入 * * @param value 值 * @param expireTime 超时时间(秒) * @return true成功 false失败 */ public Boolean set(String key, Object value, int expireTime) { try { redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS); return true; } catch (Exception e) { e.printStackTrace(); return false; } } }
1 package com.xq.serviceImpl.hash; 2 3 import com.xq.model.User; 4 import org.apache.log4j.Logger; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.data.redis.core.HashOperations; 7 import org.springframework.data.redis.core.RedisTemplate; 8 import org.springframework.stereotype.Service; 9 10 import javax.annotation.Resource; 11 12 @Service 13 public class RedisServiceImpl { 14 @Autowired 15 private RedisTemplate<String, Object> redisTemplate; 16 @Resource(name = "redisTemplate") 17 private HashOperations<String, String, User> hash; 18 19 private static org.apache.log4j.Logger log = Logger.getLogger(RedisServiceImpl.class); 20 21 /** 22 * 判断key是否存在,如果存在 在Redis中查询 23 * 如果不存在,在MYSQL中查询,并将结果得到,添加到Redis Hash中 24 * 25 * @param id 26 * @return 27 */ 28 public User selectUserById1(String id) { 29 if (hash.hasKey("user", id)) { 30 log.info("Redis中查询对象"); 31 return 32 hash.get("user", id); 33 } else { 34 User u = new User(); 35 u.setId(id); 36 u.setName("coil"); 37 u.setAge(22); 38 log.info("mysql中查询对象"); 39 hash.put("user", id, u); 40 return u; 41 } 42 } 43 }
1 package com.xq.serviceImpl.hash; 2 3 import com.xq.service.HashCacheService; 4 import org.slf4j.Logger; 5 import org.slf4j.LoggerFactory; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.data.redis.core.Cursor; 8 import org.springframework.data.redis.core.RedisTemplate; 9 import org.springframework.data.redis.core.ScanOptions; 10 import org.springframework.stereotype.Service; 11 import org.springframework.util.CollectionUtils; 12 13 import java.util.List; 14 import java.util.Map; 15 import java.util.Set; 16 import java.util.concurrent.TimeUnit; 17 18 @Service("hashCacheService") 19 public class HashCacheServiceImpl implements HashCacheService { 20 private final static Logger log = LoggerFactory.getLogger(HashCacheServiceImpl.class); 21 @Autowired 22 private RedisTemplate<String, Object> redisTemplate; 23 24 /** 25 * 获取MAP中的某个值 26 * 27 * @param key 键 28 * @param item 项 29 * @return 值 30 */ 31 public Object hget(String key, String item) { 32 return redisTemplate.opsForHash().get(key, item); 33 } 34 35 /** 36 * 获取hashKey对应的所有键值 37 * 38 * @param key 键 39 * @return 对应的多个键值 40 */ 41 public Map<Object, Object> hmget(String key) { 42 return redisTemplate.opsForHash().entries(key); 43 } 44 45 /** 46 * 以map集合的形式添加键值对 47 * 48 * @param key 键 49 * @param map 对应多个键值 50 * @return true 成功 false 失败 51 */ 52 public boolean hmset(String key, Map<String, Object> map) { 53 try { 54 redisTemplate.opsForHash().putAll(key, map); 55 return true; 56 } catch (Exception e) { 57 e.printStackTrace(); 58 return false; 59 } 60 } 61 62 /** 63 * HashSet 并设置时间 64 * 65 * @param key 键 66 * @param map 对应多个键值 67 * @param time 时间(秒) 68 * @return true成功 false失败 69 */ 70 public boolean hmset(String key, Map<String, Object> map, long time) { 71 try { 72 redisTemplate.opsForHash().putAll(key, map); 73 if (time > 0) { 74 expire(key, time); 75 } 76 return true; 77 } catch (Exception e) { 78 e.printStackTrace(); 79 return false; 80 } 81 } 82 83 /** 84 * 向一张hash表中放入数据,如果不存在将创建 85 * 86 * @param key 键 87 * @param item 项 88 * @param value 值 89 * @return true 成功 false失败 90 */ 91 public boolean hset(String key, String item, Object value) { 92 try { 93 redisTemplate.opsForHash().put(key, item, value); 94 return true; 95 } catch (Exception e) { 96 e.printStackTrace(); 97 return false; 98 } 99 } 100 101 /** 102 * 向一张hash表中放入数据,如果不存在将创建 103 * 104 * @param key 键 105 * @param item 项 106 * @param value 值 107 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 108 * @return true 成功 false失败 109 */ 110 public boolean hset(String key, String item, Object value, long time) { 111 try { 112 redisTemplate.opsForHash().put(key, item, value); 113 if (time > 0) { 114 expire(key, time); 115 } 116 return true; 117 } catch (Exception e) { 118 e.printStackTrace(); 119 return false; 120 } 121 } 122 123 /** 124 * 删除hash表中的值 125 * 126 * @param key 键 不能为null 127 * @param item 项 可以使多个 不能为null 128 */ 129 public void hdel(String key, Object... item) { 130 131 redisTemplate.opsForHash().delete(key, item); 132 } 133 134 /** 135 * 判断hash表中是否有该项的值 136 * 137 * @param key 键 不能为null 138 * @param item 项 不能为null 139 * @return true 存在 false不存在 140 */ 141 public boolean hHasKey(String key, String item) { 142 return redisTemplate.opsForHash().hasKey(key, item); 143 } 144 145 /** 146 * hash递增 如果不存在,就会创建一个 并把新增后的值返回 147 * 148 * @param key 键 149 * @param item 项 150 * @param by 要增加几(大于0) 151 * @return 152 */ 153 public long hincr(String key, String item, long by) { 154 return redisTemplate.opsForHash().increment(key, item, by); 155 } 156 157 /** 158 * hash递减 159 * 160 * @param key 键 161 * @param item 项 162 * @param by 要减少记(小于0) 163 * @return 164 */ 165 public long hdecr(String key, String item, long by) { 166 return redisTemplate.opsForHash().increment(key, item, -by); 167 } 168 169 /** 170 * 171 * 获取指定变量中的hashMap值。 172 * 173 * @param key 174 * @return 返回LIST对象 175 */ 176 @Override 177 public List<Object> values(String key) { 178 return redisTemplate.opsForHash().values(key); 179 } 180 181 /** 182 * 获取变量中的键。 183 * 184 * @param key 185 * @return 返回SET集合 186 */ 187 @Override 188 public Set<Object> keys(String key) { 189 return redisTemplate.opsForHash().keys(key); 190 } 191 192 /** 193 * 获取变量的长度。 194 * 195 * @param key 键 196 * @return 返回长度 197 */ 198 @Override 199 public long size(String key) { 200 return redisTemplate.opsForHash().size(key); 201 } 202 203 /** 204 * 以集合的方式获取变量中的值。 205 * 206 * @param key 207 * @param list 208 * @return 返回LIST集合值 209 */ 210 @Override 211 public List multiGet(String key, List list) { 212 return redisTemplate.opsForHash().multiGet(key, list); 213 } 214 215 /** 216 * 如果变量值存在,在变量中可以添加不存在的的键值对 217 * 如果变量不存在,则新增一个变量,同时将键值对添加到该变量。 218 * 219 * @param key 220 * @param hashKey 221 * @param value 222 */ 223 @Override 224 public void putIfAbsent(String key, String hashKey, Object value) { 225 redisTemplate.opsForHash().putIfAbsent(key, hashKey, value); 226 } 227 228 /** 229 * 匹配获取键值对,ScanOptions.NONE为获取全部键对, ScanOptions.scanOptions().match("map1").build() 230 * 匹配获取键位map1的键值对,不能模糊匹配。 231 * 232 * @param key 233 * @param options 234 * @return 235 */ 236 @Override 237 public Cursor<Map.Entry<Object, Object>> scan(String key, ScanOptions options) { 238 return redisTemplate.opsForHash().scan(key, options); 239 } 240 241 /** 242 * 删除变量中的键值对,可以传入多个参数,删除多个键值对。 243 * 244 * @param key 键 245 * @param hashKeys MAP中的KEY 246 */ 247 @Override 248 public void delete(String key, String... hashKeys) { 249 redisTemplate.opsForHash().delete(key, hashKeys); 250 } 251 252 public boolean expire(String key, long seconds) { 253 return redisTemplate.expire(key, seconds, TimeUnit.SECONDS); 254 } 255 256 /** 257 * 删除 258 * 259 * @param keys 260 */ 261 @Override 262 public void del(String... keys) { 263 if (keys != null && keys.length > 0) { 264 265 if (keys.length == 1) { 266 redisTemplate.delete(keys[0]); 267 } else { 268 269 redisTemplate.delete(CollectionUtils.arrayToList(keys)); 270 } 271 } 272 } 273 274 @Override 275 public long getExpire(String key) { 276 return 0; 277 } 278 }
SpringBoot2.x中redis使用(lettuce)
原文:https://www.cnblogs.com/xianquan/p/13289494.html