mybatis中#{}报错 Parameter index out of range (1 > number of parameters, which is 0)问题

本文探讨了在MyBatis中进行模糊查询时使用$符号而非#符号的原因及风险,并给出了具体的Mapper.xml文件示例。

最近遇到一个错误:

在Mybatis的Mapper文件中的sql涉及 like语句:

Mapper.xml文件写法:

 <sql id="dynamicWhere">
        <where>
            <if test="subscribe not in {null, ''}">subscribe = #{subscribe}</if>
            <if test="openid not in {null, ''}">AND openid = #{openid}</if>
            <if test="unionid not in {null, ''}">AND unionid = #{unionid}</if>
            <if test="nickname not in {null, ''}">AND nickname like '%#{nickname}%'</if>
        </where>
    </sql>
错误:

2017-07-20 18:17:31,058 DEBUG [org.apache.ibatis.logging.slf4j.Slf4jLoggerImpl-49] - ==>  Preparing: SELECT COUNT(1) FROM wechat_user_info WHERE nickname like '%?%' 
org.springframework.dao.TransientDataAccessResourceException: 
### Error querying database.  Cause: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
这里会发现nickname的like语句有问题。

后面发现是因为#的原因,此时需要用到$符号

正确的写法:

    <sql id="dynamicWhere">
        <where>
            <if test="subscribe not in {null, ''}">subscribe = #{subscribe}</if>
            <if test="openid not in {null, ''}">AND openid = #{openid}</if>
            <if test="unionid not in {null, ''}">AND unionid = #{unionid}</if>
            <if test="nickname not in {null, ''}">AND nickname like '%${nickname}%'</if>
        </where>
    </sql>

结论:

在Mybatis中Mapper.xml文件中,如果有sql涉及的模糊查询,中间包含like语句时,只能使用$,不能使用#。

但是使用$时,相当于直接传递字符串,存在sql注入的风险

使用#{}语法将导致MyBatis生成PreparedStatement属性,并根据PreparedStatement参数安全地设置值(例如?)。虽然这更安全,更快速,几乎总是首选,但有时您只想直接将未修改的字符串注入到SQL语句中。例如,对于ORDER BY,您可以使用以下内容:

ORDER BY $ { columnName }

这里MyBatis不会修改或转义字符串。









评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值