91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mybatis自定義typeHandler實現類型轉化

發布時間:2020-09-25 09:13:45 來源:網絡 閱讀:7192 作者:liuzhiyong0524 欄目:數據庫

 

Mybatis類型轉換介紹

1.1     目錄

1.2     建立TypeHandler

1.2.1    TypeHandler接口

1.2.2    BaseTypeHandler抽象類

1.3     注冊TypeHandler

1.4     Mybatis自動獲取TypeHandler

1.5     Mybatis中自動注冊的TypeHandler

 

 

1.2     建立TypeHandler

我們知道javajava的數據類型,數據庫有數據庫的數據類型,那么我們在往數據庫中插入數據的時候是如何把java類型當做數據庫類型插入數據庫,在從數據庫讀取數據的時候又是如何把數據庫類型當做java類型來處理呢?這中間必然要經過一個類型轉換。在Mybatis中我們可以定義一個叫做TypeHandler類型處理器的東西,通過它可以實現Java類型跟數據庫類型的相互轉換。下面將就如何建立自己的TypeHandler做一個簡要介紹。

1.2.1  TypeHandler接口

       Mybatis中要實現自己的TypeHandler就需要實現Mybatis為我們提供的TypeHandler接口。在TypeHandler中定義了四個方法:

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. public interface TypeHandler<T> {  

  2.    

  3.     /** 

  4.      * 用于定義在Mybatis設置參數時該如何把Java類型的參數轉換為對應的數據庫類型 

  5.      * @param ps 當前的PreparedStatement對象 

  6.      * @param i 當前參數的位置 

  7.      * @param parameter 當前參數的Java對象 

  8.      * @param jdbcType 當前參數的數據庫類型 

  9.      * @throws SQLException 

  10.      */  

  11.     void setParameter(PreparedStatement ps, int i, T parameter,  

  12.            JdbcType jdbcType) throws SQLException;  

  13.    

  14.     /** 

  15.      * 用于在Mybatis獲取數據結果集時如何把數據庫類型轉換為對應的Java類型 

  16.      * @param rs 當前的結果集 

  17.      * @param columnName 當前的字段名稱 

  18.      * @return 轉換后的Java對象 

  19.      * @throws SQLException 

  20.      */  

  21.     T getResult(ResultSet rs, String columnName) throws SQLException;  

  22.    

  23.     /** 

  24.      * 用于在Mybatis通過字段位置獲取字段數據時把數據庫類型轉換為對應的Java類型 

  25.      * @param rs 當前的結果集 

  26.      * @param columnIndex 當前字段的位置 

  27.      * @return 轉換后的Java對象 

  28.      * @throws SQLException 

  29.      */  

  30.     T getResult(ResultSet rs, int columnIndex) throws SQLException;  

  31.    

  32.     /** 

  33.      * 用于Mybatis在調用存儲過程后把數據庫類型的數據轉換為對應的Java類型 

  34.      * @param cs 當前的CallableStatement執行后的CallableStatement 

  35.      * @param columnIndex 當前輸出參數的位置 

  36.      * @return 

  37.      * @throws SQLException 

  38.      */  

  39.     T getResult(CallableStatement cs, int columnIndex) throws SQLException;  

  40.    

  41. }  

 

       現在假設我們有一個實體對象User,其中有一個屬性interestsString數組類型,如下所示:

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. public class User {  

  2.    

  3.     private int id;  

  4.     private String name;  

  5.     private int age;  

  6.     private String[] interests;  

  7.    

  8.     public int getId() {  

  9.        return id;  

  10.     }  

  11.    

  12.     public void setId(int id) {  

  13.        this.id = id;  

  14.     }  

  15.    

  16.     public String getName() {  

  17.        return name;  

  18.     }  

  19.    

  20.     public void setName(String name) {  

  21.        this.name = name;  

  22.     }  

  23.    

  24.     public int getAge() {  

  25.        return age;  

  26.     }  

  27.    

  28.     public void setAge(int age) {  

  29.        this.age = age;  

  30.     }  

  31.    

  32.     public String[] getInterests() {  

  33.        return interests;  

  34.     }  

  35.    

  36.     public void setInterests(String[] interests) {  

  37.        this.interests = interests;  

  38.     }  

  39.    

  40.     @Override  

  41.     public String toString() {  

  42.        return "User [age=" + age + ", id=" + id + ", interests="  

  43.               + Arrays.toString(interests) + ", name=" + name + "]";  

  44.     }  

  45.      

  46. }  

 

