如何用JOOQ获取每个用户最新的已完成UserTool ID?
更简洁的实现方式
方案一:数据库层面直接分组取最新记录(推荐)
原实现会查询所有数据再在内存中筛选,数据量大时效率偏低。可以借助窗口函数ROW_NUMBER(),直接在SQL层面过滤出每个用户最新的已完成记录,返回结果直接就是目标UserTool ID,无需后续额外处理:
List<Integer> allUserToolIDs = masterDB .select(Tool.USER_TOOL_ID) .from( select( Tool.USER_ID, Tool.USER_TOOL_ID, rowNumber().over(partitionBy(Tool.USER_ID).orderBy(Tool.FINISHED.desc())).as("rn") ).from(Tool.TABLE) ) .where(field("rn").eq(1)) .fetchInto(Integer.class);
方案二:简化内存处理逻辑
如果不想调整查询逻辑,也可以用Java Stream替代循环,一行代码完成结果提取:
var allUserTools = masterDB.select(Tool.USER_ID, Tool.USER_TOOL_ID) .from(Tool.TABLE) .orderBy(Tool.FINISHED.desc()) .fetchGroups(Tool.USER_ID, UserTool.USER_TOOL_ID); List<Integer> allUserToolIDs = allUserTools.values().stream() .filter(Predicate.not(Collection::isEmpty)) .map(list -> list.get(0)) .collect(Collectors.toList());
补充说明
- 方案一把筛选逻辑交给数据库执行,能大幅减少传输到应用层的数据量,性能更优,适合数据规模较大的场景
- 方案二只是简化了Java代码的写法,核心逻辑和原实现一致,更适合数据量较小的场景
内容的提问来源于stack exchange,提问作者Jackson Collins
相关产品推荐
相关产品推荐

