数据库方式实现实时排行榜
文章目录
- 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)
- 🌟 亮点功能
- 📦 spring cloud模块概览
- 常用工具
- 🔗 更多信息
- 1.排行榜的设计
- 1.实时榜单
- 1.数据库统计
- 2.redis 的 sorted set
- 2.非实时榜单
- 2.数据库方式实现
- 1.sun-club-subject模块
- 1.sun-club-application-controller
- 1.SubjectController.java
- 2.SubjectInfoDTO.java 新增三个属性
- 2.sun-club-domain
- 1.SubjectInfoDomainService.java
- 2.SubjectInfoDomainServiceImpl.java
- 3.SubjectInfoBO.java 新增三个属性
- 3.sun-club-infra
- 1.SubjectInfoService.java
- 2.SubjectInfoServiceImpl.java
- 3.SubjectInfoDao.java
- 4.SubjectInfoDao.xml 注意count(1)要加别名才能与entity对应
- 5.UserInfo.java 新增头像属性
- 6.UserRpc.java 设置头像属性
- 2.测试
🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)
轻松高效的现代化开发体验
Sun Frame 是我个人开源的一款基于 SpringBoot 的轻量级框架,专为中小型企业设计。它提供了一种快速、简单且易于扩展的开发方式。
我们的开发文档记录了整个项目从0到1的任何细节,实属不易,请给我们一个Star!🌟
您的支持是我们持续改进的动力。
您的支持是我们持续改进的动力。
🌟 亮点功能
- 组件化开发:灵活选择,简化流程。
- 高性能:通过异步日志和 Redis 缓存提升性能。
- 易扩展:支持多种数据库和消息队列。
📦 spring cloud模块概览
- Nacos 服务:高效的服务注册与发现。
- Feign 远程调用:简化服务间通信。
- 强大网关:路由与限流。
常用工具
- 日志管理:异步处理与链路追踪。
- Redis 集成:支持分布式锁与缓存。
- Swagger 文档:便捷的 API 入口。
- 测试支持:SpringBoot-Test 集成。
- EasyCode:自定义EasyCode模板引擎,一键生成CRUD。
🔗 更多信息
- 开源地址:Gitee Sun Frame
- 详细文档:语雀文档
1.排行榜的设计
1.实时榜单
1.数据库统计
现在数据库里面的 createby 字段。用户的标识是唯一的,那我们直接通过 group by 的形式统计 count。
select count(1),create_by from subject_info group by create_by limit 0,5;
数据量比较小,并发也比较小。这种方案是 ok 的。保证可以走到索引,返回速度快,不要产生慢 sql。
在数据库层面加一层缓存,接受一定的延时性。
2.redis 的 sorted set
有序集合,不允许重复的成员,然后每一个 key 都会包含一个 score 分数的概念。redis 根据分数可以帮助我们做从小到大,和从大到小的一个处理。
有序集合的 key 不可重复,score 重复。
它通过我们的一个哈希表来实现的,添加,删除,查找,复杂度 o(1) ,最大数量是 2 32 次方-1.
zadd
zrange
zincrby
zscore
这种的好处在于,完全不用和数据库做任何的交互,纯纯的通过缓存来做,速度非常快,要避免一些大 key 的问题。
2.非实时榜单
定时任务 xxl-job
统计数据库的数据形式,帮助我们统计完成后,直接写入缓存。缓存的外部的交互展示。
2.数据库方式实现
1.sun-club-subject模块
1.sun-club-application-controller
1.SubjectController.java
/*** 获取题目的贡献榜* @return*/
@PostMapping("/getContributeList")
public Result<List<SubjectInfoDTO>> getContributeList() {try {// 打印日志if (log.isInfoEnabled()) {log.info("SubjectController getContributeList");}// 获取贡献榜List<SubjectInfoBO> boList = subjectInfoDomainService.getContributeList();// 转换BO为DTOList<SubjectInfoDTO> dtoList = SubjectInfoDTOConverter.INSTANCE.convertBO2DTO(boList);return Result.ok(dtoList);} catch (Exception e) {log.error("SubjectController getContributeList error", e);return Result.fail("获取贡献榜失败");}
}
2.SubjectInfoDTO.java 新增三个属性
/*** 创建人昵称*/
private String createUser;/*** 创建人头像*/
private String createUserAvatar;/*** 题目数量*/
private Integer subjectCount;
2.sun-club-domain
1.SubjectInfoDomainService.java
/*** 获取贡献榜* @return*/
List<SubjectInfoBO> getContributeList();
2.SubjectInfoDomainServiceImpl.java
@Override
public List<SubjectInfoBO> getContributeList() {// 从数据库中查询题目信息的listList<SubjectInfo> subjectInfoList = subjectInfoService.getContributeList();// 如果查不到就直接返回空if (CollectionUtils.isEmpty(subjectInfoList)) {return Collections.emptyList();}// 如果查到了,就封装到BO中List<SubjectInfoBO> boList = new LinkedList<>();subjectInfoList.forEach(subjectInfo -> {SubjectInfoBO subjectInfoBO = new SubjectInfoBO();subjectInfoBO.setSubjectCount(subjectInfo.getSubjectCount());// rpc调用根据createBy来查询该用户的昵称和头像String createdBy = subjectInfo.getCreatedBy();UserInfo userInfo = userRpc.getUserInfo(createdBy);subjectInfoBO.setCreateUser(userInfo.getNickName());subjectInfoBO.setCreateUserAvatar(userInfo.getAvater());boList.add(subjectInfoBO);});return boList;
}
3.SubjectInfoBO.java 新增三个属性
/*** 创建人昵称*/
private String createUser;/*** 创建人头像*/
private String createUserAvatar;/*** 题目数量*/
private Integer subjectCount;
3.sun-club-infra
1.SubjectInfoService.java
/*** 获取贡献榜* @return*/
List<SubjectInfo> getContributeList();
2.SubjectInfoServiceImpl.java
/*** 获取贡献榜* @return*/@Overridepublic List<SubjectInfo> getContributeList() {return this.subjectInfoDao.getContributeList();}
3.SubjectInfoDao.java
/*** 获取贡献榜* @return*/
List<SubjectInfo> getContributeList();
4.SubjectInfoDao.xml 注意count(1)要加别名才能与entity对应
<!-- 根据createdBy分组查询每组的题目数量 -->
<select id="getContributeList" resultMap="SubjectInfoMap">select count(1) as subjectCount,created_byfrom subject_infowhere is_deleted = 0and created_by is not nullgroup by created_bylimit 0, 5
</select>
5.UserInfo.java 新增头像属性
package com.sunxiansheng.subject.infra.eneity;import lombok.Data;/*** Description:* @Author sun* @Create 2024/6/16 13:47* @Version 1.0*/
@Data
public class UserInfo {private String userName;private String nickName;private String avater;
}