mybatis的char與varchar的區(qū)別

1.場(chǎng)景描述:

 <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>

根據(jù)時(shí)間區(qū)間查詢(xún)數(shù)據(jù)時(shí),當(dāng)開(kāi)始時(shí)間和結(jié)束時(shí)間相同時(shí),查詢(xún)不到數(shù)據(jù);當(dāng)開(kāi)始時(shí)間和結(jié)束不同時(shí),卻可以查到結(jié)果;
此時(shí)用的是占位符#,而當(dāng)使用連接符$時(shí),問(wèn)題不復(fù)現(xiàn);

2.問(wèn)題原因:

1.數(shù)據(jù)庫(kù)中對(duì)應(yīng)的時(shí)間字段屬性為char(10),而存儲(chǔ)格式為YYYYmmdd,對(duì)于oracle數(shù)據(jù)庫(kù)的char類(lèi)型,當(dāng)長(zhǎng)度不足時(shí),會(huì)在后位用空格補(bǔ)齊;
2.使用連接符$時(shí),相當(dāng)于CHAR型與字符常量的比較,字符常量作為char型處理,也就是在比較時(shí)會(huì)自動(dòng)將常量右補(bǔ)齊空格后比較;所以可以正常查到結(jié)果;
3.使用占位符#時(shí),相當(dāng)于當(dāng)CHAR類(lèi)型和VARCHAR2類(lèi)型比較,比較時(shí)對(duì)字段值是不作處理,直接比較的,所以查不到結(jié)果;而當(dāng)開(kāi)始時(shí)間和結(jié)束時(shí)間不同時(shí),主要比較的是非空格部分,所以可以查到結(jié)果;

第一種解決方案: 加trim; 如下:
where MUID = #{muid,jdbcType=CHAR}
  and trim(LOCALNAME) = #{localname,jdbcType=CHAR}
第二種解決方案: 將#替換為$ ;如下:
where MUID = #{muid,jdbcType=CHAR}
  and LOCALNAME = ${localname}
由于使用$符,存在sql注入的隱患,所以不推薦使用;
第三種解決方案: 將數(shù)據(jù)庫(kù)中字段的屬性改為與內(nèi)容長(zhǎng)度一致,或是直接只用varchar屬性;
比如: date char(8)  --> YYYYmmdd

3.參考文檔:

1.oracle中char與varchar2的區(qū)別 http://blog.csdn.net/haiross/article/details/44150809#t0
2.mybatis使用oracle char 字段查詢(xún)返回結(jié)果總是null http://blog.csdn.net/xiaxiaorui2003/article/details/52302080

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容