当前位置:   article > 正文

springboot配置redis+jedis,支持基础redis,并实现jedis GEO地图功能

springboot配置redis+jedis,支持基础redis,并实现jedis GEO地图功能

Springboot配置redis+jedis,已在项目中测试并成功运行,支持基础redis操作,并通过jedis做了redis GEO地图的java实现,GEO支持存储地理位置信息来实现诸如附近的人、摇一摇等这类依赖于地理位置信息的功能。本文参考了网上多篇博文,具体的记录不记得了...所以不一一列出,有任何问题请联系我删除。

一、添加依赖
  1. <!--redis-->
  2. <!-- 注意:1.5版本的依赖和2.0的依赖不一样,1.5名字里面应该没有“data”, 2.0必须是“spring-boot-starter-data-redis” 这个才行-->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-data-redis</artifactId>
  6. <!-- 1.5的版本默认采用的连接池技术是jedis 2.0以上版本默认连接池是lettuce, 在这里采用jedis,所以需要排除lettuce的jar -->
  7. <exclusions>
  8. <exclusion>
  9. <groupId>redis.clients</groupId>
  10. <artifactId>jedis</artifactId>
  11. </exclusion>
  12. <exclusion>
  13. <groupId>io.lettuce</groupId>
  14. <artifactId>lettuce-core</artifactId>
  15. </exclusion>
  16. </exclusions>
  17. </dependency>
  18. <!-- 添加jedis客户端 -->
  19. <dependency>
  20. <groupId>redis.clients</groupId>
  21. <artifactId>jedis</artifactId>
  22. </dependency>
  23. <!--spring2.0集成redis所需common-pool2-->
  24. <!-- 必须加上,jedis依赖此 -->
  25. <!-- spring boot 2.0 的操作手册有标注 大家可以去看看 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/-->
  26. <dependency>
  27. <groupId>org.apache.commons</groupId>
  28. <artifactId>commons-pool2</artifactId>
  29. <version>2.5.0</version>
  30. </dependency>
  31. <!-- 将作为Redis对象序列化器 -->
  32. <dependency>
  33. <groupId>com.alibaba</groupId>
  34. <artifactId>fastjson</artifactId>
  35. <version>1.2.47</version>
  36. </dependency>
二、配置文件(application.properties)
  1. #redis配置
  2. spring.redis.host=127.0.0.1
  3. spring.redis.port=6379
  4. spring.redis.password=12345
  5. spring.redis.timeout=20000
  6. #连接池最大连接数(使用负值表示没有限制)
  7. spring.redis.jedis.pool.max-active=100
  8. #连接池最大阻塞等待时间(使用负值表示没有限制)
  9. spring.redis.jedis.pool.max-wait=-1
  10. #连接池中的最大空闲连接
  11. spring.redis.jedis.pool.max-idle=10
  12. #连接池中的最小空闲连接
  13. spring.redis.jedis.pool.min-idle=0
  14. #寻找队伍,主键key
  15. join.team.key=joinTeam
  16. #寻找队伍,失效时间(单位:秒)
  17. join.team.time=1800