我們需要把它以拼接字符串的形式存到數據庫中,然后在取出來的時候又把它還原為一個String數組。這個時候我們就可以給它定義一個TypeHandler專門來處理String數組類型和數據庫VARCHAR類型的相互轉換。在這里我們建立一個名叫StringArrayTypeHandlerTypeHandler,代碼如下所示:

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. package com.tiantian.mybatis.handler;  

  2.    

  3. import java.sql.CallableStatement;  

  4. import java.sql.PreparedStatement;  

  5. import java.sql.ResultSet;  

  6. import java.sql.SQLException;  

  7. import java.sql.Types;  

  8.    

  9. import org.apache.ibatis.type.JdbcType;  

  10. import org.apache.ibatis.type.TypeHandler;  

  11.    

  12. public class StringArrayTypeHandler implements TypeHandler<String[]> {  

  13.    

  14.        public String[] getResult(ResultSet rs, String columnName)  

  15.                      throws SQLException {  

  16.               String columnValue = rs.getString(columnName);  

  17.               return this.getStringArray(columnValue);  

  18.        }  

  19.    

  20.        public String[] getResult(ResultSet rs, int columnIndex)  

  21.                      throws SQLException {  

  22.               String columnValue = rs.getString(columnIndex);  

  23.               return this.getStringArray(columnValue);  

  24.        }  

  25.    

  26.        public String[] getResult(CallableStatement cs, int columnIndex)  

  27.                      throws SQLException {  

  28.               // TODO Auto-generated method stub  

  29.               String columnValue = cs.getString(columnIndex);  

  30.               return this.getStringArray(columnValue);  

  31.        }  

  32.    

  33.        public void setParameter(PreparedStatement ps, int i, String[] parameter,  

  34.                      JdbcType jdbcType) throws SQLException {  

  35.               if (parameter == null)  

  36.                      ps.setNull(i, Types.VARCHAR);  

  37.               else {  

  38.                      StringBuffer result = new StringBuffer();  

  39.                      for (String value : parameter)  

  40.                             result.append(value).append(",");  

  41.                      result.deleteCharAt(result.length()-1);  

  42.                      ps.setString(i, result.toString());  

  43.               }  

  44.        }  

  45.    

  46.        private String[] getStringArray(String columnValue) {  

  47.               if (columnValue == null)  

  48.                      return null;  

  49.               return columnValue.split(",");  

  50.        }  

  51.    

  52. }  

 

