MyBatis中使用 like 及注意事项
Contents
常见错误用法
select * from tbl where title like '%#{title}%'
这种写法, 会报以下类似错:
Error setting non null for parameter #5 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.sql.SQLException: Parameter index out of range (5 > number of parameters, which is 4).
正确用法
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
Why ?
知其然, 更要知其所以然. 这让我们来从源码调试发现原因
这样子的写法
@Mapper
public interface DemoMapper {
String getById(@Param("title") String title);
}
<select id="getById" resultType="string">
SELECT title from test_like WHERE title '%#{title}%';
</select>
运行时, 发现它报了以下错误
Caused by: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:55) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:87) ~[mybatis-3.4.5.jar:3.4.5]
... 45 common frames omitted
Caused by: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:55) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.type.UnknownTypeHandler.setNonNullParameter(UnknownTypeHandler.java:45) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:53) ~[mybatis-3.4.5.jar:3.4.5]
... 46 common frames omitted
Caused by: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
可以看到, 预先的处理后, mybatis 将 '%#{title}%'
替换为了 '%?%'
, 并且将我们的命名的参数保存在了一个 ParamMap
对象中.
到这里时, 可以看到 mybatis 准备将我们的 sql
字段, 用 parameterObject
对象来进行参数替换.
到这里时, 就准备正式将相应的参数的值设置到SQL语句中.
最终问题
原来这并不关 MyBatis 的事, 这里到 jdbc 才开始报错的. 因为占位符 '%?%'
与 %?%
是不同的, 前面的是有引号括住 ?
, 后面一个是没引号括住的.
可以看到, 正确的占位符时, 它的SQL是这样子的
这………_