使用MyBatis动态生成sql

本文介绍了如何使用MyBatis结合动态参数,通过模板SQL生成实际的查询语句。在示例中,展示了如何处理包含占位符的模板,如`type = '${type}'`和`period = '${period}'`,并最终生成如`select period, sum(amount) as sum from abc where type = 'fruit' and period = '2021-01'`的SQL。注意,MyBatis中模板SQL的占位符应使用`${id}`而非`#{id}`,以避免被解析为PreparedStatement,同时这种方式不适用于防止SQL注入。" 86016051,2803957,Intel NCS2在Ubuntu 16.04的部署问题及解决,"['NCS', '深度学习', 'Ubuntu', '移动部署']

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

问题举例:

有一个带占位符的模板sql,语法跟mybatis的XML是类似的,如

select period, sum(amount) as sum from abc where type = '${type}' 
<if test='period != null'> 
    and period = '${period}' 
</if>
<if test='debtType != null'> 
    and debt_type = '${debtType}' 
</if>

和 动态的参数,如:

{"type": "fruit", "period": "2021-01"}

参数是动态的,因为有可能是实时从页面上传过来的。

希望生成的sql是:

select period, sum(amount) as sum from abc where type = 'fruit'  and period = '2021-01';

那么,如果想通过这样的模板sql,加上动态参数,来动态生成sql,应该怎么做呢?

(这里感谢聪明帅气的师兄:哲哥(elon_wen) 的帮助,查遍stackoverflow都没有方案,但是他却找到了方案!)

MyBatis提供了这样的方案:

public static void main(String[] args) throws Exception {

    String script = "<script>select * from table where 1 = 1<if test='id != null'>and id = ${id} </if></script>";

    System.out.println(buildSql(script));
//  打印出来的结果是:select * from table where 1 = 1 and id = 1
}

private static String buildSql(String script) {

    LanguageDriver languageDriver = new XMLLanguageDriver();

    Configuration configuration = new Configuration();

    SqlSource sqlSource = languageDriver.createSqlSource(configuration, script, Object.class);

    Map<String, String> parameters = new HashMap<>();
    parameters.put("id", "1");

    BoundSql boundSql = sqlSource.getBoundSql(parameters);

    return boundSql.getSql();

}

需要注意的是,这里的模板sql里的占位符,需要使用 ${id} ,而不是 #{id},不然打印出来的是问号(因为变成了PreparedStatement,具体见https://stackoverflow.com/questions/33197085/mybatis-3-get-sql-string-from-mapper/33197157#33197157)。同时,这种方式也不能防止sql注入。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值