SpringBoot整合Redis
SpringBoot整合Redis
window安装redis:https://blog.csdn.net/hello_list/article/details/123003445
docker安装redis:https://blog.csdn.net/hello_list/article/details/124887038
今天我们简单使用下spring boot操作redis,废话不多说直接开始整;
环境准备
新建一个spring boot项目
选上这几个,我本地有sptingboot2.6.3版本,我就直接用那个了;
查看项目依赖是否装好
配置文件,其实也不用配,如果你没有配置你的redis,默认也是这个,像我这个默认就是这个都不用配
我们知道redis中有五大基本类型,今天我们就简单学学spring boot对基本类型的使用,其实五个类型也就是opsFor···什么什么,点里面方法,一看就知道怎么用了,这里简单使用下
-
字符串
//将redisTemplate对象注入进来@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString() { redisTemplate.opsForValue().set("name","xuexiriji"); String name = (String) redisTemplate.opsForValue().get("name"); System.out.println(name);}//结果:xuexiriji
字符串最简单,同时也是使用最多;
-
列表
@Testvoid testList() { ListOperations<String,String> listOperations = redisTemplate.opsForList(); //我们知道list就是左右都可以pop和push,可以当做栈也可以当消息队列 listOperations.leftPush("list","test01"); listOperations.leftPush("list","test02"); listOperations.rightPush("list","test03"); listOperations.rightPush("list","test04"); //取范围,0到-1就是从0开始起步,0到2就是前三个 List<String> list = listOperations.range("list", 0, -1); for (String s : list) { //到这里我们可以这里理解,左就是向上,由就是向下,添加 System.out.println(s); }}
效果:
-
集合
@Testvoid testSet() { SetOperations setOperations = redisTemplate.opsForSet(); //首先我们知道set的特性,不重复 setOperations.add("set","java"); setOperations.add("set","redis"); setOperations.add("set","redis"); setOperations.add("set","java"); for (Object set : setOperations.members("set")) { System.out.println(set); } // 我们还可以这样使用求交并集,如果多个用户有相同的爱好可以到一起,还可以做抽奖功能 setOperations.add("user:1:hobbys","吃饭","睡觉","玩"); setOperations.add("user:2:hobbys","吃饭","唱歌"); setOperations.add("user:3:hobbys","打代码","看电影","玩"); for (Object o : setOperations.intersect("user:1:hobbys", "user:2:hobbys")) { System.out.println(o); } for (Object o : setOperations.intersect("user:1:hobbys", "user:3:hobbys")) { System.out.println(o); }}
效果:
-
有序集合
@Testvoid testZSet() { //和集合差不多,但是多了排序功能,那我们可以干什么呢,排行榜 ZSetOperations<String,String> zSetOperations = redisTemplate.opsForZSet(); zSetOperations.add("article", "user:1:java", 1); zSetOperations.add("article", "user:2:redis", 2); zSetOperations.add("article", "user:3:Linux", 1); zSetOperations.add("article", "user:4:springboot", 4); //点赞前 for (String article : zSetOperations.reverseRange("article", 0, -1)) { System.out.println(article); } for (int i = 0; i < 5; i++) { //当有人给java文章连续点赞五次后 zSetOperations.incrementScore("article", "user:1:java", 1); } System.out.println("刷新排行榜"); //点赞后 for (String article : zSetOperations.reverseRange("article", 0, -1)) { System.out.println(article); }}
效果:
-
哈希
@Testvoid testHash() { //hash key-map集合 HashOperations<String,String,String> hashOperations = redisTemplate.opsForHash(); //比方说我们存一个用户表格 hashOperations.put("usertable","user1","name:xuexiriji1:age:18"); hashOperations.put("usertable","user2","name:xuexiriji2:age:18"); hashOperations.put("usertable","user3","name:xuexiriji3:age:18"); hashOperations.put("usertable","user4","name:xuexiriji4:age:18"); //取user1 String s = hashOperations.get("usertable", "user1"); System.out.println(s); //遍历全部 Set<String> usertable = hashOperations.keys("usertable"); for (String s1 : usertable) { System.out.println(s1); System.out.println(hashOperations.get("usertable", s1)); }}
效果:
这是五大基本类型简单的基本使用,其实都不常用,我们更常用的其实就是string,当然了就是对象,所以我们在看看怎么存储对象
user类
import lombok.Data;import java.util.Date;@Datapublic class User implements Serializable { private String name; private Integer age; private Date birthday;}
Test
@Testpublic void testUser(){ User user = new User(); user.setName("xuexiriji"); user.setAge(18); user.setBirthday(new Date()); redisTemplate.opsForValue().set(user.getName(),user.toString()); //删除这个对象 Object o = redisTemplate.opsForValue().get(user.getName()); System.out.println(o); //是否存在,false表示不存在了 redisTemplate.delete(user.getName()); System.out.println(redisTemplate.hasKey(user.getName()));}
效果:
这里我们没有自定义这个redisTemplate对象,在开发中我们肯定不使用这个默认的,我们会自定义,然后再封装,怎么自定义,这里简单说一下,比如redis里面的incr操作,我们试一下,报错,类型不符合:
这里我们看下redis中的类型,发现我们存的其实都是乱码,是因为这里我们的序列化方式不一样,你用的默认jdk的序列化,人家用的是redis的序列化所以类型不同,这个时候我们就要自定义下redisTemplate了,我们只需要通过这个方法给到序列化就行
@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { // 1.创建 redisTemplate 模版 RedisTemplate<Object, Object> template = new RedisTemplate<>(); // 2.关联 redisConnectionFactory template.setConnectionFactory(redisConnectionFactory); // 3.创建 序列化类 GenericToStringSerializer genericToStringSerializer = new GenericToStringSerializer(Object.class); // 6.序列化类,对象映射设置 // 7.设置 value 的转化格式和 key 的转化格式 template.setValueSerializer(genericToStringSerializer); template.afterPropertiesSet(); return template;}
成功运行;
那当然,也不用你自己定义,这些网上模板很多,只要你懂了,拿过来修修改改用就行了;这里不用你找,这里给到
自定义redisTemplate模板
@Bean@SuppressWarnings("all")public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); template.setConnectionFactory(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key采用String的序列化方式 template.setKeySerializer(stringRedisSerializer); // hash的key也采用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); // value序列化方式采用jackson template.setValueSerializer(jackson2JsonRedisSerializer); // hash的value序列化方式采用jackson template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template;}
写一个工具类更方便我们使用:
package com.kuang.utils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.CollectionUtils;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;@Componentpublic final class RedisUtil { @Autowired private RedisTemplate<String, Object> redisTemplate; // =============================common============================ /** * 指定缓存失效时间 * @param key 键 * @param time 时间(秒) */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据key 获取过期时间 * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } // ============================String============================= /** * 普通缓存获取 * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 递增 * @param key 键 * @param delta 要增加几(大于0) */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 递减 * @param key 键 * @param delta 要减少几(小于0) */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key, -delta); } // ================================Map================================= /** * HashGet * @param key 键 不能为null * @param item 项 不能为null */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * 获取hashKey对应的所有键值 * @param key 键 * @return 对应的多个键值 */ public Map<Object, Object> hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * @param key 键 * @param map 对应多个键值 */ public boolean hmset(String key, Map<String, Object> map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * HashSet 并设置时间 * @param key 键 * @param map 对应多个键值 * @param time 时间(秒) * @return true成功 false失败 */ public boolean hmset(String key, Map<String, Object> map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @return true 成功 false失败 */ public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 * @return true 成功 false失败 */ public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除hash表中的值 * * @param key 键 不能为null * @param item 项 可以使多个 不能为null */ public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } /** * 判断hash表中是否有该项的值 * * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */ public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } /** * hash递增 如果不存在,就会创建一个 并把新增后的值返回 * * @param key 键 * @param item 项 * @param by 要增加几(大于0) */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash递减 * * @param key 键 * @param item 项 * @param by 要减少记(小于0) */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ============================set============================= /** * 根据key获取Set中的所有值 * @param key 键 */ public Set<Object> sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 根据value从一个set中查询,是否存在 * * @param key 键 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将数据放入set缓存 * * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */ public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 将set数据放入缓存 * * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 * @return 成功个数 */ public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) expire(key, time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 获取set缓存的长度 * * @param key 键 */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值为value的 * * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */ public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } // ===============================list================================= /** * 获取list缓存的内容 * * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 */ public List<Object> lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 获取list缓存的长度 * * @param key 键 */ public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 通过索引 获取list中的值 * * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 */ public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 */ public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @param time 时间(秒) */ public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @return */ public boolean lSet(String key, List<Object> value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key, List<Object> value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据索引修改list中的某条数据 * * @param key 键 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 移除N个值为value * * @param key 键 * @param count 移除多少个 * @param value 值 * @return 移除的个数 */ public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } }}
小结
不管什么对redis进行操作,都是通过redis原理来的,就是帮你去做命令嘛,只要你通过那个命令行把redis那些命令玩明白,这些就是过一眼的事,所以一定要先理解明白原理,这些就都很快了,希望大家支持一下博主,bye~