feat: 排行榜redis set方式
This commit is contained in:
@@ -42,5 +42,25 @@
|
||||
<artifactId>qing-yu-club-infra</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
<version>2.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.12.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@@ -0,0 +1,46 @@
|
||||
package com.landaiqing.subject.domain.redis;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* Redis的config处理
|
||||
*
|
||||
* @author: landaiqing
|
||||
*/
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
redisTemplate.setKeySerializer(redisSerializer);
|
||||
redisTemplate.setHashKeySerializer(redisSerializer);
|
||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
|
||||
Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
jsonRedisSerializer.setObjectMapper(objectMapper);
|
||||
return jsonRedisSerializer;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
package com.landaiqing.subject.domain.redis;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ZSetOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* RedisUtil工具类
|
||||
*
|
||||
* @author: landaiqing
|
||||
* @date: 2024/2/19
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RedisUtil {
|
||||
|
||||
@Resource
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
private static final String CACHE_KEY_SEPARATOR = ".";
|
||||
|
||||
/**
|
||||
* 构建缓存key
|
||||
*/
|
||||
public String buildKey(String... strObjs) {
|
||||
return Stream.of(strObjs).collect(Collectors.joining(CACHE_KEY_SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在key
|
||||
*/
|
||||
public boolean exist(String key) {
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除key
|
||||
*/
|
||||
public boolean del(String key) {
|
||||
return redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* set(不带过期)
|
||||
*/
|
||||
public void set(String key, String value) {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* set(带过期)
|
||||
*/
|
||||
public boolean setNx(String key, String value, Long time, TimeUnit timeUnit) {
|
||||
return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取string类型缓存
|
||||
*/
|
||||
public String get(String key) {
|
||||
return (String) redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
public Boolean zAdd(String key, String value, Long score) {
|
||||
return redisTemplate.opsForZSet().add(key, value, Double.valueOf(String.valueOf(score)));
|
||||
}
|
||||
|
||||
public Long countZset(String key) {
|
||||
return redisTemplate.opsForZSet().size(key);
|
||||
}
|
||||
|
||||
public Set<String> rangeZset(String key, long start, long end) {
|
||||
return redisTemplate.opsForZSet().range(key, start, end);
|
||||
}
|
||||
|
||||
public Long removeZset(String key, Object value) {
|
||||
return redisTemplate.opsForZSet().remove(key, value);
|
||||
}
|
||||
|
||||
public void removeZsetList(String key, Set<String> value) {
|
||||
value.stream().forEach((val) -> redisTemplate.opsForZSet().remove(key, val));
|
||||
}
|
||||
|
||||
public Double score(String key, Object value) {
|
||||
return redisTemplate.opsForZSet().score(key, value);
|
||||
}
|
||||
|
||||
public Set<String> rangeByScore(String key, long start, long end) {
|
||||
return redisTemplate.opsForZSet().rangeByScore(key, Double.valueOf(String.valueOf(start)), Double.valueOf(String.valueOf(end)));
|
||||
}
|
||||
|
||||
public Object addScore(String key, Object obj, double score) {
|
||||
return redisTemplate.opsForZSet().incrementScore(key, obj, score);
|
||||
}
|
||||
|
||||
public Object rank(String key, Object obj) {
|
||||
return redisTemplate.opsForZSet().rank(key, obj);
|
||||
}
|
||||
|
||||
|
||||
public Set rankWithScore(String key,long start,long end){
|
||||
Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -4,11 +4,13 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.landaiqing.subject.common.entity.PageResult;
|
||||
import com.landaiqing.subject.common.enums.IsDeletedFlagEnum;
|
||||
import com.landaiqing.subject.common.util.IdWorkerUtil;
|
||||
import com.landaiqing.subject.common.util.LoginUtil;
|
||||
import com.landaiqing.subject.domain.convert.SubjectInfoConverter;
|
||||
import com.landaiqing.subject.domain.entity.SubjectInfoBO;
|
||||
import com.landaiqing.subject.domain.entity.SubjectOptionBO;
|
||||
import com.landaiqing.subject.domain.handler.subject.SubjectTypeHandler;
|
||||
import com.landaiqing.subject.domain.handler.subject.SubjectTypeHandlerFactory;
|
||||
import com.landaiqing.subject.domain.redis.RedisUtil;
|
||||
import com.landaiqing.subject.domain.service.SubjectInfoDomainService;
|
||||
import com.landaiqing.subject.infra.basic.entity.SubjectInfo;
|
||||
import com.landaiqing.subject.infra.basic.entity.SubjectInfoEs;
|
||||
@@ -21,15 +23,13 @@ import com.landaiqing.subject.infra.basic.service.SubjectMappingService;
|
||||
import com.landaiqing.subject.infra.entity.UserInfo;
|
||||
import com.landaiqing.subject.infra.rpc.UserRpc;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.ZSetOperations;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@@ -51,6 +51,11 @@ public class SubjectInfoDomainServiceImpl implements SubjectInfoDomainService {
|
||||
@Resource
|
||||
private UserRpc userRpc;
|
||||
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
private static final String RANK_KEY = "subject_rank";
|
||||
|
||||
|
||||
/**
|
||||
* @description: 新增标签
|
||||
@@ -96,6 +101,8 @@ public class SubjectInfoDomainServiceImpl implements SubjectInfoDomainService {
|
||||
subjectInfoEs.setSubjectType(subjectInfo.getSubjectType());
|
||||
subjectEsService.insert(subjectInfoEs);
|
||||
subjectEsService.insert(subjectInfoEs);
|
||||
// redis放入zadd 记录排行榜
|
||||
redisUtil.addScore(RANK_KEY, LoginUtil.getLoginId(), 1);
|
||||
|
||||
}
|
||||
|
||||
@@ -156,15 +163,18 @@ public class SubjectInfoDomainServiceImpl implements SubjectInfoDomainService {
|
||||
|
||||
@Override
|
||||
public List<SubjectInfoBO> getContributeList() {
|
||||
List<SubjectInfo> subjectInfoList= subjectInfoService.getContributeCount();
|
||||
if(CollectionUtils.isEmpty(subjectInfoList)){
|
||||
Set<ZSetOperations.TypedTuple<String>> typedTuples = redisUtil.rankWithScore(RANK_KEY, 0, 5);
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("getContributeList.typedTuples:{}", JSON.toJSONString(typedTuples));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(typedTuples)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<SubjectInfoBO> boList=new LinkedList<>();
|
||||
subjectInfoList.forEach(subjectInfo -> {
|
||||
List<SubjectInfoBO> boList = new LinkedList<>();
|
||||
typedTuples.forEach(rank -> {
|
||||
SubjectInfoBO subjectInfoBO = new SubjectInfoBO();
|
||||
subjectInfoBO.setSubjectCount(subjectInfo.getSubjectCount());
|
||||
UserInfo userInfo = userRpc.getUserInfo(subjectInfo.getCreatedBy());
|
||||
subjectInfoBO.setSubjectCount(rank.getScore().intValue());
|
||||
UserInfo userInfo = userRpc.getUserInfo(rank.getValue());
|
||||
subjectInfoBO.setCreatUser(userInfo.getNickName());
|
||||
subjectInfoBO.setCreateUserAvatar(userInfo.getAvatar());
|
||||
boList.add(subjectInfoBO);
|
||||
|
@@ -27,6 +27,28 @@ spring:
|
||||
enabled: true
|
||||
config:
|
||||
enabled: true
|
||||
# redis配置
|
||||
redis:
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 0
|
||||
# Redis服务器地址
|
||||
host: 116.196.80.239
|
||||
# Redis服务器连接端口
|
||||
port: 6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password: LDQ20020618xxx
|
||||
# 连接超时时间
|
||||
timeout: 2s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
max-active: 200
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 10
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ9zUefu5PFeiy4nNNRCIaNT5IY3IxRrlHMiotffSPstMensKg4PoSWJsRRrp/zQEzWegxz2Bkv3F5vfGqqM9N0CAwEAAQ==
|
||||
logging:
|
||||
config: classpath:log4j2-spring.xml
|
||||
|
Reference in New Issue
Block a user