1.2.2  BaseTypeHandler抽象類

       在實現自己的TypeHandler時,除了上面提到的實現最原始的接口之外,Mybatis還為我們提供了一個實現了TypeHandler接口的抽象類BaseTypeHandler。所以我們也可以通過繼承BaseTypeHandler來實現自己的TypeHandler

       我們先來看一下BaseTypeHandler類的定義:

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {  

  2.    

  3.   protected Configuration configuration;  

  4.    

  5.   public void setConfiguration(Configuration c) {  

  6.     this.configuration = c;  

  7.   }  

  8.    

  9.   public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {  

  10.     if (parameter == null) {  

  11.       if (jdbcType == null) {  

  12.         throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");  

  13.       }  

  14.       try {  

  15.         ps.setNull(i, jdbcType.TYPE_CODE);  

  16.       } catch (SQLException e) {  

  17.         throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " +  

  18.              "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " +  

  19.              "Cause: " + e, e);  

  20.       }  

  21.     } else {  

  22.       setNonNullParameter(ps, i, parameter, jdbcType);  

  23.     }  

  24.   }  

  25.    

  26.   public T getResult(ResultSet rs, String columnName) throws SQLException {  

  27.     T result = getNullableResult(rs, columnName);  

  28.     if (rs.wasNull()) {  

  29.       return null;  

  30.     } else {  

  31.       return result;  

  32.     }  

  33.   }  

  34.    

  35.   public T getResult(ResultSet rs, int columnIndex) throws SQLException {  

  36.     T result = getNullableResult(rs, columnIndex);  

  37.     if (rs.wasNull()) {  

  38.       return null;  

  39.     } else {  

  40.       return result;  

  41.     }  

  42.   }  

  43.    

  44.   public T getResult(CallableStatement cs, int columnIndex) throws SQLException {  

  45.     T result = getNullableResult(cs, columnIndex);  

  46.     if (cs.wasNull()) {  

  47.       return null;  

  48.     } else {  

  49.       return result;  

  50.     }  

  51.   }  

  52.    

  53.   public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;  

  54.    

  55.   public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;  

  56.    

  57.   public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;  

  58.    

  59.   public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;  

  60.    

  61. }  

 

       我們可以看到BaseTypeHandlerTypeHandler接口的四個方法做了一個簡單的選擇,把null值的情況都做了一個過濾,核心的取值和設值的方法還是抽象出來了供子類來實現。使用BaseTypeHandler還有一個好處是它繼承了另外一個叫做TypeReference的抽象類,通過TypeReferencegetRawType()方法可以獲取到當前TypeHandler所使用泛型的原始類型。這對Mybatis在注冊TypeHandler的時候是非常有好處的。在沒有指定javaType的情況下,Mybatis在注冊TypeHandler時可以通過它來獲取當前TypeHandler所使用泛型的原始類型作為要注冊的TypeHandlerjavaType類型,這個在講到Mybatis注冊TypeHandler的方式時將講到。

       當通過繼承BaseTypeHandler來實現自己的TypeHandler時,我們的StringArrayTypeHandler應該這樣寫:

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. public class StringArrayTypeHandler extends BaseTypeHandler<String[]> {  

  2.    

  3.     @Override  

  4.     public String[] getNullableResult(ResultSet rs, String columnName)  

  5.            throws SQLException {  

  6.        return getStringArray(rs.getString(columnName));  

  7.     }  

  8.    

  9.     @Override  

  10.     public String[] getNullableResult(ResultSet rs, int columnIndex)  

  11.            throws SQLException {  

  12.        return this.getStringArray(rs.getString(columnIndex));  

  13.     }  

  14.    

  15.     @Override  

  16.     public String[] getNullableResult(CallableStatement cs, int columnIndex)  

  17.            throws SQLException {  

  18.        return this.getStringArray(cs.getString(columnIndex));  

  19.     }  

  20.    

  21.     @Override  

  22.     public void setNonNullParameter(PreparedStatement ps, int i,  

  23.            String[] parameter, JdbcType jdbcType) throws SQLException {  

  24.        //由于BaseTypeHandler中已經把parameter為null的情況做了處理,所以這里我們就不用再判斷parameter是否為空了,直接用就可以了  

  25.        StringBuffer result = new StringBuffer();  

  26.        for (String value : parameter)  

  27.            result.append(value).append(",");  

  28.        result.deleteCharAt(result.length()-1);  

  29.        ps.setString(i, result.toString());  

  30.     }  

  31.      

  32.     private String[] getStringArray(String columnValue) {  

  33.        if (columnValue == null)  

  34.            return null;  

  35.        return columnValue.split(",");  

  36.     }  

  37. }  

 

 

1.3     注冊TypeHandler

       建立了自己的TypeHandler之后就需要把它注冊到Mybatis的配置文件中,讓Mybatis能夠識別并使用它。注冊TypeHandler主要有兩種方式,一種是通過在Mybatis配置文件中定義typeHandlers元素的子元素typeHandler來注冊;另一種是通過在Mybatis配置文件中定義typeHandlers元素的子元素package來注冊。使用typeHandler子元素注冊時一次只能注冊一個TypeHandler,而使用package子元素注冊時,Mybatis會把指定包里面的所有TypeHandler都注冊為TypeHandler。使用typeHandler子元素注冊時我們需要通過它的handler屬性來指明當前要注冊的TypeHandler的全名稱,這個屬性是必須要的。另外還有兩個附加屬性可以指定,一個是javaType,用以指定對應的java類型;另一個是jdbcType,用以指定對應的jdbc類型。使用package子元素注冊時需要我們通過它的name屬性來指定要掃描的包,如果這個時候我們也需要指定對應TypeHandlerjavaTypejdbcType的話就需要我們在TypeHandler類上使用注解來定義了。Mybatis注冊TypeHandler最基本的方式就是建立一個javaTypejdbcTypeTypeHandler的對應關系。在使用typeHandler子元素進行注冊的時候,有三種類型的注冊方式:

1.如果我們指定了javaTypejdbcType,那么Mybatis會注冊一個對應javaTypejdbcTypeTypeHandler

2.如果我們只指定了javaType屬性,那么這個時候又分兩種情況:

1)如果我們通過注解的形式在TypeHandler類上用@MappedJdbcTypes指定了對應的jdbcType,那么Mybatis會一一注冊指定的javaTypejdbcTypeTypeHandler的組合,也包括使用這種形式指定了jdbcTypenull的情況。現假設我們有如下這樣一個StringArrayTypeHandler

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. @MappedJdbcTypes({JdbcType.VARCHAR})  

  2. public class StringArrayTypeHandler implements TypeHandler<String[]> {  

  3.     //..中間的實現代碼省略了  

  4.     //..  

  5. }  

 

       然后我們在Mybatis的配置文件中這樣注冊它:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <typeHandlers>  

  2.    <typeHandler handler="com.tiantian.mybatis.handler.StringArrayTypeHandler" javaType="[Ljava.lang.String;"/>  

  3. </typeHandlers>  

 

       Mybatis在實際注冊的時候是以javaTypeString數組,jdbcTypeVARCHAR來注冊StringArrayTypeHandler的。

