场景
定义了一个字段,存储了一个 json 数组比如:[41,38,42]
,它的含义是一个线性的流程定义,所以保证顺序至关重要
现在使用 MyBatis Plus 的 API 方法去通过 ID 数组查询得到对象数组
List<ProcessNodePO> processNodeList = processNodeMapper.selectList(new LambdaQueryWrapper<ProcessNodePO>()
.in(ProcessNodePO::getProcessId, processIdList));
问题
原 ID 数组中的顺序为:41,38,42
查询得到的对象 ID 顺序为:38,41,42
顺序被改写,对象数组顺序与参数数组顺序不一致
这个问题的本质是 SQL 语句中的IN()
造成的
目标
使得查询得到的对象数组顺序与原参数数组保持一致
解决方案
方案 1:MyBatis plus last()
last()
用于在查询末尾添加自定义 SQL,但是代码和 SQL 语句混在一起观感不好、也不利于维护,而且通过字符串来拼接 SQL 也会存在 SQL 注入的风险
List<Integer> processIdList = Arrays.asList(41, 38, 42);
LambdaQueryWrapper<ProcessNodePO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ProcessNodePO::getProcessId, processIdList);
// 使用 FIELD 函数在 SQL 中指定排序顺序
String fieldOrder = processIdList.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
queryWrapper.last("ORDER BY FIELD(process_id, " + fieldOrder + ")");
List<ProcessNodePO> processNodeList = processNodeMapper.selectList(queryWrapper);
方案二:用 Java 代码对查询出的集合重新排序
这个方式也不好
List<ProcessNodePO> processNodeList = processNodeMapper.selectList(queryWrapper);
// 使用给定的顺序排序结果
Map<Integer, Integer> orderMap = new HashMap<>();
for (int i = 0; i < processIdList.size(); i++) {
orderMap.put(processIdList.get(i), i);
}
// 按照 orderMap 排序
processNodeList.sort(Comparator.comparingInt(po -> orderMap.getOrDefault(po.getProcessId(), Integer.MAX_VALUE)));
方案三:用 MyBatis 动态 SQL
当然,这本质上和方案一没有区别,都是使用FIELD()
,但是形式上好得多
<select id="queryListByDesignatedOrder" parameterType="java.lang.Integer"
resultType="com.xingyun.warning.center.infrastructure.db.dataObject.helper.ProcessNodePO">
SELECT process_id,process_desc,is_input_required as inputRequired,param_name,prompt,is_request_required as
sendRequestRequired,component
FROM t_operation_helper_process_node
WHERE process_id IN
<foreach item="id" collection="nodeIdList" open="(" separator="," close=")">
#{id}
</foreach>
ORDER BY FIELD(
process_id,
<foreach item="id" collection="nodeIdList" separator=",">
#{id}
</foreach>
)
</select>
标签:顺序,process,id,列表,Plus,数组,SQL,MyBatis,processIdList
From: https://www.cnblogs.com/yaocy/p/18157045