三、初始化redis和jedis
  1. @Slf4j
  2. @Configuration
  3. @EnableCaching
  4. public class RedisConfig extends CachingConfigurerSupport {
  5. @Autowired
  6. private JedisConnectionFactory jedisConnectionFactory;
  7. @Value("${spring.redis.host}")
  8. private String host;
  9. @Value("${spring.redis.port}")
  10. private int port;
  11. @Value("${spring.redis.timeout}")
  12. private int timeout;
  13. @Value("${spring.redis.jedis.pool.max-idle}")
  14. private int maxIdle;
  15. @Value("${spring.redis.jedis.pool.min-idle}")
  16. private int minIdle;
  17. @Value("${spring.redis.jedis.pool.max-active}")
  18. private int maxActive;
  19. /**
  20. * 生成key的策略
  21. * @return
  22. */
  23. @Bean
  24. public KeyGenerator keyGenerator() {
  25. //设置自动key的生成规则,配置springboot的注解,进行方法级别的缓存
  26. //使用:进行分割,可以更多的显示出层级关系
  27. return new KeyGenerator() {
  28. @Override
  29. public Object generate(Object o, Method method, Object... objects) {
  30. StringBuilder stringBuilder = new StringBuilder();
  31. stringBuilder.append(o.getClass().getName());
  32. stringBuilder.append(":");
  33. stringBuilder.append(method.getName());
  34. for (Object object : objects) {
  35. stringBuilder.append(":" + String.valueOf(object));
  36. }
  37. String key = String.valueOf(stringBuilder);
  38. log.info("自动生成Redis Key -> [{}]", key);
  39. return key;
  40. }
  41. };
  42. }
  43. @Bean
  44. @Override
  45. public CacheManager cacheManager() {
  46. //初始化缓存管理器,在这里可以缓存的整体过期时间等,默认么有配置
  47. log.info("初始化 -> [{}]", "CacheManager RedisCacheManager Start");
  48. RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(jedisConnectionFactory);
  49. return builder.build();
  50. }
  51. @Bean
  52. public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
  53. //设置序列化
  54. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  55. ObjectMapper objectMapper = new ObjectMapper();
  56. objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  57. objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  58. jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
  59. //配置redisTemplate
  60. RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
  61. redisTemplate.setConnectionFactory(jedisConnectionFactory);
  62. RedisSerializer serializer = new StringRedisSerializer();
  63. redisTemplate.setKeySerializer(serializer);//key序列化
  64. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);//value序列化
  65. redisTemplate.setHashKeySerializer(serializer);//Hash key 序列化
  66. redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);//Hash value序列化
  67. redisTemplate.afterPropertiesSet();
  68. return redisTemplate;
  69. }
  70. @Override
  71. @Bean
  72. public CacheErrorHandler errorHandler() {
  73. //异常处理,当Redis发生异常时,打印日志,但是程序正常运行
  74. log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
  75. CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
  76. @Override
  77. public void handleCacheGetError(RuntimeException e, Cache cache, Object o) {
  78. log.error("Redis occur handleCacheGetError:key -> [{}]", o, e);
  79. }
  80. @Override
  81. public void handleCachePutError(RuntimeException e, Cache cache, Object o, Object o1) {
  82. log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", o, o1, e);
  83. }
  84. @Override
  85. public void handleCacheEvictError(RuntimeException e, Cache cache, Object o) {
  86. log.error("Redis occur handleCacheEvictError:key -> [{}]", o, e);
  87. }
  88. @Override
  89. public void handleCacheClearError(RuntimeException e, Cache cache) {
  90. log.error("Redis occur handleCacheClearError:", e);
  91. }
  92. };
  93. return cacheErrorHandler;
  94. }
  95. @Bean
  96. public JedisPoolConfig setJedisPoolConfig() {
  97. JedisPoolConfig poolConfig = new JedisPoolConfig();
  98. poolConfig.setMaxTotal(maxActive);//最大连接数,连接全部用完,进行等待
  99. poolConfig.setMinIdle(minIdle); //最小空余数
  100. poolConfig.setMaxIdle(maxIdle); //最大空余数
  101. return poolConfig;
  102. }
  103. @Bean
  104. public JedisPool setJedisPool(JedisPoolConfig jedisPoolConfig) {
  105. JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
  106. return jedisPool;
  107. }
  108. }
四、封装jedis常用方法