2)如果沒有使用@MappedJdbcTypes注解指定對應的jdbcType,那么這個時候Mybatis會把jdbcType置為null,然后注冊一個javaTypenullTypeHandler的組合。

3.既沒有指定javaType屬性,又沒有指定jdbcType屬性,或者只指定了jdbcType屬性。這種情況又分三種類型:

1)如果TypeHandler類上使用了注解@MappedTypes指定了對應的javaType,那么Mybatis將一一利用對應的javaTypeTypeHandler去以2的方式進行注冊。現假設我們定義了這樣一個StringArrayTypeHandler

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. @MappedTypes({String[].class})  

  2. @MappedJdbcTypes({JdbcType.VARCHAR})  

  3. public class StringArrayTypeHandler implements TypeHandler<String[]> {  

  4.    

  5.      

  6.    

  7. }  

 

       然后,在Mybatis的配置文件中注冊它時既不指定它的javaType屬性也不指定它的jdbcType屬性,代碼如下:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <typeHandlers>  

  2.    <typeHandler handler="com.tiantian.mybatis.handler.StringArrayTypeHandler"/>  

  3. </typeHandlers>  

 

     則這個時候Mybatis在注冊該StringArrayTypeHandler的時候首先會判斷它上面有沒有標注@MappedTypes,如果有則把它的MappedTypes一一拿出來作為javaType,然后以方式2進行注冊。所以這里實際上Mybatis注冊的還是javaTypeString數組,jdbcTypeVARCHAR這樣一個組合的TypeHandler

2TypeHandler類上沒有使用@MappedTypes指定對應的javaType時,如果當前的TypeHandler繼承了TypeReference抽象類,Mybatis會利用TypeReferencegetRawType()方法取到當前TypeHandler泛型對應的javaType類型,然后利用取得的javaTypeTypeHandler2的方式進行注冊,同時還包括一個javaTypenull以方式2進行的注冊。TypeReferenceMybatis中定義的一個抽象類,主要是用來獲取對應的泛型類型。

3TypeHandler類上既沒有標注@MappedTypes,又沒有繼承TypeReference抽象類。這種情況Mybatis會以nullnull的組合注冊該TypeHandler

使用package子元素注冊的TypeHandler會以上面的方式3進行注冊。

