MyBatis學習16 自訂類型處理器typeHandlers介紹__mybatis

來源:互聯網
上載者:User

本文部落格地址:http://blog.csdn.net/soonfly/article/details/65628372 (轉載請註明出處)
我們在寫mapper映射器的設定檔時,不經意間已經用到類型轉換,不過是mybatis幫我們完成的。

<update id="update" parameterType="twm.mybatisdemo.pojo.User">    update user set    username=#{username},password=#{password},address=#{address}  where id=#{id}</update>

像上面例子,只需要向update方法傳入一個user對象,mybatis利用反射拆開user對象,然後根據對象中的欄位在預先處理語句(PreparedStatement)中設定參數,並且根據欄位的類型,使用setXXX()方式設定相應的值。XXX可以是Integer,String,Date等Java類型。
同理,在從結果集(ResultSet)中取出一個值時,將使用rs.getInt、rs.getString、rs.getTimeStamp等方法將資料轉換為Java對象。

那麼問題來了,javaType和jdbcType的轉換關係由誰來定呢。這就是類型處理器(type handlers)的功能所在。
比如java.lang.String轉成JDBC.Varchar,java.lang.Integer轉成JDBC.int。MyBatis使用內建的類型處理器能轉換所有的基礎資料型別 (Elementary Data Type)、基本類型的封裝類型、byte[] 、java.util.Date、java.sql.Date、java,sql.Time、java.sql.Timestamp、java枚舉類型等。

不過對於自訂的類型怎麼辦呢。
假設上面的address在資料庫欄位類型是varchar(50),但是在JAVA twm.mybatisdemo.pojo.User類中的address欄位並不是String類型,而是一個自訂的Address類型:

public class Address {    String province;    String city;    public Address() {}    public Address(String province, String city) {        this.province = province;        this.city = city;    }    //getter and setter......}

碰到這種情況,mybatis基本懵逼了。。。
如果啟動並執行話就報錯誤:

Type handler was null on parameter mapping for property ‘address’. It
was either not specified and/or could not be found for the javaType /
jdbcType combination specified.

address欄位需要傳遞給#{address},而address欄位是Address類型的,MyBatis並不知道該怎樣來處理這個類型的對象。
因此,需要建立一個自訂的類型處理器(TypeHandler)了

1、建立類型處理器:

class AddressTypeHandler extends BaseTypeHandler<Address>{}

通過ide自動產生代碼,可以看到父類BaseTypeHandler有四個方法需要我們實現,包括三個get方法,一個set方法。

2、實現get方法
三個get方法都是用於將資料庫獲得的記錄集裡的address欄位轉成java Address類型的對象。
所以我們首先給Address類增加一個構造方法,用途:根據字串產生一個執行個體對象。

//假設我們儲存在db中的字串是以","號分隔省市關係的public Address(String address) {      if (address != null) {          String[] segments = address.split(",");          if (segments.length > 1) {              this.province = segments[0];            this.city = segments[1];          }         else if (segments.length > 0) {              this.city = segments[0];          }      }  }

然後實現AddressTypeHandler類中的三個get方法:(有強迫症,不喜歡看arg0,arg1。所以順便也改一下)

@Overridepublic Address getNullableResult(ResultSet rSet, String columnName)        throws SQLException {    return new Address(rSet.getString(columnName));}@Overridepublic Address getNullableResult(ResultSet rSet, int columnIndex)        throws SQLException {    return new Address(rSet.getString(columnIndex));}@Overridepublic Address getNullableResult(CallableStatement cStatement, int columnIndex)        throws SQLException {    return new Address(cStatement.getString(columnIndex));}

3、實現set方法

set方法是用來將java類型轉成資料庫儲存的類型。
這裡我們先實現一下Address類的toString()方法(如果toString另有它用,那麼就另外用一個方法名)

@Overridepublic String toString() {    return this.province + "," + this.city;}

然後實現AddressTypeHandler類中的setNonNullParameter

@Overridepublic void setNonNullParameter(PreparedStatement pStatement, int index,        Address address, JdbcType jdbcType) throws SQLException {    pStatement.setString(index, address.toString());}

4、在myBatis設定檔中註冊該類

<!-- 註冊自訂類型處理器 --><typeHandlers>    <typeHandler handler="twm.mybatisdemo.type.AddressTypeHandler" /></typeHandlers>

這裡有個小插曲,我當時在設定檔最後插入了這段,結果提示錯誤:

The content of element type “configuration” must match
“(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)”.

原來在configuration裡的標籤,必須按照提示的這個順序寫,不然就報錯。
因此typeHandlers必須放在environments前面,typeAliases後面。
回顧一下,是不是感覺跟序列化/還原序列化這套路很相似。

本文部落格地址:http://blog.csdn.net/soonfly/article/details/65628372 (轉載請註明出處)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.