cvsdhgcd 2023-09-03 16:26 采纳率: 50%
浏览 17

用mybatis-plus 当无条件时,where 依旧拼接在sql上

做的是一个分页展示,带条件查询,

//service层
 @Override
    @Transactional(readOnly = true)
    public PageResult findAllByConditions(UserDetailsQueryDto userDetailsQueryDto) throws Exception {
        QueryWrapper<UserDetailsEntity> queryWrapper = new QueryWrapper();
        queryWrapper.gt(null != userDetailsQueryDto.getStartAge(), "ud.age", userDetailsQueryDto.getStartAge());
        queryWrapper.gt(null != userDetailsQueryDto.getStartTime(), "ulr.login_time",userDetailsQueryDto.getStartTime());
        queryWrapper.lt(null != userDetailsQueryDto.getEndAge(), "ud.age", userDetailsQueryDto.getEndAge());
        queryWrapper.lt(null != userDetailsQueryDto.getEndTime(), "ulr.login_time", userDetailsQueryDto.getEndTime());
        queryWrapper.eq(null != userDetailsQueryDto.getSex(), "ud.sex", userDetailsQueryDto.getSex());
//有问题的地方↓
        queryWrapper.and(wrapper -> wrapper.like(!ObjectUtils.isEmpty(userDetailsQueryDto.getUserName()), "u.user_name", userDetailsQueryDto.getUserName()).or().like(!ObjectUtils.isEmpty(userDetailsQueryDto.getUserName()), "ud.nick_name", userDetailsQueryDto.getUserName()));
//有问题的地方↑
        IPage<UserDetailsBo> userDetailsEntityIPage = super.getBaseMapper().findAllByConditions(new Page<UserDetailsBo>(userDetailsQueryDto.getPageNo(), userDetailsQueryDto.getPageSize()), queryWrapper);

        return PageResult.pageInfo(userDetailsEntityIPage.getCurrent(), userDetailsEntityIPage.getPages(), DozerUtil.mapList(userDetailsEntityIPage.getRecords(), UserDetailsQueryDto.class));

    }
//Mapper层
 IPage<UserDetailsBo> findAllByConditions(Page<UserDetailsBo> userDetailsBoPage, @Param(Constants.WRAPPER) QueryWrapper<UserDetailsEntity> queryWrapper) throws DataAccessException;
//xml
  <sql id="ud_column" >ud.id,ud.user_id,ud.sex,ud.age,ud.nick_name</sql>
    <select id="findAllByConditions" resultType="com.dj.boot.entity.bo.UserDetailsBo">
        select<include refid="ud_column"/>,u.user_name , ulr.login_time from user_details ud left join user u on ud.user_id=u.id left join user_login_record ulr on ulr.user_id=u.id
            ${ew.customSqlSegment}
    </select>

问题出在业务层的这个条件上

 queryWrapper.and(wrapper -> wrapper.like(!ObjectUtils.isEmpty(userDetailsQueryDto.getUserName()), "u.user_name", userDetailsQueryDto.getUserName()).or().like(!ObjectUtils.isEmpty(userDetailsQueryDto.getUserName()), "ud.nick_name", userDetailsQueryDto.getUserName()));

如果有条件

img

最开始我用 null != userDetailsQueryDto.getUserName()&&!"".equals(userDetailsQueryDto.getUserName())判断前端是否传来的字符串,但是挡不住!,
userDetailsQueryDto.getUserName()为空字符串时,还是会拼上sql ,不理解?,

img

然后我换成了(!ObjectUtils.isEmpty(userDetailsQueryDto.getUserName())去判断前端是否传来的字符串,但是

img

应该是把字符串挡住了,但明明没做条件,还是会拼上where,

在IPage那打了个断点,看了下queryWapper里的内容
无条件时,normal的size=0,cacheSqlSegment=true

img

正常的有条件时 normal的size有值,cacheSqlSegment=false

img

但是我现在的问题所遇到的情况

img

img

img

我知道可以把这个条件查询放在xml里去写,这样肯定可以解决问题,
但我想知道怎么在现有基础上改,以及为什么会出现这种问题,
我个人理解时 and( 字段 like ? or 字段 like ?) 这个条件拼接时有问题,但暂时get不到是哪方面
谁能解答下吗

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-09-03 16:34
    关注

    引用 皆我百晓生 小程序回复内容作答:
    根据你提供的代码和问题描述,我看到问题出在以下代码段中:

    queryWrapper.and(wrapper -> wrapper.like(!ObjectUtils.isEmpty(userDetailsQueryDto.getUserName()), "u.user_name", userDetailsQueryDto.getUserName()).or().like(!ObjectUtils.isEmpty(userDetailsQueryDto.getUserName()), "ud.nick_name", userDetailsQueryDto.getUserName()));
    

    首先,你应该明确当userDetailsQueryDto.getUserName()为空字符串时,你是否希望进行条件查询;如果不希望进行条件查询,那么应该将这部分逻辑排除在外,不拼接到queryWrapper中。否则,就会导致即使userDetailsQueryDto.getUserName()为空字符串,仍然会进行条件查询。

    一种解决方法是使用.来代替字符串的判断,如下所示:

    queryWrapper.and(wrapper -> wrapper.like(StringUtils.isNotBlank(userDetailsQueryDto.getUserName()), "u.user_name", userDetailsQueryDto.getUserName()).or().like(StringUtils.isNotBlank(userDetailsQueryDto.getUserName()), "ud.nick_name", userDetailsQueryDto.getUserName()));
    

    这样,只有当userDetailsQueryDto.getUserName()不为空字符串时,才会进行条件查询。

    另外,你提到了你可以将该条件查询放在xml文件中,这也是个很好的解决方法。只需在xml文件的<select>标签中添加一句<if>判断即可:

    <select id="findAllByConditions" resultType="com.dj.boot.entity.bo.UserDetailsBo">
        select<include refid="ud_column"/>,u.user_name , ulr.login_time from user_details ud left join user u on ud.user_id=u.id left join user_login_record ulr on ulr.user_id=u.id
        <if test="userDetailsQueryDto.userName != null and userDetailsQueryDto.userName != ''">
            where u.user_name like concat('%', #{userDetailsQueryDto.userName}, '%') or ud.nick_name like concat('%', #{userDetailsQueryDto.userName}, '%')
        </if>
    </select>
    

    这样就能根据userDetailsQueryDto.getUserName()是否为空字符串来决定是否进行条件查询。

    希望能帮到你!如果有任何疑问,请随时追问。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月3日

悬赏问题

  • ¥50 MATLAB实现圆柱体容器内球形颗粒堆积
  • ¥15 python如何将动态的多个子列表,拼接后进行集合的交集
  • ¥20 vitis-ai量化基于pytorch框架下的yolov5模型
  • ¥15 如何实现H5在QQ平台上的二次分享卡片效果?
  • ¥15 python爬取bilibili校园招聘网站
  • ¥30 求解达问题(有红包)
  • ¥15 请解包一个pak文件
  • ¥15 不同系统编译兼容问题
  • ¥100 三相直流充电模块对数字电源芯片在物理上它必须具备哪些功能和性能?
  • ¥30 数字电源对DSP芯片的具体要求