這里我們如下注冊我們的TypeHandler

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE configuration  

  3.   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-config.dtd">  

  5. <configuration>  

  6.    

  7.     <properties resource="config/jdbc.properties"></properties>  

  8.     <typeAliases>  

  9.        <package name="com.tiantian.mybatis.model"/>  

  10.     </typeAliases>  

  11.     <typeHandlers>  

  12.        <typeHandler handler="com.tiantian.mybatis.handler.StringArrayTypeHandler" javaType="[Ljava.lang.String;" jdbcType="VARCHAR"/>  

  13.     </typeHandlers>  

  14.     <environments default="development">  

  15.        <environment id="development">  

  16.            <transactionManager type="JDBC" />  

  17.            <dataSource type="POOLED">  

  18.               <property name="driver" value="${jdbc.driver}" />  

  19.               <property name="url" value="${jdbc.url}" />  

  20.               <property name="username" value="${jdbc.username}" />  

  21.               <property name="password" value="${jdbc.password}" />  

  22.            </dataSource>  

  23.        </environment>  

  24.     </environments>  

  25.     <mappers>  

  26.        <mapper resource="com/tiantian/mybatis/mapper/UserMapper.xml"/>  

  27.        <package name="com.tiantian.mybatis.mapperinterface"/>  

  28.     </mappers>  

  29. </configuration>  

 

       注意String數組的全類名稱是“[Ljava.lang.String;”,所以上面在注冊StringArrayTypeHandler時定義的javaType屬性為“[Ljava.lang.String;”。

1.4     Mybatis自動獲取TypeHandler

       在介紹了Mybatis是如何注冊TypeHandler之后就介紹一下Mybatis是如何獲取對應的TypeHandler進行類型轉換的。

       如果我們在Mapper.xml文件中配置某一個屬性或變量的映射關系時指定了該屬性對應的javaTypejdbcType,則Mybatis會從注冊好的TypeHandler中尋找對應的javaTypejdbcType組合的TypeHandler進行處理,這也是Mybatis最基本的獲取TypeHandler進行類型轉換的方式。假設Mybatis配置文件中有這么一段TypeHandler的注冊信息:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <typeHandlers>  

  2.    <typeHandler handler="com.tiantian.mybatis.handler.StringArrayTypeHandler" javaType="[Ljava.lang.String;" jdbcType="VARCHAR"/>  

  3. </typeHandlers>  

 

看這樣一個UserMapper.xml定義:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE mapper  

  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

  5.    

  6. <mapper namespace="com.tiantian.mybatis.mapper.UserMapper">  

  7.    

  8.     <resultMap id="UserResult" type="User">  

  9.        <id column="id" property="id"/>  

  10.        <result column="interests" property="interests" javaType="[Ljava.lang.String;" jdbcType="VARCHAR"/>  

  11.     </resultMap>  

  12.    

  13.     <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyColumn="id">  

  14.        insert into t_user(name, age, interests) values(#{name}, #{age}, #{interests, javaType=[Ljava.lang.String;, jdbcType=VARCHAR})  

  15.     </insert>  

  16.      

  17.     <update id="updateUser" parameterType="User">  

  18.        update t_user set name=#{name}, age=#{age}, interests=#{interests} where id=#{id}  

  19.     </update>  

  20.      

  21.     <select id="findById" parameterType="int" resultMap="UserResult">  

  22.        select * from t_user where id=#{id}  

  23.     </select>  

  24.      

  25.     <delete id="deleteUser" parameterType="int">  

  26.        delete from t_user where id=#{id}  

  27.     </delete>  

  28. </mapper>  

 

       我們可以看到在idUserResultresultMap中,我們定義了一個對應字段interests的映射關系,并且定義了其javaType為“[Ljava.lang.String;”,jdbcTypeVARCHAR,這個時候Mybatis就會到已經注冊了的TypeHandler中尋找到能處理javaTypejdbcType對應的類型轉換的TypeHandler來進行處理。在這里就會找到我們注冊的StringArrayTypeHandler。在上面idinsertUserinsert語句中,我們也為變量interests指定了它的javaTypejdbcType屬性,這時候Mybatis也會尋找javaTypejdbcType對應的TypeHandler。上面這樣定義是Mybatis最基本也是最完整地獲取到對應的TypeHandler的方法。這里我們來對UserMapper(它的代碼我就不貼出來了,有Mybatis基礎的都應該知道它的代碼)的findById來做一個測試:

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. @Test  

  2. public void testFind() {  

  3.    SqlSession sqlSession = sqlSessionFactory.openSession();  

  4.    try {  

  5.        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  

  6.        User user = userMapper.findById(20);  

  7.        System.out.println(user);  

  8.    } finally {  

  9.        sqlSession.close();  

  10.    }  

  11. }  

 

       其輸出結果如下:

Text代碼  Mybatis自定義typeHandler實現類型轉化

  1. User [age=30, id=20, interests=[Music, Movie, NBA], name=張三]  

 

我們可以看到Mybatis已經把我們存放在數據庫中VARCHAR類型的字段interests轉換為User類字符串數組類型的interests屬性,這說明我們定義的StringArrayTypeHandler發生作用了。

除了上面的完整指定一個變量對應的javaTypejdbcType,讓Mybatis能夠完美的找到對應的TypeHandler之外。我們平常在使用的時候可能還有以下方式:

       1.只指定變量對應的javaType類型。這個時候Mybatis會拿著這個javaTypejdbcTypenull的組合到注冊的TypeHandler中尋找對應的TypeHandler。這里我們同樣來做一個測試:

       1)不動StringArrayTypeHandler的注冊信息,把我們的UserMapper.xml改為如下形式:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE mapper  

  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

  5. <mapper namespace="com.tiantian.mybatis.mapper.UserMapper">  

  6.     <resultMap id="UserResult" type="User">  

  7.        <id column="id" property="id"/>  

  8.        <result column="interests" property="interests" javaType="[Ljava.lang.String;"/>  

  9.     </resultMap>  

  10.    

  11.     <select id="findById" parameterType="int" resultMap="UserResult">  

  12.        select * from t_user where id=#{id}  

  13.     </select>  

  14. </mapper>  

 

       這時候再運行上面的測試程序,輸出結果如下:

Text代碼  Mybatis自定義typeHandler實現類型轉化

  1. User [age=30, id=20, interests=null, name=張三]  

 

       我們可以看到輸出的interestsnull,這說明Mybatis沒有使用我們定義的StringArrayTypeHandler來轉換interests

       2UserMapper.xml還像上面那樣定義,但是也只指定javaType屬性來注冊我們的StringArrayTypeHandler,代碼如下:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE configuration  

  3.   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-config.dtd">  

  5. <configuration>  

  6.     <properties resource="config/jdbc.properties"></properties>  

  7.     <typeAliases>  

  8.        <package name="com.tiantian.mybatis.model"/>  

  9.     </typeAliases>  

  10.     <typeHandlers>  

  11.        <typeHandler handler="com.tiantian.mybatis.handler.StringArrayTypeHandler" javaType="[Ljava.lang.String;"/>  

  12.     </typeHandlers>  

  13.     <environments default="development">  

  14.        <environment id="development">  

  15.            <transactionManager type="JDBC" />  

  16.            <dataSource type="POOLED">  

  17.               <property name="driver" value="${jdbc.driver}" />  

  18.               <property name="url" value="${jdbc.url}" />  

  19.               <property name="username" value="${jdbc.username}" />  

  20.               <property name="password" value="${jdbc.password}" />  

  21.            </dataSource>  

  22.        </environment>  

  23.     </environments>  

  24.     <mappers>  

  25.        <mapper resource="com/tiantian/mybatis/mapper/UserMapper.xml"/>  

  26.     </mappers>  

  27. </configuration>  

 

       這個時候再運行上面的測試代碼,輸出結果如下:

Text代碼  Mybatis自定義typeHandler實現類型轉化

  1. User [age=30, id=20, interests=[Music, Movie, NBA], name=張三]  

 

       這是因為我們是以javaTypenull注冊的StringArrayTypeHandler,然后在需要轉換interests時又是以相同的javaTypenull來尋找的,所以就會找到我們注冊的StringArrayTypeHandler來進行類型轉換。

       2.只指定變量對應的jdbcType類型。這個時候Mybatis會利用我們指定的返回類型和對應的屬性取該屬性在返回類型中對應的javaType,之后再拿著該javaType和我們指定的jdbcType到注冊的TypeHandler中獲取對應的TypeHandler。這里我們來看這樣一個測試:

       保持之前指定javaTypejdbcType的方式注冊StringArrayTypeHandler,然后在定義interests變量的時候不指定javaType,只指定jdbcType,這個時候UserMapper.xml如下所示:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE mapper  

  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

  5. <mapper namespace="com.tiantian.mybatis.mapper.UserMapper">  

  6.     <resultMap id="UserResult" type="User">  

  7.        <id column="id" property="id"/>  

  8.        <result column="interests" property="interests" jdbcType="VARCHAR"/>  

  9.     </resultMap>  

  10.     <select id="findById" parameterType="int" resultMap="UserResult">  

  11.        select * from t_user where id=#{id}  

  12.     </select>  

  13. </mapper>  

 

       這個時候繼續運行上面的測試代碼,輸出結果如下:

Text代碼  Mybatis自定義typeHandler實現類型轉化

  1. User [age=30, id=20, interests=[Music, Movie, NBA], name=張三]  

 

       這個時候Mybatis是這樣獲取TypeHandler的:首先它發現我們的interests沒有指定javaType,這個時候它就會通過我們指定的類型User和屬性interests獲取User類的interests屬性對應的java類型,即String數組,再拿著獲取到的javaType和我們指定的jdbcTypeVARCHAR去尋找對應的TypeHandler,這個時候就找到了我們之前以String數組和VARCHAR注冊好的StringArrayTypeHandler來處理interests的類型轉換。

       3.javaType類型和jdbcType類型都不指定。這個時候Mybatis會以方式2中的方式獲取到對應的javaType類型,然后再以方式1獲取到對應的TypeHandler。這里我們也來做一個測試:

       1)首先,注冊一個javaTypeString數組,jdbcType不指定即為nullTypeHandlerStringArrayTypeHandler,代碼如下:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE configuration  

  3.   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-config.dtd">  

  5. <configuration>  

  6.     <properties resource="config/jdbc.properties"></properties>  

  7.     <typeAliases>  

  8.        <package name="com.tiantian.mybatis.model"/>  

  9.     </typeAliases>  

  10.     <typeHandlers>  

  11.        <typeHandler handler="com.tiantian.mybatis.handler.StringArrayTypeHandler" javaType="[Ljava.lang.String;"/>  

  12.     </typeHandlers>  

  13.     <environments default="development">  

  14.        <environment id="development">  

  15.            <transactionManager type="JDBC" />  

  16.            <dataSource type="POOLED">  

  17.               <property name="driver" value="${jdbc.driver}" />  

  18.               <property name="url" value="${jdbc.url}" />  

  19.               <property name="username" value="${jdbc.username}" />  

  20.               <property name="password" value="${jdbc.password}" />  

  21.            </dataSource>  

  22.        </environment>  

  23.     </environments>  

  24.     <mappers>  

  25.        <mapper resource="com/tiantian/mybatis/mapper/UserMapper.xml"/>  

  26.     </mappers>  

  27. </configuration>  

 

       2)然后,定義我們的interests字段的映射關系時既不指定javaType,又不指定jdbcType,代碼如下:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE mapper  

  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

  5. <mapper namespace="com.tiantian.mybatis.mapper.UserMapper">  

  6.     <resultMap id="UserResult" type="User">  

  7.        <id column="id" property="id"/>  

  8.        <result column="interests" property="interests"/>  

  9.     </resultMap>  

  10.     <select id="findById" parameterType="int" resultMap="UserResult">  

  11.        select * from t_user where id=#{id}  

  12.     </select>  

  13. </mapper>  

 

       這個時候再運行上面的測試代碼,輸出如下:

Text代碼  Mybatis自定義typeHandler實現類型轉化

  1. User [age=30, id=20, interests=[Music, Movie, NBA], name=張三]  

 

       這種情況是這樣的:我們以javaTypeString數組和jdbcTypenull注冊了一個StringArrayTypeHandler,然后在定義interests字段的映射關系時我們沒有指明其對應的javaTypejdbcType,這個時候Mybatis會利用我們指定的User類型和interests屬性獲取到User類的interests屬性對應的java類型,即String數組,然后結合jdbcTypenull去尋找注冊的TypeHandler,這樣就找到了StringArrayTypeHandler。經StringArrayTypeHandler的處理就把jdbcTypeVARCHAR的數據轉換為javaTypeString數組的數據,所以輸出結果如上所示。

       4.還有一種形式是我們直接通過變量的typeHandler屬性指定其對應的TypeHandler,這個時候Mybatis就會使用該用戶自己指定的TypeHandler來進行類型轉換,而不再以javaTypejdbcType組合的方式獲取對應的TypeHandler。這里我們也來做一個測試:

       1)首先在Mybatis的配置文件中以javaTypejdbcType配套的方式注冊一個StringArrayTypeHandler,代碼如下:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE configuration  

  3.   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-config.dtd">  

  5. <configuration>  

  6.     <properties resource="config/jdbc.properties"></properties>  

  7.     <typeAliases>  

  8.        <package name="com.tiantian.mybatis.model"/>  

  9.     </typeAliases>  

  10.     <typeHandlers>  

  11.        <typeHandler handler="com.tiantian.mybatis.handler.StringArrayTypeHandler" javaType="[Ljava.lang.String;" jdbcType="VARCHAR"/>  

  12.     </typeHandlers>  

  13.     <environments default="development">  

  14.        <environment id="development">  

  15.            <transactionManager type="JDBC" />  

  16.            <dataSource type="POOLED">  

  17.               <property name="driver" value="${jdbc.driver}" />  

  18.               <property name="url" value="${jdbc.url}" />  

  19.               <property name="username" value="${jdbc.username}" />  

  20.               <property name="password" value="${jdbc.password}" />  

  21.            </dataSource>  

  22.        </environment>  

  23.     </environments>  

  24.     <mappers>  

  25.        <mapper resource="com/tiantian/mybatis/mapper/UserMapper.xml"/>  

  26.     </mappers>  

  27. </configuration>  

 

       按照前面說的Mybatis按照變量的javaTypejdbcType來取對應的TypeHandler的話,這里注冊的StringArrayTypeHandler只有在指定變量的javaType為字符串數組而jdbcTypeVARCHAR的情況下才能被獲取到。

       2)然后我們在UserMapper.xml文件中不指定interests字段對應的javaTypejdbcType,但是通過typeHandler屬性指定將以StringArrayTypeHandler來進行類型轉換,代碼如下:

