| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- package zs.payment.utils;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.data.redis.core.ZSetOperations;
- import org.springframework.stereotype.Repository;
- import redis.clients.jedis.GeoCoordinate;
- import redis.clients.jedis.GeoUnit;
- import redis.clients.jedis.Pipeline;
- import redis.clients.jedis.Tuple;
- import redis.clients.jedis.params.SetParams;
- import java.util.*;
- import java.util.concurrent.TimeUnit;
- import java.util.stream.Collectors;
- /**
- * 该redis主要包含支付、订单等数据相关缓存(与资讯池共用)
- */
- @Repository
- @Slf4j
- public class RedisUtils {
- @Value("${pay.redis.master}")
- private String ecoCluster;
- public void set(String key, String cont) {
- set(key, cont, 0);
- }
- public void set(String key, String cont, int seconds) {
- Redis.withCluster(ecoCluster, jedis -> {
- jedis.set(key, cont);
- if (seconds > 0) {
- jedis.expire(key, seconds);
- }
- return null;
- });
- }
- public String get(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.get(key));
- }
- public String getByKey(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.get(key));
- }
- public List<String> lRange(String key, long startIndex, long endIndex) {
- List<String> back = new ArrayList<>();
- if (key == null || key.isEmpty()) {
- return back;
- }
- Redis.withCluster(ecoCluster, jedis ->
- back.addAll(jedis.lrange(key, startIndex, endIndex))
- );
- return back;
- }
- public List<String> mget(List<String> keys) {
- List<String> back = new ArrayList<>();
- if (keys == null || keys.isEmpty()) {
- return back;
- }
- Redis.withCluster(ecoCluster, jedis ->
- back.addAll(jedis.mget(keys.toArray(new String[0])))
- );
- return back;
- }
- public Long del(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.del(key));
- }
- public void hset(String key, String field, String cont) {
- hset(key, field, cont, 0);
- }
- public void hset(String key, String field, String cont, int seconds) {
- Redis.withCluster(ecoCluster, jedis -> {
- jedis.hset(key, field, cont);
- if (seconds > 0) {
- jedis.expire(key, seconds);
- }
- return null;
- });
- }
- public void hmset(String key, Map<String, String> hash) {
- hmset(key, hash, 0);
- }
- public void hmset(String key, Map<String, String> hash, int seconds) {
- Redis.withCluster(ecoCluster, jedis -> {
- jedis.hmset(key, hash);
- if (seconds > 0) {
- jedis.expire(key, seconds);
- }
- return null;
- });
- }
- public Long hincrBy(String key, String field, long value) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.hincrBy(key, field, value));
- }
- public String hget(String key, String field) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.hget(key, field));
- }
- public Map<String, String> hgetAll(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.hgetAll(key));
- }
- public void hdel(String key, String field) {
- Redis.withCluster(ecoCluster, jedis -> {
- jedis.hdel(key, field);
- return null;
- });
- }
- /**
- *
- * 添加
- * redis> SADD myset "one"
- * @param key
- * @param members
- * @return
- */
- public long sadd(String key, String... members) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.sadd(key, members));
- }
- /**
- * 删除
- * redis> SREM myset "one"
- * @param key
- * @param members
- * @return
- */
- public long srem(String key,String... members){
- return Redis.withCluster(ecoCluster,jedis -> jedis.srem(key,members));
- }
- public Set<String> smembers(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.smembers(key));
- }
- public Boolean sismember(String key,String value){
- return Redis.withCluster(ecoCluster,jedis -> jedis.sismember(key,value));
- }
- public long zadd(String key, double score, String member) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zadd(key, score, member));
- }
- /**
- * 向有序集合批量添加元素(使用 Tuple 集合)
- * @param key 键
- * @param tuples 元组集合(包含分数和成员)
- * @return 成功添加的数量
- */
- public Long zadd(String key, Set<ZSetOperations.TypedTuple<String>> tuples) {
- if (tuples == null || tuples.isEmpty()) {
- return 0L;
- }
- long result = 0L;
- for (ZSetOperations.TypedTuple<String> tuple : tuples) {
- result=result+ Redis.withCluster(ecoCluster, jedis -> jedis.zadd(key, tuple.getScore(),tuple.getValue()));
- }
- return result;
- }
- // /**
- // * 通过管道模式一次性添加多个值
- // *
- // * @param key
- // * @param list
- // */
- // public void zaddWithPipeline(String key, List<?> list) {
- // Redis.withCluster(ecoCluster, jedis -> {
- // Pipeline pipeline = jedis.pipelined();
- // for (Object item : list) {
- // double score = Double.parseDouble(((Map<?, ?>) item).get("userId").toString());
- // jedis.zadd(key, score, Strings.toJson(item));
- // }
- // pipeline.syncAndReturnAll();
- // });
- // }
- public long llen(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.llen(key));
- }
- public List<String> lrangeList(String key, int start, int end) {
- List<String> result = Redis.withCluster(ecoCluster, jedis -> jedis.lrange(key, start, end));
- return result != null ? result : new ArrayList<>();
- }
- public void lpush(String key, String... strings) {
- Redis.withCluster(ecoCluster, jedis -> {
- jedis.lpush(key, strings);
- return null;
- });
- }
- public long rpush(String key, String value) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.rpush(key, value));
- }
- public String rpop(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.rpop(key));
- }
- public String lpop(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.lpop(key));
- }
- public long zrem(String key, String member) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zrem(key, member));
- }
- /**
- *
- * 返回有序集的元素个数(对应 redisTemplate.opsForZSet().size())
- * @param key
- * @return
- */
- public long zcard(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zcard(key));
- }
- public Double zscore(String key, String member) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zscore(key, member));
- }
- /**
- * 倒序(从大到小)获取指定区间内的数据
- *
- * @param key
- * @param start
- * @param end
- * @return
- */
- public Set<String> zrevrange(String key, long start, long end) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zrevrange(key, start, end));
- }
- /**
- * 正序(从小到大)获取指定区间内的数据
- *
- * @param key
- * @param start
- * @param end
- * @return
- */
- public Set<String> zrange(String key, long start, long end) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zrange(key, start, end));
- }
- /**
- * 根据score值,倒序(从大到小)获取指定区间内的数据
- *
- * @param key
- * @param score
- * @param psize
- * @return
- */
- public Set<String> zrevrangeByScore(String key, String score, Integer psize) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zrevrangeByScore(key, "(" + score, "-inf", 0, psize));
- }
- /**
- * 获取score值介于score1和score2之间的数据
- *
- * @param key
- * @param score1
- * @param score2
- * @return
- */
- public Set<String> zrangeByScore(String key, String score1, String score2) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zrangeByScore(key, score1, score2));
- }
- /**
- * 设置自增长
- *
- * @param key
- * @return
- */
- public synchronized long setIncyBy(String key) {
- return setIncyBy(key, 1L, 0);
- }
- /**
- * 设置自增长
- *
- * @param key
- * @param num
- * @return
- */
- public synchronized long setIncyBy(String key, long num) {
- return setIncyBy(key, num, 0);
- }
- /**
- * 设置自增长
- *
- * @param key
- * @param num
- * @param seconds
- * @return
- */
- public synchronized long setIncyBy(String key, long num, int seconds) {
- return Redis.withCluster(ecoCluster, jedis -> {
- long result = jedis.incrBy(key, num);
- if (seconds > 0) {
- jedis.expire(key, seconds);
- }
- return result;
- });
- }
- public long setIncy(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.incr(key));
- }
- public long setDecy(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.decr(key));
- }
- /**
- * 按分数从小到大删除指定区域的数据 (对应redisTemplate.opsForZSet().removeRange(key,begin,end)))
- *
- * @param key
- * @param start
- * @param end
- * @return
- */
- public long zremrangeByRank(String key, long start, long end) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.zremrangeByRank(key, start, end));
- }
- /**
- * setnx实现简单的分布式锁
- *
- * @param key
- * @param value
- * @return
- */
- public long setnx(String key, String value) {
- return setnx(key, value, 0);
- }
- /**
- * setnx实现简单的分布式锁
- *
- * @param key
- * @param value
- * @param seconds
- * @return
- */
- public long setnx(String key, String value, int seconds) {
- return Redis.withCluster(ecoCluster, jedis -> {
- long result = jedis.setnx(key, value);
- if (result == 1 && seconds > 0) {
- jedis.expire(key, seconds);
- }
- return result;
- });
- }
- /**
- * SET NX EX 原子命令:仅当Key不存在时设置值,并设置过期时间
- * 用于分布式锁的获取
- *
- * @param key 锁的键
- * @param value 锁的值(通常是实例ID或服务ID)
- * @param seconds 过期时间(秒)
- * @return true 表示成功获得锁,false 表示锁已被占用
- */
- public boolean setIfAbsent(String key, String value, int seconds) {
- String result = Redis.withCluster(ecoCluster, jedis -> {
- // 使用 SET key value NX EX seconds 原子命令
- // NX: Only set the key if it does not already exist
- // EX: Set the specified expire time, in seconds
- SetParams params = new SetParams().nx().ex(seconds);
- return jedis.set(key, value, params);
- });
- // 返回 "OK" 表示成功,null 表示键已存在
- return "OK".equals(result);
- }
- /**
- * 根据前缀获取所有的key
- * 例如:pro_*
- */
- public Set<String> getListKey(String prefix) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.keys(prefix.concat("*")));
- }
- public long geoAdd(String key, double lng, double lat, String member) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.geoadd(key, lng, lat, member));
- }
- public double geoDist(String key, String member1, String member2) {
- Double result = Redis.withCluster(ecoCluster, jedis -> jedis.geodist(key, member1, member2, GeoUnit.KM));
- return result != null ? result : 0.0;
- }
- public List<Map<String, Object>> geoPos(String key, String... members) {
- List<GeoCoordinate> coordinates = Redis.withCluster(ecoCluster, jedis -> jedis.geopos(key, members));
- List<Map<String, Object>> coordinateList = new ArrayList<>();
- if (coordinates != null && !coordinates.isEmpty()) {
- for (GeoCoordinate coord : coordinates) {
- Map<String, Object> location = new HashMap<>();
- location.put("lng", coord.getLongitude());
- location.put("lat", coord.getLatitude());
- coordinateList.add(location);
- }
- }
- return coordinateList;
- }
- /**
- * 设置key的过期时间(对应 redisTemplate.expire())
- * @param key 键
- * @param timeout 过期时间
- * @param unit 时间单位
- * @return 是否设置成功
- */
- public long ttl(String key) {
- return Redis.withCluster(ecoCluster, jedis -> jedis.ttl(key));
- }
- public Boolean expire(String key, long timeout, TimeUnit unit) {
- return Redis.withCluster(ecoCluster, jedis -> {
- // 转换为秒
- long seconds = unit.toSeconds(timeout);
- if (seconds > Integer.MAX_VALUE) {
- log.warn("过期时间超过Integer最大值,将使用最大值: {}", Integer.MAX_VALUE);
- seconds = Integer.MAX_VALUE;
- }
- jedis.expire(key, (int) seconds);
- return true;
- });
- }
- public void set(String key, String cont, int timeout, TimeUnit unit) {
- Redis.withCluster(ecoCluster, jedis -> {
- // 转换为秒
- long seconds = unit.toSeconds(timeout);
- if (seconds > Integer.MAX_VALUE) {
- seconds = Integer.MAX_VALUE;
- }
- jedis.set(key, cont);
- if (seconds > 0) {
- jedis.expire(key, seconds);
- }
- return null;
- });
- }
- /**
- * 获取有序集合中指定排名范围内的成员及其分数(按分数从高到低排序)
- * 对应 redisTemplate.opsForZSet().reverseRangeWithScores()
- *
- * @param key 键
- * @param start 起始索引(从0开始,包含)
- * @param end 结束索引(包含,-1表示最后一个)
- * @return 包含成员和分数的元组集合
- */
- public Set<ZSetOperations.TypedTuple<String>> zReverseRangeWithScores(String key, long start, long end) {
- Set<Tuple> tuples = Redis.withCluster(ecoCluster, jedis ->
- jedis.zrevrangeWithScores(key, start, end));
- return tuples.stream()
- .map(tuple -> ZSetOperations.TypedTuple.of(
- tuple.getElement(), // 获取元素
- tuple.getScore() // 获取分数
- ))
- .collect(Collectors.toSet());
- }
- /**
- * 使用 Pipeline 批量设置字符串键值对(高性能,适合大量数据)
- * @param map 包含多个键值对的Map
- */
- public void multiSetWithPipeline(Map<String, String> map,int timeout, TimeUnit unit) {
- if (map == null || map.isEmpty()) {
- return;
- }
- Redis.withCluster(ecoCluster, jedis -> {
- // 创建管道
- Pipeline pipeline = jedis.pipelined();
- // 将所有set命令添加到管道
- for (Map.Entry<String, String> entry : map.entrySet()) {
- pipeline.set(entry.getKey(), entry.getValue());
- pipeline.expire(entry.getKey(), unit.toSeconds(timeout));
- }
- // 批量执行
- pipeline.sync();
- return null;
- });
- }
- public void hmset(String key, Map<String, String> hash, int timeout, TimeUnit unit) {
- Redis.withCluster(ecoCluster, jedis -> {
- jedis.hmset(key, hash);
- if (timeout > 0) {
- jedis.expire(key, unit.toSeconds(timeout));
- }
- return null;
- });
- }
- }
|