Spring Data 家族之Redis
前言:
自从换了一份工作之后,忙了很多很少有时间去分享自己最近学的东西了但还是要对所学的知识做输出
Spring Data 对常见的noSql 中间件都做了对应的模板封装 ,其中Redis 是我们经常使用的一个缓存服务,我们经常使用的 5大数据类型都做了对应的操作封装,下面依次讲讲对应的api 操作,这里使用一个boot 工程来演示。
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId><!--使用json序列化-->
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
配置RedisConfig
/**
* @author wym
* @date 2021/3/1 22:18
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 设置
template.setValueSerializer(new StringRedisSerializer());
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
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);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
}
1.String
String是redis最基本的类型,在redis中,一个key对应一个value
/**
* @Autowired默认按类型进行装配,
* @Resource默认按照名称进行装配
* redis 默认是 <Object ,Object> 类型
*/
@Resource
private RedisTemplate<String,Object> redisTemplate;
/**
*测试
*/
@Test
void test(){
ValueOperations<String, Object> string = redisTemplate.opsForValue();
string.set("name","翁艳敏");
}
/**
* set
*/
@Test
void testSet(){
ValueOperations<String, Object> operations = redisTemplate.opsForValue();
//直接设置 key value
operations.set("name","wym");
//设置偏移量 从哪里开始
operations.set("name","wym2",3);
//设置10分钟过期 10 , 单位
operations.set("name","wym3",10, TimeUnit.MINUTES);
//设置批量保存
Map<String,String> map=new HashMap<>();
map.put("name1","wym3");
map.put("name2","wym3");
map.put("name3","wym3");
map.put("name4","wym3");
operations.multiSet(map);
//追加 存在就追加 没有 就保存 当前这个
operations.append("name4","wym4");
//存在返回 false 不存在 返回 true 并 添加 这个 key
Boolean aBoolean = operations.setIfAbsent("lock", "value");
System.out.println(aBoolean);
}
/**
* 获取
*/
@Test
void testGet() {
ValueOperations<String, Object> string = redisTemplate.opsForValue();
Object name = string.get("name");
System.out.println(name);
//批量获取
List<String> keys=new ArrayList<>();
keys.add("name");
keys.add("name1");
keys.add("name2");
List<Object> objects = string.multiGet(keys);
for (Object object : objects) {
System.out.println(object);
}
}
/**
* 删除
*/
@Test
void testDelete(){
Boolean name = redisTemplate.delete("name");
System.out.println(name);
}
/**
* 测试自增 和减少
* 使用在 点赞 浏览 等业务方面
*/
@Test
void testIncr(){
ValueOperations<String, Object> string = redisTemplate.opsForValue();
//返回的值
Long age = string.increment("age");
//设置 步长 每次加3
string.increment("age",3);
// 每次减少
string.decrement("money",500);
}
2.Hash
redis hash 是一个键值对集合。redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。类似Java里Map<String,Object> ,user (name age,address ) 等信息 拿来存放对象信息等,也可以在业务key 过多时使用统一key
/**
* @Autowired默认按类型进行装配,
* @Resource默认按照名称进行装配
* redis 默认是 <Object ,Object> 类型
*/
@Resource
private RedisTemplate redisTemplate;
@Test
public void testRedisHash(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","weng");
map.put("age", 18);
Map<String, Object> map2 = new HashMap();
map2.put("name", "雷哥");
map2.put("age", 50);
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.put("user","1",map);
hashOperations.put("user","2",map2);
}
@Test
public void testHashGet(){
HashOperations hashOperations = redisTemplate.opsForHash();
Boolean user = hashOperations.hasKey("user", "1");
System.out.println(user);
Object user1 = hashOperations.get("user", "1");
System.out.println(user1);
Set user2 = hashOperations.keys("user");
for (Object o : user2) {
System.out.println(o);
}
List user3 = hashOperations.values("user");
user3.forEach(System.out::println);
Map user4 = hashOperations.entries("user");
System.out.println(user4);
}
@Test
public void testRemove(){
HashOperations operations = redisTemplate.opsForHash();
Long user = operations.delete("user", "1", "2");
System.out.println(user);
}
3.list
redis list 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。它的底层实际是个链表。
/**
* @Autowired默认按类型进行装配,
* @Resource默认按照名称进行装配
* redis 默认是 <Object ,Object> 类型
*/
@Resource
private RedisTemplate<String,Object> redisTemplate;
@Test
public void testRedisList(){
ListOperations<String, Object> listList = redisTemplate.opsForList();
listList.leftPush("name","张三");
listList.leftPushAll("names","李四", "王五", "赵六");
listList.rightPush("names","田七");
listList.rightPushAll("names", "王八", "老九");
}
@Test
public void testGet(){
ListOperations<String, Object> operations = redisTemplate.opsForList();// 0代表从左边开始第一个元素
Object names = operations.index("names", 0);
System.out.println(names);
Object names1 = operations.index("names", -2);
System.out.println(names1);
List<Object> names2 = operations.range("names", 0, 2);
System.out.println(names2);
}
@Test
public void testRemove(){
ListOperations<String, Object> operations = redisTemplate.opsForList();
Object names = operations.rightPop("names");
System.out.println(names);
}
4.set
redis set 和java 在的hashset 类似 不可以重复,string类型的无序集合
/**
* @Autowired默认按类型进行装配,
* @Resource默认按照名称进行装配 redis 默认是 <Object ,Object> 类型
*/
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testAdd() {
SetOperations<String, Object> stringObjectSetOperations = redisTemplate.opsForSet();
stringObjectSetOperations.add("namesSet", "zhangsan", "lisi", "wangwu", "zhangsan");
}
@Test
public void testFind(){
SetOperations<String, Object> stringObjectSetOperations = redisTemplate.opsForSet();
Set<Object> namesSet = stringObjectSetOperations.members("namesSet");
namesSet.forEach(System.out::println);
Object namesSet1 = stringObjectSetOperations.randomMember("namesSet");
System.out.println(namesSet1);
List<Object> namesSet2 = stringObjectSetOperations.randomMembers("namesSet", 2);
System.out.println(namesSet2);
}
@Test
public void testMulti(){
SetOperations<String, Object> operations = redisTemplate.opsForSet();
operations.add("name1", "zhangsan", "lisi", "wangwu", "zhaoliu");
operations.add("name2", "zhangsan", "lisi", "tianqi", "wangba");
//交集
Set<Object> intersect = operations.intersect("name1", "name2");
intersect.forEach(System.out::println);
//并集
Set<Object> union = operations.union("name1", "name2");
union.forEach(System.out::println);
//差集
Set<Object> difference = operations.difference("name1", "name2");
difference.forEach(System.out::println);
}
5.zSet
和set 差不多 ,但内部维护了一个scope 排序
/**
* @Autowired默认按类型进行装配,
* @Resource默认按照名称进行装配 redis 默认是 <Object ,Object> 类型
*/
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testAdd() {
ZSetOperations<String, Object> stringObjectZSetOperations = redisTemplate.opsForZSet();
stringObjectZSetOperations.add("userZset", "zhangsan", 100);
stringObjectZSetOperations.add("userZset", "lisi", 101);
stringObjectZSetOperations.add("userZset", "wangwu", 90);
stringObjectZSetOperations.add("userZset", "zhaoliu", 93);
stringObjectZSetOperations.add("userZset", "tianqi", 92);
}
@Test
public void testGet() {
ZSetOperations<String, Object> operations = redisTemplate.opsForZSet();
Double score = operations.score("userZset", "zhangsan");
System.out.println(score);
}
@Test
public void testList(){
ZSetOperations<String, Object> operations = redisTemplate.opsForZSet();
// 根据排名区间查询
Set<Object> userZset = operations.range("userZset", 0, 1);
userZset.forEach(System.out::println);
// 通过排名区获取元素集合和分数
Set<ZSetOperations.TypedTuple<Object>> userZset1 = operations.rangeWithScores("userZset", 0, 2);
for (ZSetOperations.TypedTuple<Object> objectTypedTuple : userZset1) {
String value = (String) objectTypedTuple.getValue();
Double score = (Double) objectTypedTuple.getScore();
System.out.println("value: " + value + ", scopre:" + score);
}
// 通过分数区间获取集合元素
Set<Object> userZset2 = operations.rangeByScore("userZset", 95, 100);
userZset2.forEach(System.out::println);
Set<Object> userZset3 = operations.reverseRangeByScore("userZset", 95, 100);
userZset3.forEach(System.out::println);
// 通过分数区间获取元素和分数
Set users = operations.rangeByScoreWithScores("userZset", 95, 100);
// 以上都是从小到大排序,从大到小排序,只需要在方法前加上reverse
users.forEach(System.out::println);
}
好了以上就是一些常见的api使用,希望能帮助到大家。