1.场景描述:
<if test="startDate != null and startDate !=''">
<![CDATA[
AND t.effective_date>= #{startDate,jdbcType=VARCHAR}
]]>
</if>
<if test="endDate != null and endDate !=''">
<![CDATA[
AND t.effective_date <= #{endDate,jdbcType=VARCHAR}
]]>
</if>
根据时间区间查询数据时,当开始时间和结束时间相同时,查询不到数据;当开始时间和结束不同时,却可以查到结果;
此时用的是占位符#,而当使用连接符$时,问题不复现;
2.问题原因:
1.数据库中对应的时间字段属性为char(10),而存储格式为YYYYmmdd,对于oracle数据库的char类型,当长度不足时,会在后位用空格补齐;
2.使用连接符$时,相当于CHAR型与字符常量的比较,字符常量作为char型处理,也就是在比较时会自动将常量右补齐空格后比较;所以可以正常查到结果;
3.使用占位符#时,相当于当CHAR类型和VARCHAR2类型比较,比较时对字段值是不作处理,直接比较的,所以查不到结果;而当开始时间和结束时间不同时,主要比较的是非空格部分,所以可以查到结果;
第一种解决方案: 加trim; 如下:
where MUID = #{muid,jdbcType=CHAR}
and trim(LOCALNAME) = #{localname,jdbcType=CHAR}
第二种解决方案: 将#替换为$ ;如下:
where MUID = #{muid,jdbcType=CHAR}
and LOCALNAME = ${localname}
由于使用$符,存在sql注入的隐患,所以不推荐使用;
第三种解决方案: 将数据库中字段的属性改为与内容长度一致,或是直接只用varchar属性;
比如: date char(8) --> YYYYmmdd
3.参考文档:
1.oracle中char与varchar2的区别 http://blog.csdn.net/haiross/article/details/44150809#t0
2.mybatis使用oracle char 字段查询返回结果总是null http://blog.csdn.net/xiaxiaorui2003/article/details/52302080