Mybatis-plus在xml中传入自定义的SQL语句

本文讲述了在 MyBatis-Plus 框架中遇到的动态 SQL 拼接问题。项目需求要求在获取用户权限后的 SQL 查询中拼接额外的条件,由于涉及到关联查询,不能直接使用 QueryWrapper 的 apply 方法。通过在 XML 查询 SQL 中将 #{}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

项目需求需要在一个框架上二开,原框架有权限校验会返回对应的权限sql语句。

例如在获取用户当前组织及下级组织后拼接生成的SQL:

AND (
    settlement_company_id IN ( 
        '06eb1b4ce4d24e368319188bb4fc6390', 
        '9ff034739e984f188612c671219ddfed', 
        'afe69288c0b84828bd2abcb1c5eec28a' 
    ) 
)

因为有使用到关联查询,无法直接使用QueryWrapper的apply来拼接语句,只能在xml中拼接。 


问题描述:

查询传入实体:

@Data
public class YygkBankAccountQueryForm {
        /**
         * 数据权限Sql
         */
        @ApiModelProperty(value = "数据权限Sql")
        private String extraSql;
}

Mapper类:

public interface YygkBankAccountMapper extends BaseMapper<YygkBankAccountEntity> {
    /**
     * 分页查询银行账户
     *
     * @param iPage                 分页数据
     * @param yygkBankInfoQueryForm 查询参数
     * @return IPage<YygkBankAccountEntity>
     */
    IPage<YygkBankAccountEntity> queryPage(IPage<YygkBankAccountEntity> iPage, @Param("query") YygkBankAccountQueryForm yygkBankInfoQueryForm);
}

XML的查询SQL语句:

<select id="queryPage" resultMap="BaseMap">
    SELECT
    <include refid="YygkBankAccountSql"/>
    FROM yygk_bank_account ba
    LEFT JOIN yygk_currency_info ci ON ba.currency_id = ci.id
    <where>
        ba.delete_mark != 1
        <if test="query.extraSql != null and query.extraSql != ''">
            AND #{query.extraSql}
        </if>
    </where>
    ORDER BY ba.sort DESC
</select>

query.extraSql为我需要拼接的SQL语句。

执行查询的打印日志:

2022-06-17 18:59:55.981 DEBUG 16768 --- [io-30601-exec-1] c.g.y.m.Y.queryPage_mpCount              : ==>  Preparing: SELECT COUNT(1) FROM yygk_bank_account ba WHERE ba.delete_mark != 1 AND ?
2022-06-17 18:59:56.088 DEBUG 16768 --- [io-30601-exec-1] c.g.y.m.Y.queryPage_mpCount              : ==> Parameters:  (settlement_company_id in( '06eb1b4ce4d24e368319188bb4fc6390','9ff034739e984f188612c671219ddfed','afe69288c0b84828bd2abcb1c5eec28a' ) )(String)
2022-06-17 18:59:56.174 DEBUG 16768 --- [io-30601-exec-1] c.g.y.m.Y.queryPage_mpCount              : <==      Total: 1

可以看到在执行了mybatis-plus的count查询后并没有再执行查询数据


原因分析:

怀疑是要用SQL注入才能拼接SQL语句


解决方案:

参考:MyBatis-Plus 使用 Wrapper 自定义SQL_火柴头9527的博客-优快云博客_mybatis-plus wrapper自定义sql

xml的SQL语句改为使用SQL注入:

<select id="queryPage" resultMap="BaseMap">
    SELECT
    <include refid="YygkBankAccountSql"/>
    FROM yygk_bank_account ba
    LEFT JOIN yygk_currency_info ci ON ba.currency_id = ci.id
    <where>
        ba.delete_mark != 1
        <if test="query.extraSql != null and query.extraSql != ''">
            AND ${query.extraSql}
        </if>
    </where>
    ORDER BY ba.sort DESC
</select>

将#{}替换成${}

2022-06-17 19:21:05.437 DEBUG 9008 --- [io-30601-exec-2] c.g.y.m.Y.queryPage_mpCount              : ==>  Preparing: SELECT COUNT(1) FROM yygk_bank_account ba WHERE ba.delete_mark != 1 AND (settlement_company_id IN ('06eb1b4ce4d24e368319188bb4fc6390', '9ff034739e984f188612c671219ddfed', 'afe69288c0b84828bd2abcb1c5eec28a'))
2022-06-17 19:21:05.523 DEBUG 9008 --- [io-30601-exec-2] c.g.y.m.Y.queryPage_mpCount              : ==> Parameters: 
2022-06-17 19:21:05.598 DEBUG 9008 --- [io-30601-exec-2] c.g.y.m.Y.queryPage_mpCount              : <==      Total: 1
2022-06-17 19:21:05.630 DEBUG 9008 --- [io-30601-exec-2] c.g.y.m.YygkBankAccountMapper.queryPage  : ==>  Preparing: SELECT ci.currency_code as currency_code, ba.id, ba.bank_id, ba.bank_name, ba.bank_short_name, ba.bank_english_name, ba.swift_code, ba.account_name, ba.sort, ba.account_number, ba.receipts_payment_type, ba.internal_account, ba.settlement_type, ba.account_type, ba.deposit_type, ba.settlement_company_id, ba.settlement_company_name, ba.default_mark, ba.currency_id, ba.currency_code, ba.account_identification, ba.opening_bank_identification, ba.billing_account, ba.remark, ba.creator_time, ba.creator_user_id, ba.creator_user, ba.last_modify_time, ba.last_modify_user_id, ba.last_modify_user, ba.enable_mark, ba.delete_time, ba.delete_user_id, ba.delete_mark FROM yygk_bank_account ba LEFT JOIN yygk_currency_info ci ON ba.currency_id = ci.id WHERE ba.delete_mark != 1 AND (settlement_company_id in( '06eb1b4ce4d24e368319188bb4fc6390','9ff034739e984f188612c671219ddfed','afe69288c0b84828bd2abcb1c5eec28a' ) ) ORDER BY ba.sort DESC LIMIT ?
2022-06-17 19:21:05.635 DEBUG 9008 --- [io-30601-exec-2] c.g.y.m.YygkBankAccountMapper.queryPage  : ==> Parameters: 20(Long)
2022-06-17 19:21:05.651 DEBUG 9008 --- [io-30601-exec-2] c.g.y.m.YygkBankAccountMapper.queryPage  : <==      Total: 2

可以看到在执行了mybatis-plus的count查询后,继续执行了查询数据语句。

虽然问题解决,但我还是不理解为何将#{}换成${}就能成功,有知道的大佬麻烦评论区告知一下,感谢!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值