SpringBoot依赖之Spring Data Redis的功能抽离公共服务
前几期我们针对在SpringBoot中的 Spring Data Redis 依赖对Redis不同类型的存储格式进行了细分学习,今天在这里进行汇总,当然如果你的项目使用的是Spring Data Redis这个原生官方以来,下面的汇总类RedisService 也可以作为公共类用在你们的项目当中。
项目学习代码地址
往期文章
SpringBoot依赖之Spring Data Redis 一 String类型
SpringBoot依赖之Spring Data Redis 一 List 类型
SpringBoot依赖之Spring Data Redis 一 Hash类型
SpringBoot依赖之Spring Data Redis一集合Set
SpringBoot依赖之Spring Data Redis一有序集合Sorted Set
SpringBoot依赖之Spring Data Redis实现位图Bitmap
SpringBoot依赖之Spring Data Redis 实现地理坐标(Geospatial)
我们可以在 RedisService
和 RedisController
中实现对 Redis 其他几种类型(String、List、Set、Sorted Set、Bitmap、HyperLogLog 等)的操作。以下是所有 Redis 数据类型的实现。
1. 更新 Redis 服务类
文中涉及的学习代码地址
在 RedisService
类中添加所有类型的操作方法。
package com.dependencies.springdataredis;
import org.springframework.data.domain.Range;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author zhizhou 2024/8/17 12:01
*/
@Service
public class RedisService {
private final RedisTemplate<String, Object> redisTemplate;
private final HashOperations<String, String, Object> hashOperations;
private final ListOperations<String, Object> listOperations;
private final ValueOperations<String, Object> valueOperations;
private final SetOperations<String, Object> setOperations;
private final ZSetOperations<String, Object> zSetOperations;
private final HyperLogLogOperations<String, Object> hyperLogLogOperations;
private final GeoOperations<String, Object> geoOperations;
public RedisService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
this.valueOperations = redisTemplate.opsForValue();
this.hashOperations = redisTemplate.opsForHash();
this.listOperations = redisTemplate.opsForList();
this.setOperations = redisTemplate.opsForSet();
this.zSetOperations = redisTemplate.opsForZSet();
this.hyperLogLogOperations = redisTemplate.opsForHyperLogLog();
this.geoOperations = redisTemplate.opsForGeo();
}
public void saveValue(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
public String getValue(String key) {
return (String) redisTemplate.opsForValue().get(key);
}
//hash
// 保存哈希数据
public void saveToHash(String key, String field, String value) {
hashOperations.put(key, field, value);
}
// 从哈希中获取数据
public String getFromHash(String key, String field) {
return (String) hashOperations.get(key, field);
}
// 删除哈希中的某个字段
public void deleteFromHash(String key, String field) {
hashOperations.delete(key, field);
}
// 获取哈希中的所有键值对
public Map<String, Object> getAllFromHash(String key) {
return hashOperations.entries(key);
}
//list
// 向列表左侧推入值
public void pushToListLeft(String key, String value) {
listOperations.leftPush(key, value);
}
// 向列表右侧推入值
public void pushToListRight(String key, String value) {
listOperations.rightPush(key, value);
}
// 从列表左侧弹出值
public String popFromListLeft(String key) {
return (String) listOperations.leftPop(key);
}
// 从列表右侧弹出值
public String popFromListRight(String key) {
return (String) listOperations.rightPop(key);
}
// 获取列表中所有值
public List<Object> getList(String key) {
return listOperations.range(key, 0, -1);
}
//Set
// Set操作
public void addToSet(String key, String value) {
setOperations.add(key, value);
}
public Set<Object> getSetMembers(String key) {
return setOperations.members(key);
}
public boolean isMemberOfSet(String key, String value) {
return setOperations.isMember(key, value);
}
public void removeFromSet(String key, String value) {
setOperations.remove(key, value);
}
// Sorted Set操作
public void addToSortedSet(String key, String value, double score) {
zSetOperations.add(key, value, score);
}
public Set<Object> getSortedSetRange(String key, long start, long end) {
return zSetOperations.range(key, start, end);
}
public void removeFromSortedSet(String key, String value) {
zSetOperations.remove(key, value);
}
// HyperLogLog操作
public void addToHyperLogLog(String key, String value) {
hyperLogLogOperations.add(key, value);
}
public long countInHyperLogLog(String key) {
return hyperLogLogOperations.size(key);
}
// Bitmap操作
public void setBit(String key, long offset, boolean value) {
valueOperations.setBit(key, offset, value);
}
public boolean getBit(String key, long offset) {
return valueOperations.getBit(key, offset);
}
private static final String GEO_KEY = "locations";
// 添加地理坐标
public void addLocation(String member, double longitude, double latitude) {
geoOperations.add(GEO_KEY, new Point(longitude, latitude), member);
}
// 根据坐标查询附近的地点
public List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> getNearbyLocations(double longitude, double latitude, double radius) {
Circle within = new Circle(new Point(longitude, latitude), new Distance(radius, RedisGeoCommands.DistanceUnit.KILOMETERS));
return geoOperations.radius(GEO_KEY, within).getContent();
}
// 获取两地之间的距离
public Distance getDistance(String member1, String member2) {
return geoOperations.distance(GEO_KEY, member1, member2, RedisGeoCommands.DistanceUnit.METERS);
}
}
2. 更新控制器类
在 RedisController
中添加处理这些数据类型操作的端点。
package com.dependencies.springdataredis;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author zhizhou 2024/8/17 12:02
*/
@RestController
public class RedisController {
private final RedisService redisService;
public RedisController(RedisService redisService) {
this.redisService = redisService;
}
@GetMapping("/set")
public String setKey(@RequestParam String key, @RequestParam String value) {
redisService.saveValue(key, value);
return "保存成功";
}
@GetMapping("/get")
public String getKey(@RequestParam String key) {
return redisService.getValue(key);
}
@GetMapping("/hash/set")
public String setHash(@RequestParam String key, @RequestParam String field, @RequestParam String value) {
redisService.saveToHash(key, field, value);
return "哈希值保存成功";
}
// 获取哈希中的数据
@GetMapping("/hash/get")
public String getHash(@RequestParam String key, @RequestParam String field) {
return redisService.getFromHash(key, field);
}
// 删除哈希中的某个字段
@GetMapping("/hash/delete")
public String deleteHashField(@RequestParam String key, @RequestParam String field) {
redisService.deleteFromHash(key, field);
return "哈希字段已删除";
}
// 获取哈希中的所有字段和值
@GetMapping("/hash/getall")
public Map<String, Object> getAllHash(@RequestParam String key) {
return redisService.getAllFromHash(key);
}
// 向列表左侧推入值
@GetMapping("/list/leftpush")
public String leftPushToList(@RequestParam String key, @RequestParam String value) {
redisService.pushToListLeft(key, value);
return "值被推到列表的左侧";
}
// 向列表右侧推入值
@GetMapping("/list/rightpush")
public String rightPushToList(@RequestParam String key, @RequestParam String value) {
redisService.pushToListRight(key, value);
return "值被推到列表的右侧";
}
// 从列表左侧弹出值
@GetMapping("/list/leftpop")
public String leftPopFromList(@RequestParam String key) {
return redisService.popFromListLeft(key);
}
// 从列表右侧弹出值
@GetMapping("/list/rightpop")
public String rightPopFromList(@RequestParam String key) {
return redisService.popFromListRight(key);
}
// 获取列表中所有值
@GetMapping("/list/getall")
public List<Object> getAllFromList(@RequestParam String key) {
return redisService.getList(key);
}
// Set操作
@GetMapping("/set/add")
public String addToSet(@RequestParam String key, @RequestParam String value) {
redisService.addToSet(key, value);
return "值已加入集合set";
}
@GetMapping("/set/members")
public Set<Object> getSetMembers(@RequestParam String key) {
return redisService.getSetMembers(key);
}
@GetMapping("/set/ismember")
public boolean isMemberOfSet(@RequestParam String key, @RequestParam String value) {
return redisService.isMemberOfSet(key, value);
}
@GetMapping("/set/remove")
public String removeFromSet(@RequestParam String key, @RequestParam String value) {
redisService.removeFromSet(key, value);
return "值已从集合set移除";
}
// Sorted Set操作
@GetMapping("/zset/add")
public String addToSortedSet(@RequestParam String key, @RequestParam String value, @RequestParam double score) {
redisService.addToSortedSet(key, value, score);
return "值已加入有序集合sorted set";
}
@GetMapping("/zset/range")
public Set<Object> getSortedSetRange(@RequestParam String key, @RequestParam long start, @RequestParam long end) {
return redisService.getSortedSetRange(key, start, end);
}
@GetMapping("/zset/remove")
public String removeFromSortedSet(@RequestParam String key, @RequestParam String value) {
redisService.removeFromSortedSet(key, value);
return "值已从有序集合sorted set移除";
}
// HyperLogLog操作
@GetMapping("/hyperloglog/add")
public String addToHyperLogLog(@RequestParam String key, @RequestParam String value) {
redisService.addToHyperLogLog(key, value);
return "Value added to HyperLogLog";
}
@GetMapping("/hyperloglog/count")
public long countInHyperLogLog(@RequestParam String key) {
return redisService.countInHyperLogLog(key);
}
// Bitmap操作
@GetMapping("/bitmap/set")
public String setBit(@RequestParam String key, @RequestParam long offset, @RequestParam boolean value) {
redisService.setBit(key, offset, value);
return "Bit set in bitmap";
}
@GetMapping("/bitmap/get")
public boolean getBit(@RequestParam String key, @RequestParam long offset) {
return redisService.getBit(key, offset);
}
// Geo操作
//添加地理位置
@GetMapping("/add-location")
public String addLocation(@RequestParam String member, @RequestParam double longitude, @RequestParam double latitude) {
redisService.addLocation(member, longitude, latitude);
return "Location added.";
}
//查询附近的地点
@GetMapping("/nearby")
public List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> getNearbyLocations(@RequestParam double longitude, @RequestParam double latitude, @RequestParam double radius) {
return redisService.getNearbyLocations(longitude, latitude, radius);
}
//# 如果使用 Lettuce 作为客户端 lettuce
//获取两地之间的距离
@GetMapping("/distance")
public Distance getDistance(@RequestParam String member1, @RequestParam String member2) {
return redisService.getDistance(member1, member2);
}
}
项目学习代码地址
3. 测试操作
启动项目后,可以通过以下 URL 测试各种 Redis 数据类型的功能:
-
String操作:
-
设置值:
http://localhost:8080/set?key=myKey&value=myValue
-
获取值:
http://localhost:8080/get?key=myKey
-
-
List操作:
- 向列表左侧推入值:
http://localhost:8080/list/leftpush?key=myList&value=value1
- 向列表右侧推入值:
http://localhost:8080/list/rightpush?key=myList&value=value2
- 从列表左侧弹出值:
http://localhost:8080/list/leftpop?key=myList
- 从列表右侧弹出值:
http://localhost:8080/list/rightpop?key=myList
- 获取列表中所有值:
http://localhost:8080/list/getall?key=myList
- 向列表左侧推入值:
-
Hash操作:
-
保存哈希数据:
http://localhost:8080/hash/set?key=user:1001&field=name&value=一周一志程序员
-
获取哈希数据:
http://localhost:8080/hash/get?key=user:1001&field=name
-
删除哈希字段:
http://localhost:8080/hash/delete?key=user:1001&field=name
-
获取所有哈希数据:
http://localhost:8080/hash/getall?key=user:1001
-
-
Set 操作:
- 添加成员到集合:
http://localhost:8080/set/add?key=mySet&value=value1
- 获取集合中的所有成员:
http://localhost:8080/set/members?key=mySet
- 检查成员是否在集合中:
http://localhost:8080/set/ismember?key=mySet&value=value1
- 删除集合中的成员:
http://localhost:8080/set/remove?key=mySet&value=value1
- 添加成员到集合:
-
Sorted Set 操作:
- 添加成员到有序集合:
http://localhost:8080/zset/add?key=myZSet&value=value1&score=1.0
- 获取有序集合中的成员范围:
http://localhost:8080/zset/range?key=myZSet&start=0&end=-1
- 删除有序集合中的成员:
http://localhost:8080/zset/remove?key=myZSet&value=value1
- 添加成员到有序集合:
-
HyperLogLog 操作:
- 添加成员到 HyperLogLog:
http://localhost:8080/hyperloglog/add?key=myHLL&value=value1
- 获取 HyperLogLog 的基数估算:
http://localhost:8080/hyperloglog/count?key=myHLL
- 添加成员到 HyperLogLog:
-
Bitmap 操作:
- 设置 Bitmap 中某个位的值:
http://localhost:8080/bitmap/set?key=myBitmap&offset=7&value=true
- 获取 Bitmap 中某个位的值:
http://localhost:8080/bitmap/get?key=myBitmap&offset=7
- 设置 Bitmap 中某个位的值:
-
Geospatial 操作:
- 添加地理位置:
http://localhost:8080/add-location?member=location1&longitude=13.361389&latitude=38.115556
- 查询附近的地点:
http://localhost:8080/nearby?longitude=13.361389&latitude=38.115556&radius=10
- 获取两地之间的距离:
http://localhost:8080/distance?member1=location1&member2=location2
- 添加地理位置:
4. 总结
通过这些步骤,我们在 Spring Boot 项目中成功实现了对 Redis 各种数据类型(String、List、Set、Sorted Set、Bitmap、HyperLogLog 等)的操作。可以处理和管理 Redis 中的各种复杂数据结构,适应不同的应用场景需求。汇总到此结束。关注我一起为Java程序员蓄能,努力为职业生涯续航!