mybatis插入資料時處理為null的屬性
阿新 • • 發佈:2019-02-15
在做專案的時候,資料庫中的所有欄位被設定為全都不能為null,但是在我們開發過程中,插入一些記錄的時候,實體類中的一些欄位如果頁面沒有傳入,則預設就會被設定為null,這樣的話,在執行插入語句的時候,資料庫就會報錯,說指定的列不能為null,這樣資料就無法插入。
在網上找了一下,都沒有這種處理的方式,但是找到了mybatis的型別轉換,說的是在java中的型別和資料庫中的型別不一致的時候,需要自己處理資料庫型別和java中型別之間的轉換,這個就是通過mybatis的typehandler來處理的。
檢視typehandler這個介面發現有一下幾個需要實現的方法:
public String getResult(ResultSet rs, String columnName) throws SQLException;
public String getResult(ResultSet rs, int columnIndex) throws SQLException;
public String getResult(CallableStatement cs, int columnIndex) throws SQLException;
public void setParameter(PreparedStatement pstmt, int index, String value, JdbcType jdbcType) throws SQLException ;
在這4個需要實現的方法中,我們只需要關注第4個方法,因為這個方法是mybatis在給引數設定值的時候,會呼叫到此方法,基於這樣的原因,如果我們在setParameter中判斷當前引數傳入的值,如果value=null,我們就將引數的值設定為空的字串,這樣就避免了在執行插入語句的時候,傳入null的情況,資料庫中也不會報錯,問題就解決了。
程式碼:
以上是已經定義好的一個typehandler類,但是還需要我們在配置檔案中註冊我們自定義的typehandler,因為使用了和spring繼承的配置,所以註冊typehandler的配置在spring的配置檔案中的配置如下:
這裡指定了typeHandlersPackage屬性,value為自定義的typehandler的包名,這樣mybatis會將這個包下面的所有的類註冊為對應的TypeHandler類。
到這裡我們的自定義的TypeHandler就配置好了,
下面在我們的mybatis的mapper中,指定對應的typehandler為自定義的TypeHandler類就可以了
這裡在name引數上指定了typeHandler配置,這樣在資料插入的時候,mybatis會呼叫自定義的TypeHandler類來處理name引數的值,即,如果name的值為null則設定為空字串,如果不為空,則直接設定值。
現在如果我們測試,在前端如果沒有傳入name屬性的情況下,資料庫中插入的資料是否為空字串,而不是null
這裡我們什麼引數都沒有傳入,那麼在springmvc中Controller中,就會將對應的實體的屬性值設定為null
現在我們看到,頁面傳入的屬性值已經被注入到對應的實體的屬性中,沒有傳入的屬性全都是null。
此時檢視資料庫中插入的記錄,可以看到name的值為空字串,而沒有處理的sex的值為null
實現自定義的除了使用以上這種實現TypeHandler介面的方式外,還可以直接繼承BaseTypeHandler來實現。
package zzt.ssm.controller.typehandler; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; public class NullValueHandler implements TypeHandler<String> { @Override public String getResult(ResultSet rs, String columnName) throws SQLException { return rs.getString(columnName); } @Override public String getResult(ResultSet rs, int columnIndex) throws SQLException { return rs.getString(columnIndex); } @Override public String getResult(CallableStatement cs, int columnIndex) throws SQLException { return cs.getString(columnIndex); } @Override public void setParameter(PreparedStatement pstmt, int index, String value, JdbcType jdbcType) throws SQLException { if(value == null && jdbcType == JdbcType.VARCHAR){//判斷傳入的引數值是否為null pstmt.setString(index,"");//設定當前引數的值為空字串 }else{ pstmt.setString(index,value);//如果不為null,則直接設定引數的值為value } } } |
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 指定mapper檔案位置 -->
<property name="mapperLocations" value="classpath*:**/dao/*Mapper.xml" />
<!-- 指定別名 -->
<property name="typeAliasesPackage" value="zzt.ssm.domain" />
<property name="typeHandlersPackage" value="zzt.ssm. |
<!-- 新增人員資訊 --> <insert id="insertPerson" parameterType="Person"> insert into person(name,sex,address) values(#{name,jdbcType=VARCHAR,typeHandler=zzt.ssm.controller.typehandler.NullValueHandler},#{sex},#{address}) </insert> |
實現自定義的除了使用以上這種實現TypeHandler介面的方式外,還可以直接繼承BaseTypeHandler來實現。