前言
SpringDataRedis提供了十分简单的地理位置定位的功能,今天我就用一小段代码告诉大家如何实现。
正文
1、引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2、更新用户位置信息
编写一个更新用户位置信息的接口,其中几个参数的含义如下:
userId:要更新位置信息或查询附近的人的用户ID。longitude:新的经度值或查询附近的人时指定的中心经度。latitude:新的纬度值或查询附近的人时指定的中心纬度。
@Autowired private RedisTemplate<String, Object> redisTemplate; // 更新用户位置信息 @PostMapping("/{userId}/location") public void updateUserLocation(@PathVariable long userId, @RequestParam double longitude, @RequestParam double latitude) { String userLocationKey = "user_location"; // 使用Redis的地理位置操作对象,将用户的经纬度信息添加到指定的key中 redisTemplate.opsForGeo().add(userLocationKey, new Point(longitude, latitude), userId); }
3、获取附近的人
编写一个获取附近的人的接口
@Autowired private RedisTemplate<String, Object> redisTemplate; // 获取附近的人 @GetMapping("/{userId}/nearby") public List<Object> getNearbyUsers(@PathVariable long userId, @RequestParam double longitude, @RequestParam double latitude, @RequestParam double radius) { String userLocationKey = "user_location"; Distance distance = new Distance(radius, Metrics.KILOMETERS); Circle circle = new Circle(new Point(longitude, latitude), distance); // 使用Redis的地理位置操作对象,在指定范围内查询附近的用户位置信息 GeoResults<GeoLocation<Object>> geoResults = redisTemplate .opsForGeo() .radius(userLocationKey, circle); List<Object> nearbyUsers = new ArrayList<>(); for (GeoResult<GeoLocation<Object>> geoResult : geoResults.getContent()) { Object memberId = geoResult.getContent().getName(); // 排除查询用户本身 if (!memberId.equals(userId)) { nearbyUsers.add(memberId); } } return nearbyUsers; }
其中几个重要属性的含义如下:
Distance:Spring Data Redis中的一个类,用于表示距离。它可以用于指定搜索半径或者计算两点之间的距离。在示例代码中,我们创建了一个Distance对象来指定搜索范围的半径,并使用Metrics.KILOMETERS表示以千米为单位的距离。
Circle:Spring Data Redis中的一个类,用于表示圆形区域。它由一个中心点(用Point表示)和一个半径(用Distance表示)组成。在示例代码中,我们通过传入中心点和距离创建了一个Circle对象,用于定义附近人搜索的圆形区域。
GeoResults:Spring Data Redis中的一个类,用于表示地理位置查询的结果。它包含了一个Content属性,该属性是一个List<GeoResult<GeoLocation<Object>>>类型的列表,其中每个GeoResult对象都包含了地理位置信息以及与该位置相关的其他数据。在示例代码中,我们通过调用redisTemplate.opsForGeo().radius()方法返回了一个GeoResults对象,其中包含了在指定范围内的所有地理位置结果。
4、完整代码如下
为了用更少的代码片段让大家一目了然,所以都写在controller中,应用在项目里面时最好把其中的实现部分都转移到service中。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResult; import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("/users") public class UserController { @Autowired private RedisTemplate<String, Object> redisTemplate; // 更新用户位置信息 @PostMapping("/{userId}/location") public void updateUserLocation(@PathVariable long userId, @RequestParam double longitude, @RequestParam double latitude) { String userLocationKey = "user_location"; // 使用Redis的地理位置操作对象,将用户的经纬度信息添加到指定的key中 redisTemplate.opsForGeo().add(userLocationKey, new Point(longitude, latitude), userId); } // 获取附近的人 @GetMapping("/{userId}/nearby") public List<Object> getNearbyUsers(@PathVariable long userId, @RequestParam double longitude, @RequestParam double latitude, @RequestParam double radius) { String userLocationKey = "user_location"; Distance distance = new Distance(radius, Metrics.KILOMETERS); Circle circle = new Circle(new Point(longitude, latitude), distance); // 使用Redis的地理位置操作对象,在指定范围内查询附近的用户位置信息 GeoResults<GeoLocation<Object>> geoResults = redisTemplate .opsForGeo() .radius(userLocationKey, circle); List<Object> nearbyUsers = new ArrayList<>(); for (GeoResult<GeoLocation<Object>> geoResult : geoResults.getContent()) { Object memberId = geoResult.getContent().getName(); // 排除查询用户本身 if (!memberId.equals(userId)) { nearbyUsers.add(memberId); } } return nearbyUsers; } }
总结
SpringDataRedis本身也是对Redis底层命令的封装,所以Jedis里面其实也提供了差不多的实现,大家可以自己去试一试。
如果有redis相关的面试,如果能说出Redis的Geo命令,面试官就知道你有研究过,是可以大大加分的。
侧面证明了你对Redis的了解不局限于简单的set、get命令,希望这篇文章对大家有所帮助。
如果喜欢,记得点赞关注↓↓↓,持续分享干货!