美文网首页
mybatis的char与varchar的区别

mybatis的char与varchar的区别

作者: GuangHui | 来源:发表于2017-08-10 16:17 被阅读299次

    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

    相关文章

      网友评论

          本文标题:mybatis的char与varchar的区别

          本文链接:https://www.haomeiwen.com/subject/lcihrxtx.html