Mybatis-plus如何在xml中传入自定义的SQL语句
作者:穹龙
项目场景
项目需求需要在一个框架上二开,原框架有权限校验会返回对应的权限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语句
解决方案
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查询后,继续执行了查询数据语句。
虽然问题解决,但我还是不理解为何将#{}换成${}就能成功。。。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。