说明
最近在使用<if>标签合并接口和SQL的过程遇到了一些坑,放在这记录一下
首先我们有下面这样一个mapper接口(根据status变量来选择不同的SQL):
List<xxxxxxDTO> findAll(String status);
问题一:There is no getter for property named 'xxxx' in 'class java.lang.String'
原因:Mybatis默认采用ONGL解析参数,所以会自动采用对象树的形式取 string.xxx 值,如果没在在方法中定义,则会抛异常报错。
解决方案1:
在Mapper接口使用@Param注解标记参数名
List<xxxxxxDTO> findAll(@Param(value = "status") String status);
然后在mapper.xml里就可以这样写
<select id="findAll" resultMap="baseResultMap" parameterType="String">
<if test='status=="0"'><!-- 注意是单引号里套双引号,待会说为什么 -->
SELECT xxxxxxx FROM xxxxxxxx_table WHERE status='0'
</if>
</select>
解决方案2:
把mapper.xml使用的 变量名(如本例的status)修改为 _parameter 即可
<select id="findAll" resultMap="baseResultMap" parameterType="String">
<if test='_parameter=="0"'><!-- 注意是单引号里套双引号,待会说为什么 -->
SELECT xxxxxxx FROM xxxxxxxx_table WHERE status='0'
</if>
</select>
问题2:nested exception is java.sql.SQLException: sql injection violation, syntax error: ERROR. pos 23, line 1, column 23, token RPAREN : select count(0) from () tmp_count或者是出现:NumberFormatException: For input string:"xx"
原因:如果你在xml写成了下面的形式:
<select id="findAll" resultMap="baseResultMap" parameterType="String">
<if test="_parameter=='0'"><!-- 或者是用了@Param写成 "status=='0'" -->
SELECT xxxxxxx FROM xxxxxxxx_table WHERE status='0'
</if>
</select>
原因给的是字符串,却拿一个数字比较,mybatis会做一些转化,结果在数字格式化时发生异常。
解决方案1:
将数值转为字符串
<select id="findAll" resultMap="baseResultMap" parameterType="String">
<if test="status=='0'.toString()">
SELECT xxxxxxx FROM xxxxxxxx_table WHERE status='0'
</if>
</select>
解决方案2:
加转义实体字符串引号"
<select id="findAll" resultMap="baseResultMap" parameterType="String">
<if test="status=="0"">
SELECT xxxxxxx FROM xxxxxxxx_table WHERE status='0'
</if>
</select>
解决方案3:(推荐)
外部单双引号交换
<select id="findAll" resultMap="baseResultMap" parameterType="String">
<if test='status=="0"'>
SELECT xxxxxxx FROM xxxxxxxx_table WHERE status='0'
</if>
</select>