Mybatis-Plus的QueryWrapper获取自定义SQL 简化自定义XML复杂情况${ew.customSqlSegment} 

 /**
     * 获取自定义SQL 简化自定义XML复杂情况
     * <p>使用方法</p>
     * <p>`自定义sql` + ${ew.customSqlSegment}</p>
     * <p>1.逻辑删除需要自己拼接条件 (之前自定义也同样)</p>
     * <p>2.不支持wrapper中附带实体的情况 (wrapper自带实体会更麻烦)</p>
     * <p>3.用法 ${ew.customSqlSegment} (不需要where标签包裹,切记!)</p>
     * <p>4.ew是wrapper定义别名,可自行替换</p>
     */
    public String getCustomSqlSegment() {
        MergeSegments expression = getExpression();
        if (Objects.nonNull(expression)) {
            NormalSegmentList normal = expression.getNormal();
            String sqlSegment = getSqlSegment();
            if (StringUtils.isNotBlank(sqlSegment)) {
                if (normal.isEmpty()) {
                    return sqlSegment;
                } else {
                    return Constants.WHERE + StringPool.SPACE + sqlSegment;
                }
            }
        }
        return StringPool.EMPTY;
    }

重点看官方注释:

获取自定义SQL 简化自定义XML复杂情况

     使用方法

     `自定义sql` + ${ew.customSqlSegment}

     1.逻辑删除需要自己拼接条件 (之前自定义也同样)

     2.不支持wrapper中附带实体的情况 (wrapper自带实体会更麻烦)

     3.用法 ${ew.customSqlSegment} (不需要where标签包裹,切记!)

     4.ew是wrapper定义别名,可自行替换


示例1:

mapper.xml

 <select id="tableList" resultType="java.util.LinkedHashMap">
        SELECT
            ${ew.sqlSelect} // 这里拼接select后面的语句
        FROM
            ${table_name} //如果是单表的话,这里可以写死
        ${ew.customSqlSegment}
    </select>

mapper

IPage<LinkedHashMap<String,Object>> tableList(@Param("table_name") String table_name,
										Page page,
                                           @Param(Constants.WRAPPER) QueryWrapper queryWrapper);

test

String responseField = "*"; 
queryWrapper.select(responseField);
// 即 select * ...

String responseField = "name";
queryWrapper.select(responseField);
// 即 select name ...

示例2:

controller

 public String saveAddress(HttpSession session) {
        UserVO user1 = (UserVO)session.getAttribute("user");

        LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery()
                .select(User::getNickName, User::getUserId) // 需要查询的列,即 ${ew.sqlSelect}
                .eq(User::getUserId, user1.getUserId());// 条件
        User user = this.userMapper.selectNickNameAndUserId(lambdaQueryWrapper);
        System.out.println(user);
        return null;
    }

mapper

    User selectNickNameAndUserId(@Param(Constants.WRAPPER) LambdaQueryWrapper<User> queryWrapper);

mapper.xml

<select id="selectNickNameAndUserId" resultType="com.example.demo.entity.User">
        select
            <if test="ew != null and ew.SqlSelect != null and ew.SqlSelect != ''">
                ${ew.SqlSelect}
            </if>
        from
            user
        where is_deleted != 1
        <if test="ew != null">
            <if test="ew.nonEmptyOfWhere">
                AND
            </if>
            ${ew.sqlSegment}
        </if>
    </select>
 <select id="selectNickNameAndUserId" resultType="com.example.demo.entity.User">
        select
            <if test="ew != null and ew.SqlSelect != null and ew.SqlSelect != ''">
                ${ew.SqlSelect}
            </if>
        from
            user
        ${ew.customSqlSegment}
    </select>

使用${ew.sqlSegment} 如果是联表查询且查询条件是连表的字段则需在service层拼接查询条件时字段前指定别名,而且不能用lambda的查询了

 <select id="selectByRoleId" resultType="com.captain.crewer.mybatis.plus.dto.RolePermsDTO">
        SELECT tp.id,
               tp.perm_name,
               tp.url,
               tr.role_id   as roleId,
               tr.role_name as roleName
        FROM tb_role tr
                     LEFT JOIN tb_perm_role tpr ON tr.role_id = tpr.role_id
                     LEFT JOIN tb_perm tp ON tpr.perm_id = tp.id ${ew.customSqlSegment}
    </select>

mapper

 List<RolePermsDTO> selectByRoleId(@Param(Constants.WRAPPER) Wrapper<RolePermsDTO> wrapper);

test

 @Test
    public void test2(){
        QueryWrapper<RolePermsDTO> wrapper = new QueryWrapper<>();
        wrapper.eq("tr.role_id", 1);
        
        tbPermService.selectByRoleId(wrapper);
    }
大家都在看: