SpringBoot整合Redis并完成工具类
SpringBoot整合Redis的资料很多,但是我只需要整合完成后,可以操作Redis就可以了,所以不需要配合缓存相关的注解使用(如@Cacheable),而且我的系统框架用的日志是log4j,不是SpringBoot默认的Logback。通过查询资料我完成了Redis整合,并写了Redis操作工具类。特意在此记录一下,分享给大家,也方便以后查阅。
1.SpringBoot版本如下
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
2.添加Redis依赖
2.1如果没有特殊要求,直接添加依赖即可
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2.2如开篇所说,我不想要SpringBoot默认的日志,spring-boot-starter-data-redis包里自带了Logback的jar包,所以2.1的依赖不是我想要的,我的依赖如下
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.0.11.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
这两个依赖只是spring-boot-starter-data-redis依赖里关于Redis的依赖包,其实只需要这两个就OK了
3.application.properties中加入redis相关配置
#Redis spring.redis.host=192.168.0.202 #redis.host=192.168.0.202 ## Redis服务器连接端口 spring.redis.port=6379 ## 连接超时时间(毫秒) redis.timeout=3 ## Redis服务器连接密码(默认为空) redis.password=123456 ## 连接池中的最大连接数 redis.poolMaxTotal=10 ## 连接池中的最大空闲连接 redis.poolMaxIdle=10 ## 连接池最大阻塞等待时间(使用负值表示没有限制) redis.poolMaxWait=3
4.Redis模板及基本操作方法
查过资料的小伙伴们应该知道,SpringBoot的Redis模板配置类有一定的局限性,这里不再赘述,我自己写了一个RedisTemplate,直接贴代码
package com.gemdale.redis;
import com.alibaba.fastjson.JSON;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisTemplateService {
private static StringRedisTemplate stringRedisTemplate;
public <T> boolean set(String key ,T value){
try {
//任意类型转换成String
String val = beanToString(value);
if(val==null||val.length()<=0){
return false;
}
getStringRedisTemplate().opsForValue().set(key,val);
return true;
}catch (Exception e){
return false;
}
}
public <T> T get(String key,Class<T> clazz){
try {
String value = getStringRedisTemplate().opsForValue().get(key);
return stringToBean(value,clazz);
}catch (Exception e){
return null ;
}
}
@SuppressWarnings("unchecked")
private <T> T stringToBean(String value, Class<T> clazz) {
if(value==null||value.length()<=0||clazz==null){
return null;
}
if(clazz ==int.class ||clazz==Integer.class){
return (T)Integer.valueOf(value);
}
else if(clazz==long.class||clazz==Long.class){
return (T)Long.valueOf(value);
}
else if(clazz==String.class){
return (T)value;
}else {
return JSON.toJavaObject(JSON.parseObject(value),clazz);
}
}
/**
*
* @param value T任意类型
* @return String
*/
private <T> String beanToString(T value) {
if(value==null){
return null;
}
Class <?> clazz = value.getClass();
if(clazz==int.class||clazz==Integer.class){
return ""+value;
}
else if(clazz==long.class||clazz==Long.class){
return ""+value;
}
else if(clazz==String.class){
return (String)value;
}else {
return JSON.toJSONString(value);
}
}
//获取RedisTemplate
public static RedisTemplate<String, String> getStringRedisTemplate() {
if (stringRedisTemplate == null){
synchronized (RedisTemplateService.class){
if (stringRedisTemplate == null)
stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory());
}
}
return stringRedisTemplate;
}
public static RedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName("192.168.0.202");
jedisConnectionFactory.setPort(6379);
jedisConnectionFactory.setPassword("123456");
return jedisConnectionFactory;
}
}
5.Redis工具类
我另外写了一个专门的工具类,没有验证,放在这里只为备忘,有需要的小伙伴可以参考,如有问题欢迎指正。
1 package com.winmine.utils; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.data.redis.core.RedisTemplate; 5 import org.springframework.stereotype.Component; 6 import org.springframework.util.CollectionUtils; 7 8 import java.util.List; 9 import java.util.Map; 10 import java.util.Set; 11 import java.util.concurrent.TimeUnit; 12 13 @Component 14 public class RedisUtils { 15 @Autowired 16 private RedisTemplate<String, Object> redisTemplate; 17 18 // =============================common============================ 19 /** 20 * 指定缓存失效时间 21 * @param key 键 22 * @param time 时间(秒) 23 * @return 24 */ 25 public boolean expire(String key, long time) { 26 try { 27 if (time > 0) { 28 redisTemplate.expire(key, time, TimeUnit.SECONDS); 29 } 30 return true; 31 } catch (Exception e) { 32 e.printStackTrace(); 33 return false; 34 } 35 } 36 /** 37 * 根据key 获取过期时间 38 * @param key 键 不能为null 39 * @return 时间(秒) 返回0代表为永久有效 40 */ 41 public long getExpire(String key) { 42 return redisTemplate.getExpire(key, TimeUnit.SECONDS); 43 } 44 /** 45 * 判断key是否存在 46 * @param key 键 47 * @return true 存在 false不存在 48 */ 49 public boolean hasKey(String key) { 50 try { 51 return redisTemplate.hasKey(key); 52 } catch (Exception e) { 53 e.printStackTrace(); 54 return false; 55 } 56 } 57 58 /** 59 * 删除缓存 60 * @param key 可以传一个值 或多个 61 */ 62 @SuppressWarnings("unchecked") 63 public void del(String... key) { 64 if (key != null && key.length > 0) { 65 if (key.length == 1) { 66 redisTemplate.delete(key[0]); 67 } else { 68 redisTemplate.delete(CollectionUtils.arrayToList(key)); 69 } 70 } 71 } 72 73 // ============================String============================= 74 /** 75 * 普通缓存获取 76 * @param key 键 77 * @return 值 78 */ 79 public Object get(String key) { 80 return key == null ? null : redisTemplate.opsForValue().get(key); 81 } 82 /** 83 * 普通缓存放入 84 * @param key 键 85 * @param value 值 86 * @return true成功 false失败 87 */ 88 public boolean set(String key, Object value) { 89 try { 90 redisTemplate.opsForValue().set(key, value); 91 return true; 92 } catch (Exception e) { 93 e.printStackTrace(); 94 return false; 95 } 96 } 97 /** 98 * 普通缓存放入并设置时间 99 * @param key 键 100 * @param value 值 101 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 102 * @return true成功 false 失败 103 */ 104 public boolean set(String key, Object value, long time) { 105 try { 106 if (time > 0) { 107 redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); 108 } else { 109 set(key, value); 110 } 111 return true; 112 } catch (Exception e) { 113 e.printStackTrace(); 114 return false; 115 } 116 } 117 /** 118 * 递增 119 * @param key 键 120 * @param delta 要增加几(大于0) 121 * @return 122 */ 123 public long incr(String key, long delta) { 124 if (delta < 0) { 125 throw new RuntimeException("递增因子必须大于0"); 126 } 127 return redisTemplate.opsForValue().increment(key, delta); 128 } 129 /** 130 * 递减 131 * @param key 键 132 * @param delta 要减少几(小于0) 133 * @return 134 */ 135 public long decr(String key, long delta) { 136 if (delta < 0) { 137 throw new RuntimeException("递减因子必须大于0"); 138 } 139 return redisTemplate.opsForValue().increment(key, -delta); 140 } 141 142 // ================================Map================================= 143 /** 144 * HashGet 145 * @param key 键 不能为null 146 * @param item 项 不能为null 147 * @return 值 148 */ 149 public Object hget(String key, String item) { 150 return redisTemplate.opsForHash().get(key, item); 151 } 152 /** 153 * 获取hashKey对应的所有键值 154 * @param key 键 155 * @return 对应的多个键值 156 */ 157 public Map<Object, Object> hmget(String key) { 158 return redisTemplate.opsForHash().entries(key); 159 } 160 /** 161 * HashSet 162 * @param key 键 163 * @param map 对应多个键值 164 * @return true 成功 false 失败 165 */ 166 public boolean hmset(String key, Map<String, Object> map) { 167 try { 168 redisTemplate.opsForHash().putAll(key, map); 169 return true; 170 } catch (Exception e) { 171 e.printStackTrace(); 172 return false; 173 } 174 } 175 /** 176 * HashSet 并设置时间 177 * @param key 键 178 * @param map 对应多个键值 179 * @param time 时间(秒) 180 * @return true成功 false失败 181 */ 182 public boolean hmset(String key, Map<String, Object> map, long time) { 183 try { 184 redisTemplate.opsForHash().putAll(key, map); 185 if (time > 0) { 186 expire(key, time); 187 } 188 return true; 189 } catch (Exception e) { 190 e.printStackTrace(); 191 return false; 192 } 193 } 194 /** 195 * 向一张hash表中放入数据,如果不存在将创建 196 * @param key 键 197 * @param item 项 198 * @param value 值 199 * @return true 成功 false失败 200 */ 201 public boolean hset(String key, String item, Object value) { 202 try { 203 redisTemplate.opsForHash().put(key, item, value); 204 return true; 205 } catch (Exception e) { 206 e.printStackTrace(); 207 return false; 208 } 209 } 210 /** 211 * 向一张hash表中放入数据,如果不存在将创建 212 * @param key 键 213 * @param item 项 214 * @param value 值 215 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 216 * @return true 成功 false失败 217 */ 218 public boolean hset(String key, String item, Object value, long time) { 219 try { 220 redisTemplate.opsForHash().put(key, item, value); 221 if (time > 0) { 222 expire(key, time); 223 } 224 return true; 225 } catch (Exception e) { 226 e.printStackTrace(); 227 return false; 228 } 229 } 230 /** 231 * 删除hash表中的值 232 * @param key 键 不能为null 233 * @param item 项 可以使多个 不能为null 234 */ 235 public void hdel(String key, Object... item) { 236 redisTemplate.opsForHash().delete(key, item); 237 } 238 /** 239 * 判断hash表中是否有该项的值 240 * @param key 键 不能为null 241 * @param item 项 不能为null 242 * @return true 存在 false不存在 243 */ 244 public boolean hHasKey(String key, String item) { 245 return redisTemplate.opsForHash().hasKey(key, item); 246 } 247 /** 248 * hash递增 如果不存在,就会创建一个 并把新增后的值返回 249 * @param key 键 250 * @param item 项 251 * @param by 要增加几(大于0) 252 * @return 253 */ 254 public double hincr(String key, String item, double by) { 255 return redisTemplate.opsForHash().increment(key, item, by); 256 } 257 /** 258 * hash递减 259 * @param key 键 260 * @param item 项 261 * @param by 要减少记(小于0) 262 * @return 263 */ 264 public double hdecr(String key, String item, double by) { 265 return redisTemplate.opsForHash().increment(key, item, -by); 266 } 267 268 // ============================set============================= 269 /** 270 * 根据key获取Set中的所有值 271 * @param key 键 272 * @return 273 */ 274 public Set<Object> sGet(String key){ 275 try { 276 return redisTemplate.opsForSet().members(key); 277 } catch (Exception e) { 278 e.printStackTrace(); 279 return null; 280 } 281 282 } 283 284 /** 285 * 根据value从一个set中查询,是否存在 286 * @param key 键 287 * @param value 值 288 * @return true 存在 false不存在 289 */ 290 public boolean sHasKey(String key, Object value){ 291 try { 292 return redisTemplate.opsForSet().isMember(key, value); 293 } catch (Exception e) { 294 e.printStackTrace(); 295 return false; 296 } 297 } 298 299 /** 300 * 将数据放入set缓存 301 * @param key 键 302 * @param values 值 可以是多个 303 * @return 成功个数 304 */ 305 public long sSet(String key, Object... values){ 306 try { 307 return redisTemplate.opsForSet().add(key, values); 308 }catch (Exception e) { 309 e.printStackTrace(); 310 return 0; 311 } 312 } 313 314 /** 315 * 将set数据放入缓存 316 * @param key 键 317 * @param time 时间(秒) 318 * @param values 值 可以是多个 319 * @return 成功个数 320 */ 321 public long sSetAndTime(String key, long time, Object... values){ 322 Long count = 0L; 323 try { 324 count = redisTemplate.opsForSet().add(key, values); 325 if (time > 0) 326 expire(key, time); 327 }catch (Exception e){ 328 e.printStackTrace(); 329 } 330 return count; 331 } 332 333 /** 334 * 获取set缓存的长度 335 * @param key 键 336 * @return 337 */ 338 public long sGetSetSize(String key) { 339 try { 340 return redisTemplate.opsForSet().size(key); 341 }catch (Exception e){ 342 e.printStackTrace(); 343 return 0; 344 } 345 } 346 347 /** 348 * 移除值为value的 349 * @param key 键 350 * @param values 值 可以是多个 351 * @return 移除的个数 352 */ 353 public long setRemove(String key, Object... values) { 354 try { 355 Long count = redisTemplate.opsForSet().remove(key, values); 356 return count; 357 }catch (Exception e) { 358 e.printStackTrace(); 359 return 0; 360 } 361 } 362 363 // ===============================list================================= 364 365 /** 366 * 获取list缓存的内容 367 * @param key 键 368 * @param start 开始 369 * @param end 结束 0 到 -1代表所有值 370 * @return 371 */ 372 public List<Object> lGet(String key, long start, long end){ 373 try { 374 return redisTemplate.opsForList().range(key, start, end); 375 }catch (Exception e) { 376 e.printStackTrace(); 377 return null; 378 } 379 } 380 381 /** 382 * 获取list缓存的长度 383 * @param key 键 384 * @return 385 */ 386 public long lGetListSize(String key) { 387 try { 388 return redisTemplate.opsForList().size(key); 389 }catch (Exception e) { 390 e.printStackTrace(); 391 return 0; 392 } 393 } 394 395 /** 396 * 通过索引 获取list中的值 397 * @param key 键 398 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 399 * @return 400 */ 401 public Object lGetIndex(String key, long index){ 402 try { 403 return redisTemplate.opsForList().index(key, index); 404 }catch (Exception e) { 405 e.printStackTrace(); 406 return null; 407 } 408 } 409 410 /** 411 * 将list放入缓存 412 * @param key 键 413 * @param value 值 414 * @return 415 */ 416 public boolean lSet(String key, Object value) { 417 try { 418 redisTemplate.opsForList().rightPush(key, value); 419 return true; 420 }catch (Exception e) { 421 e.printStackTrace(); 422 return false; 423 } 424 } 425 426 /** 427 * 将list放入缓存 428 * @param key 键 429 * @param value 值 430 * @param time 时间(秒) 431 * @return 432 */ 433 public boolean lSet(String key, Object value, long time) { 434 try { 435 redisTemplate.opsForList().rightPush(key, value); 436 if (time > 0) 437 expire(key, time); 438 return true; 439 }catch (Exception e) { 440 e.printStackTrace(); 441 return false; 442 } 443 } 444 445 /** 446 * 将list放入缓存 447 * @param key 键 448 * @param value 值 449 * @return 450 */ 451 public boolean lSet(String key, List<Object> value) { 452 try { 453 redisTemplate.opsForList().rightPushAll(key, value); 454 return true; 455 }catch (Exception e) { 456 e.printStackTrace(); 457 return false; 458 } 459 } 460 461 /** 462 * 将list放入缓存 463 * @param key 键 464 * @param value 值 465 * @param time 时间(秒) 466 * @return 467 */ 468 public boolean lSet(String key, List<Object> value, long time){ 469 try { 470 redisTemplate.opsForList().rightPushAll(key, value); 471 if (time > 0) { 472 expire(key, time); 473 } 474 return true; 475 }catch (Exception e) { 476 e.printStackTrace(); 477 return false; 478 } 479 } 480 481 /** 482 * 根据索引修改list中的某条数据 483 * @param key 键 484 * @param index 索引 485 * @param value 值 486 * @return 487 */ 488 public boolean lUpdateIndex(String key, long index, Object value){ 489 try { 490 redisTemplate.opsForList().set(key, index, value); 491 return true; 492 }catch (Exception e) { 493 e.printStackTrace(); 494 return false; 495 } 496 } 497 498 /** 499 * 移除N个值为value 500 * @param key 键 501 * @param count 移除多少个 502 * @param value 值 503 * @return 移除的个数 504 */ 505 public long lRemove(String key, long count, Object value){ 506 try { 507 Long remove = redisTemplate.opsForList().remove(key, count, value); 508 return remove; 509 }catch (Exception e) { 510 e.printStackTrace(); 511 return 0; 512 } 513 } 514 515 516 }
6.测试
简单测试如下
1 package com.gemdale.redis; 2 3 import com.databus.Log; 4 import com.winmine.utils.MailUtils; 5 import hibernate.Acount; 6 import hibernate.VehicleDevice; 7 import org.hibernate.Session; 8 9 import java.util.*; 10 import java.util.concurrent.ConcurrentSkipListMap; 11 12 public class RedisTest { 13 RedisTemplateService redisTemplateService = new RedisTemplateService(); 14 15 16 public void test() { 17 Integer count = 1; 18 Set<String> keySet = new LinkedHashSet<>(); 19 Set<Acount> acountSet = new LinkedHashSet<>(); 20 ConcurrentSkipListMap keyMap = new ConcurrentSkipListMap(); 21 ConcurrentSkipListMap acountMap = new ConcurrentSkipListMap(); 22 Calendar calendar = null; 23 LinkedList<Long> list = new LinkedList<>(); 24 25 while (count < 15) { 26 calendar = Calendar.getInstance(); 27 // String key = "key"+count; 28 Integer key = count; 29 String testKey = RedisTemplateService.getStringRedisTemplate().opsForValue().get("testkey"); 30 Log.info("键testkey:" + testKey); 31 redisTemplateService.set(key.toString(),calendar.getTimeInMillis()); 32 String value = RedisTemplateService.getStringRedisTemplate().opsForValue().get(key.toString()); 33 Log.info(key + ":" + value); 34 if (keyMap.size() >= 10){ 35 keyMap.remove(keyMap.lastKey()); 36 keyMap.put(key,value); 37 } 38 list.removeFirst(); 39 list.add(calendar.getTimeInMillis()); 40 41 42 Integer userStr = count; 43 Acount user = new Acount(); 44 user.setUserid(calendar.getTimeInMillis() + ""); 45 user.setUserPrincipalName("user1"); 46 user.setUsername("user1"); 47 user.setPassword("user1password"); 48 user.setEmail("user@user.com"); 49 user.setStatus(0); 50 user.setMdid("mdid"); 51 user.setLoginType(3); 52 redisTemplateService.set(userStr.toString(),user); 53 54 Acount getUser = redisTemplateService.get(userStr.toString(),Acount.class); 55 Log.info(getUser); 56 if (acountMap.size() >= 10){ 57 acountMap.remove(acountMap.lastKey()); 58 acountMap.put(userStr,getUser);; 59 }else { 60 acountMap.put(userStr,getUser); 61 } 62 count++; 63 try { 64 Thread.sleep(1000); 65 }catch (Exception e){ 66 67 } 68 69 } 70 71 72 73 } 74 75 public static List<VehicleDevice> getVehicleDeviceResultList(Session session) { 76 List<VehicleDevice> list = new ArrayList<>(); 77 try { 78 Calendar calendar = Calendar.getInstance(); 79 long start = System.currentTimeMillis();;//当前时间毫秒数 80 list = (List<VehicleDevice>) session.createQuery("from VehicleDetectResult WHERE recordtime>='2019-01-29 22:57:11'") 81 .list(); 82 83 long end = System.currentTimeMillis(); 84 String aaa = MailUtils.milliSecondToTimeStr(end - start,1); 85 Log.info(aaa); 86 87 return list; 88 } catch (Exception e) { 89 e.printStackTrace(); // 打印错误信息 90 session.getTransaction().rollback(); // 出错将回滚事物 91 } finally { 92 session.close(); // 关闭Session 93 94 } 95 return null; 96 97 } 98 99 100 101 102 }