我主要封装了关于GEO地图的方法,实际项目中只用了其中两个功能,所以我只写了两个,要用其他的自己去封装就好了。

  1. @Slf4j
  2. @Component
  3. public class JedisClient {
  4. @Autowired
  5. private JedisPool jedisPool;
  6. @Value("${spring.redis.password}")
  7. private String password;
  8. @Value("${join.team.key}")
  9. private String key;
  10. @Value("${join.team.time}")
  11. private String time;
  12. public void release(Jedis jedis) {
  13. if (jedis != null) {
  14. jedis.close();
  15. }
  16. }
  17. private Jedis getJedis(JedisPool jedisPool) {
  18. Jedis jedis = jedisPool.getResource();
  19. jedis.auth(password);
  20. //设置键为key时的超时时间(寻找队伍,失效时间)
  21. jedis.expire(key, Integer.parseInt(time));
  22. return jedis;
  23. }
  24. /**
  25. * 增加用户地理位置的坐标
  26. * @param key
  27. * @param coordinate
  28. * @param memberName
  29. * @return
  30. */
  31. public Long geoadd(String key, GeoCoordinate coordinate, String memberName) {
  32. Jedis jedis = null;
  33. try {
  34. jedis = this.getJedis(jedisPool);
  35. return jedis.geoadd(key, coordinate.getLongitude(), coordinate.getLatitude(), memberName);
  36. } catch (Exception e) {
  37. log.error(e.getMessage());
  38. } finally {
  39. release(jedis);
  40. }
  41. return null;
  42. }
  43. /**
  44. * 根据给定地理位置坐标获取指定范围的用户地理位置集合(匹配位置的经纬度 + 相隔距离 + 从近到远排序)
  45. * @param key
  46. * @param coordinate
  47. * @param radius 指定半径
  48. * @param geoUnit 单位
  49. * @return
  50. */
  51. public List<GeoRadiusResponse> geoRadius(String key, GeoCoordinate coordinate, int radius, GeoUnit geoUnit) {
  52. Jedis jedis = null;
  53. try {
  54. jedis = this.getJedis(jedisPool);
  55. return jedis.georadius(key, coordinate.getLongitude(), coordinate.getLatitude(), radius, geoUnit);
  56. } catch (Exception e) {
  57. log.error(e.getMessage());
  58. } finally {
  59. release(jedis);
  60. }
  61. return null;
  62. }
  63. /**
  64. * 查询两位置距离
  65. * @param key
  66. * @param member1
  67. * @param member2
  68. * @param unit
  69. * @return
  70. */
  71. public Double geoDist(String key, String member1, String member2, GeoUnit unit) {
  72. Jedis jedis = null;
  73. try {
  74. jedis = this.getJedis(jedisPool);
  75. return jedis.geodist(key, member1, member2, unit);
  76. } catch (Exception e) {
  77. log.error(e.getMessage());
  78. } finally {
  79. release(jedis);
  80. }
  81. return null;
  82. }
  83. /**
  84. * 从集合中删除元素
  85. * @param key
  86. * @param member
  87. * @return
  88. */
  89. public Boolean geoRemove(String key, String member) {
  90. Jedis jedis = null;
  91. try {
  92. jedis = this.getJedis(jedisPool);
  93. return jedis.zrem(key, member) == 1 ? true : false;
  94. } catch (Exception e) {
  95. log.error(e.getMessage());
  96. } finally {
  97. release(jedis);
  98. }
  99. return null;
  100. }
  101. /**
  102. * 加入到sort里的数量
  103. * @param key
  104. * @return
  105. */
  106. public Long geoLen(String key) {
  107. Jedis jedis = null;
  108. try {
  109. jedis = this.getJedis(jedisPool);
  110. return jedis.zcard(key);
  111. } catch (Exception e) {
  112. log.error(e.getMessage());
  113. } finally {
  114. release(jedis);
  115. }
  116. return null;
  117. }
  118. /**
  119. * 所有集合
  120. * @param key
  121. * @return
  122. */
  123. public List<String> geoMembers(String key) {
  124. Jedis jedis = null;
  125. try {
  126. jedis = this.getJedis(jedisPool);
  127. return jedis.sort(key);
  128. } catch (Exception e) {
  129. log.error(e.getMessage());
  130. } finally {
  131. release(jedis);
  132. }
  133. return null;
  134. }
  135. }
五、实际使用
  1. @Service
  2. @Transactional
  3. public class BgUserServiceImpl extends AbstractService<BgUser> implements BgUserService {
  4. @Resource
  5. private BgUserMapper bgUserMapper;
  6. @Resource
  7. private BgUserRoleService bgUserRoleService;
  8. @Resource
  9. private BgUserGameService bgUserGameService;
  10. @Autowired
  11. private JedisClient jedisClient;
  12. @Value("${join.team.key}")
  13. private String key;
  14. ...
  15. @Override
  16. public int joinTeam(BgUser bgUser) {
  17. if (bgUser.getLongitude() == null || bgUser.getLatitude() == null) {
  18. return 0;
  19. }
  20. GeoCoordinate geoCoordinate = new GeoCoordinate(bgUser.getLongitude(), bgUser.getLatitude());
  21. long count = jedisClient.geoadd(key, geoCoordinate, bgUser.getUserId().toString());
  22. return (int)count;
  23. }
  24. @Override
  25. public List<BgUser> getNearUser(int distance, BgUser bgUser) {
  26. List<BgUser> bgUsers = new ArrayList<>();
  27. if (bgUser.getLongitude() == null || bgUser.getLatitude() == null) {
  28. return bgUsers;
  29. }
  30. GeoCoordinate geoCoordinate = new GeoCoordinate(bgUser.getLongitude(), bgUser.getLatitude());
  31. List<GeoRadiusResponse> geoRadiusResponses = jedisClient.geoRadius(key, geoCoordinate, distance, GeoUnit.M);
  32. //这里是java8流式编程,这样用很方便
  33. List<Long> userIds = geoRadiusResponses.stream().map(GeoRadiusResponse::getMemberByString).map(geoRadiusResponse -> Long.valueOf(geoRadiusResponse)).collect(Collectors.toList());
  34. if (userIds != null && userIds.size() > 0) {
  35. bgUsers = bgUserMapper.getListByUserIds(userIds);
  36. }
  37. return bgUsers;
  38. }
  39. }

转载于:https://www.cnblogs.com/zys-blog/p/10557149.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/159969
推荐阅读
相关标签
  

闽ICP备14008679号