Xml代碼  Mybatis自定義typeHandler實現類型轉化

  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE mapper  

  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  

  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

  5. <mapper namespace="com.tiantian.mybatis.mapper.UserMapper">  

  6.     <resultMap id="UserResult" type="User">  

  7.        <id column="id" property="id"/>  

  8.        <result column="interests" property="interests" typeHandler="com.tiantian.mybatis.handler.StringArrayTypeHandler"/>  

  9.     </resultMap>  

  10.     <select id="findById" parameterType="int" resultMap="UserResult">  

  11.        select * from t_user where id=#{id}  

  12.     </select>  

  13. </mapper>  

 

       運行上面的測試代碼,輸出結果:

Text代碼  Mybatis自定義typeHandler實現類型轉化

  1. User [age=30, id=20, interests=[Music, Movie, NBA], name=張三]  

 

       這是因為我們指定了進行interests字段的映射關系時使用StringArrayTypeHandler來進行類型轉換。當指定了某一個字段或變量進行映射關系時所使用的TypeHandler時,Mybatis在需要進行類型轉換時就使用給定的TypeHandler進行類型轉換,而不會再通過javaTypejdbcType的組合去注冊好的TypeHandler中尋找對應的TypeHandler

1.5     Mybatis中自動注冊的TypeHandler

       對于一些常用類型的自動轉換Mybatis已經為我們建立了相關的TypeHandler,并且會自動注冊它們,這主要包括:

