LambdaQueryWrapper——apply支持IN操作

背景

在做Rou-Yi项目中,我遇到了一个问题,在只有用LambdaQueryWrapper的项目中,其写了如下代码

// TrainRequestMapper.java
// 权限校验
@DataPermission({
    // 按部门查询需要限制部门
    @DataColumn(key = "deptName", value = "d.dept_id"),
    // 查询用户的自己的数据
    @DataColumn(key = "userName", value = "t.user_id")
})
Page<TrainRequestVo> selectPageTrainRequestList(@Param("page") Page<TrainRequest> page,
                                                @Param(Constants.WRAPPER) Wrapper<TrainRequest> queryWrapper);
// TrainRequestMapper.xml
<select id="selectPageTrainRequestList" resultMap="BaseResultMapVO">
        select t.request_id,
               t.dept_id,
               t.user_id,
               t.title,
               t.description,
               t.status,
               t.reason,
               t.create_by,
               t.create_time,
               t.update_by,
               t.update_time,
               t.remark
        from wfhb_train_request t
        left join sys_dept d on t.dept_id = d.dept_id
        ${ew.getCustomSqlSegment}
</select>

    // 	TrainRequestServiceImpl.java
    private LambdaQueryWrapper<TrainRequest> buildQueryWrapper(TrainRequestBo bo) {
        Long deptId = bo.getDeptId();
        LambdaQueryWrapper<TrainRequest> lqw = Wrappers.lambdaQuery();
        lqw.and(bo.getDeptId() != null, w -> {
            List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                .select(SysDept::getDeptId)
                .apply(DataBaseHelper.findInSet(deptId, "ancestors")));

            List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
            ids.add(deptId);
            w.in(TrainRequest::getDeptId, ids);
        });
        lqw.apply(status != null, "t.status = {0}", status);
        lqw.orderByDesc(TrainRequest::getUpdateTime);
        // lqw.last(status != null, "WHERE t.status = " + status + " ORDER BY t.update_time DESC");
        return lqw;
    }

在上述代码中我们使用了第41行代码进行动态的sql拼接

w.in(TrainRequest::getDeptId, ids);

但这样会出现问题,由于在后续的权限校验时也会拼接上Sys_dept表,Sys_dept表中存在dept_id,同时在LambdaQueryWrapper中in方法中(也就是如上代码)最终拼接的SQL为

WHERE dpet_id IN (106) // 假设最终拼接的数据为106

这会导致字段冲突,无法正确执行SQL

最终的解决方案

使用apply手动拼接SQL

private LambdaQueryWrapper<TrainRequest> buildQueryWrapper(TrainRequestBo bo) {
        Long deptId = bo.getDeptId();
        LambdaQueryWrapper<TrainRequest> lqw = Wrappers.lambdaQuery();
        lqw.and(bo.getDeptId() != null, w -> {
            List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                .select(SysDept::getDeptId)
                .apply(DataBaseHelper.findInSet(deptId, "ancestors")));

            List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
            ids.add(deptId);
            // 将 List 转换为逗号分隔的字符串
            String idStr = ids.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(", "));

            // 手动拼接 SQL
            w.apply("t.dept_id IN (" + idStr + ")");
        });
        // 字段存在歧义,手动指定字段
        lqw.apply(status != null, "t.status = {0}", status);
        lqw.orderByDesc(TrainRequest::getUpdateTime);
        // lqw.last(status != null, "WHERE t.status = " + status + " ORDER BY t.update_time DESC");
        log.debug("Final QueryWrapper: {}", lqw.getSqlSegment());
        return lqw;
    }

总结

apply用法

  1. 直接拼接,使用{0},{1},表示要拼接的参数
// 本文使用的代码
lqw.apply(status != null, "t.status = {0}", status);
// 多参数代码
lqw.apply(status != null, "t.status = {0} AND t.user_id = {1}", status, userId);
  1. 自己手动拼接SQL,可以实现 IN 操作
// 将 List 转换为逗号分隔的字符串
String idStr = ids.stream()
.map(String::valueOf)
.collect(Collectors.joining(", "));

// 手动拼接 SQL
w.apply("t.dept_id IN (" + idStr + ")");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值