關于Mybatis插入對象時空值的處理
Mybatis插入對象時空值
Mybatis中經常會有插入數(shù)據(jù)的情景,有時傳輸?shù)膶ο笞侄尾⒉皇峭暾?,如果不做任何處理則會拋出異常,影響程序執(zhí)行。
如存在對象賦值不完整的情況可以在字段后添加 jdbcType 如:
INSERT INTO student(`uid`,`name`,`class`) VALUES(#{uid,jdbcType=VARCHAR},#{name,jdbcType=VARCHAR},#{class,jdbcType=VARCHAR})
然后再 mybatis-config.xml 中添加配置
<settings> ?? ?<setting name="jdbcTypeForNull" value="NULL" /> ? </settings>
如若是其它類型也可使用 <if> 標簽
<if test="otherType != null and otherType!= ''" > ? ? otherType = #{otherType} </if>
這樣在數(shù)據(jù)庫未做限制時,就不會影響到數(shù)據(jù)的添加或修改。
需要注意的點MyBatis插入空值時,需要指定JdbcType
前天遇到一個問題 異常顯示如下:
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: Error setting null for parameter #6 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 無效的列類型: 1111
; uncategorized SQLException for SQL []; SQL state [99999]; error code [17004]; 無效的列類型: 1111; nested exception is java.sql.SQLException: 無效的列類型: 1111
對應的sqlmap如下:
<insert id="insertCustomerLog" parameterType="map"> ? ? ? ? insert into customer_log ? ? ? ? ( ? ? ? ? ID, ? ? ? ? CUSTOMER_SERVICE_USER_NAME, ? ? ? ? user_name, ? ? ? ? CONTENT, ? ? ? ? LOG_FIRST_TYPE, ? ? ? ? STATUS, ? ? ? ? LINKED_ID, ? ? ? ? FEE, ? ? ? ? ACCOUNT_FIRST_TYPE, ? ? ? ? ACCOUNT_SECOND_TYPE, ? ? ? ? ACCOUNT_THIRD_TYPE, ? ? ? ? LOG_SECOND_TYPE, ? ? ? ? LOG_IP, ? ? ? ? MEMO ? ? ? ? ) ? ? ? ? values ? ? ? ? ( ? ? ? ? ? ? ? ?seq_customer_log.nextval , ? ? ? ? ? ? ? #{customerServiceUserName} , ? ? ? ? ? ? ? #{username}, ? ? ? ? ? ? ? #{content}, ? ? ? ? ? ? ? #{logFirstType}, ? ? ? ? ? ? ? #{status}, ? ? ? ? ? ? ? #{linkedId}, ? ? ? ? ? ? ? #{fee}, ? ? ? ? ? ? ? #{accountFirstType}, ? ? ? ? ? ? ? #{accountSecondType}, ? ? ? ? ? ? ? #{accountThirdType}, ? ? ? ? ? ? ? #{logSecondType}, ? ? ? ? ? ? ? #{logIp}, ? ? ? ? ? ? ? #{memo} ? ? ? ? ) ? ? </insert>
查詢了一下 一些資料說是
MyBatis 插入空值時,需要指定JdbcType ,mybatis insert空值報空值異常,但是在pl/sql不會提示錯誤,主要原因是mybatis無法進行轉換。
<insert id="insertCustomerLog1" parameterType="com.diyicai.customer.domain.CustomerLog"> ? ? ? ? ? insert into customer_log ? ? ? ? ? ? ? ? ?( ? ? ? ? ? ? ? ? ?ID, ? ? ? ? ? ? ? ? ?CUSTOMER_SERVICE_USER_NAME, ? ? ? ? ? ? ? ? ?user_name , ? ? ? ? ? ? ? ? ?CONTENT, ? ? ? ? ? ? ? ? ?LOG_FIRST_TYPE, ? ? ? ? ? ? ? ? ?STATUS, ? ? ? ? ? ? ? ? ?LINKED_ID, ? ? ? ? ? ? ? ? ?FEE, ? ? ? ? ? ? ? ? ?ACCOUNT_FIRST_TYPE, ? ? ? ? ? ? ? ? ?ACCOUNT_SECOND_TYPE, ? ? ? ? ? ? ? ? ?ACCOUNT_THIRD_TYPE, ? ? ? ? ? ? ? ? ?LOG_SECOND_TYPE, ? ? ? ? ? ? ? ? ?LOG_IP, ? ? ? ? ? ? ? ? ?MEMO ? ? ? ? ? ? ? ? ?) ? ? ? ? ? ? ? ? ?values ? ? ? ? ? ? ? ? ?( ? ? ? ? ? ? ? ? ?seq_customer_log.nextval , ? ? ? ? ? ? ? ? ?#{customerServiceUserName,jdbcType=VARCHAR} , ? ? ? ? ? ? ? ? ?#{username,jdbcType=VARCHAR}, ? ? ? ? ? ? ? ? ?#{content,jdbcType=VARCHAR}, ? ? ? ? ? ? ? ? ?#{logFirstType,jdbcType=NUMERIC}, ? ? ? ? ? ? ? ? ?#{status,jdbcType=NUMERIC}, ? ? ? ? ? ? ? ? ?#{linkedId,jdbcType=VARCHAR}, ? ? ? ? ? ? ? ? ?#{fee,jdbcType=NUMERIC}, ? ? ? ? ? ? ? ? ?#{accountFirstType,jdbcType=NUMERIC}, ? ? ? ? ? ? ? ? ?#{accountSecondType,jdbcType=NUMERIC}, ? ? ? ? ? ? ? ? ?#{accountThirdType,jdbcType=NUMERIC}, ? ? ? ? ? ? ? ? ?#{logSecondType,jdbcType=NUMERIC}, ? ? ? ? ? ? ? ? ?#{logIp,jdbcType=VARCHAR}, ? ? ? ? ? ? ? ? ?#{memo,jdbcType=VARCHAR} ? ? ? ? ? ? ? ? ?) ? ? ? </insert> ?
錯誤日志是在:org.apache.ibatis.type.BaseTypeHandler這個類的第17行打出的。根據(jù)異常上面的代碼 :
if (parameter == null) { ? ? if (jdbcType == null) { ? ? try { ? ? ps.setNull(i, JdbcType.OTHER.TYPE_CODE); ? ? } catch (SQLException e) { ? ? throw new TypeException("Error setting null parameter. Most JDBC drivers require that the JdbcType must be specified for all nullable parameters. Cause: " + e, e); ? ? } ? ? } else { ? ? ps.setNull(i, jdbcType.TYPE_CODE); ? ? } ? ? } else { ? ? setNonNullParameter(ps, i, parameter, jdbcType); ? ? } ?
可以看出,是因為你傳入的參數(shù)的字段為null對象無法獲取對應的jdbcType類型,而報的錯誤。 你只要在insert語句中insert的對象加上jdbcType就可以了,修改如下: #{menuTitle,jdbcType=VARCHAR} ,這樣就可以解決以上錯誤了。
但是,如果我們?yōu)槊總€sql都指定jdbc類型,也比較麻煩,可以mybatis-config.xml種全局設置下:
<settings> ?? ?<setting name="jdbcTypeForNull" value="NULL"/> </settings>
另外,再補充一點資料,可能更能讓我們了解問題的真相:
適配oracle數(shù)據(jù)庫的時候,mybatis報了Error setting null parameter,bug發(fā)現(xiàn)是參數(shù)出現(xiàn)了null值,對于Mybatis,如果進行操作的時候,沒有指定jdbcType類型的參數(shù),就可能導致問題。
postgreSQL,MySQL,SQLSERVER都支持JdbcType.NULL類型,Oracle是不支持,適配的時候也因為這個問題導致mybatis報錯。
比如,之前配置#{submitDate},它會在oracle中報錯:Error settingnull parameter
更改成#{submitDate,jdbcType=DATE},注意jdbcType是區(qū)分大小寫的。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java單例模式實現(xiàn)靜態(tài)內部類方法示例
這篇文章主要介紹了Java單例模式實現(xiàn)靜態(tài)內部類方法示例,涉及構造函數(shù)私有化等相關內容,需要的朋友可以了解下。2017-09-09