Java代碼  Mybatis自定義typeHandler實現類型轉化

  1. register(Boolean.classnew BooleanTypeHandler());  

  2. register(boolean.classnew BooleanTypeHandler());  

  3. register(Byte.classnew ByteTypeHandler());  

  4. register(byte.classnew ByteTypeHandler());  

  5. register(Short.classnew ShortTypeHandler());  

  6. register(short.classnew ShortTypeHandler());  

  7. register(Integer.classnew IntegerTypeHandler());  

  8. register(int.classnew IntegerTypeHandler());  

  9. register(Long.classnew LongTypeHandler());  

  10. register(long.classnew LongTypeHandler());  

  11. register(Float.classnew FloatTypeHandler());  

  12. register(float.classnew FloatTypeHandler());  

  13. register(Double.classnew DoubleTypeHandler());  

  14. register(double.classnew DoubleTypeHandler());  

  15. register(String.classnew StringTypeHandler());  

  16. register(String.class, JdbcType.CHAR, new StringTypeHandler());  

  17. register(String.class, JdbcType.CLOB, new ClobTypeHandler());  

  18. register(String.class, JdbcType.VARCHAR, new StringTypeHandler());  

  19. register(String.class, JdbcType.LONGVARCHAR, new ClobTypeHandler());  

  20. register(String.class, JdbcType.NVARCHAR, new NStringTypeHandler());  

  21. register(String.class, JdbcType.NCHAR, new NStringTypeHandler());  

  22. register(String.class, JdbcType.NCLOB, new NClobTypeHandler());  

  23. register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());  

  24. register(BigInteger.classnew BigIntegerTypeHandler());  

  25. register(BigDecimal.classnew BigDecimalTypeHandler());  

  26. register(Byte[].classnew ByteObjectArrayTypeHandler());  

  27. register(Byte[].class, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());  

  28. register(Byte[].class, JdbcType.LONGVARBINARY, new BlobByteObjectArrayTypeHandler());  

  29. register(byte[].classnew ByteArrayTypeHandler());  

  30. register(byte[].class, JdbcType.BLOB, new BlobTypeHandler());  

  31. register(byte[].class, JdbcType.LONGVARBINARY, new BlobTypeHandler());  

  32. register(Object.class, UNKNOWN_TYPE_HANDLER);  

  33. register(Object.class, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);  

  34. register(Date.classnew DateTypeHandler());  

  35. register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler());  

  36. register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler());  

  37. register(java.sql.Date.classnew SqlDateTypeHandler());  

  38. register(java.sql.Time.classnew SqlTimeTypeHandler());  

  39. register(java.sql.Timestamp.classnew SqlTimestampTypeHandler());  

  40. register(Character.classnew CharacterTypeHandler());  

  41. register(char.classnew CharacterTypeHandler()); 



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

治多县| 兴海县| 历史| 大埔区| 册亨县| 饶河县| 蓬莱市| 寻甸| 陈巴尔虎旗| 温泉县| 丰台区| 宣恩县| 闵行区| 潜江市| 克拉玛依市| 涡阳县| 宜丰县| 盖州市| 常州市| 娄烦县| 天祝| 吉安县| 临朐县| 开江县| 永城市| 宁海县| 昌黎县| 六枝特区| 封开县| 张家港市| 鄂尔多斯市| 双鸭山市| 桑日县| 宁国市| 莎车县| 莱芜市| 中卫市| 建湖县| 乡城县| 中西区| 吉林市|