GitChat:MyBatis 列舉全面使用指南
版權宣告:版權歸博主所有,轉載請帶上本文連結!聯絡方式:[email protected]://blog.csdn.net/isea533/article/details/86664594
連續好幾天都在寫這篇 GitChat,加起來的時間可能已經超過20多小時了。
本來想和之前的 Chat 一樣釋出後在 1 個月後免費,現在發現制度變了,付費文章需要等待 1 年後才能免費,想要參與的可以點選底部閱讀原文檢視。
為了能讓更多人儘可能瞭解列舉的用法,本場 GitChat 文章對應的示例原始碼會同步放到 github 上,看不到文章的朋友也可以看示例原始碼進行了解。
文章寫的非常詳細,大概有僅30頁,下面是個目錄以及開頭的一部分內容。
全文地址:https://gitbook.cn/gitchat/activity/5c31e09e0be52863d8388be4
示例程式碼:https://github.com/abel533/mybatis-enum
MyBatis 列舉全面使用指南
1. 從最早版本的用法說起
MyBatis 從一開始就自帶了兩個列舉的型別處理器EnumTypeHandler
和EnumOrdinalTypeHandler
,這兩個列舉型別處理器可以用於最簡單情況下的列舉型別。
為了方便下面的講解,先假設有如下簡單的列舉型別:
package tk.mybatis.enums.enumordinaltypehandler; public enum Sex { MALE, FEMALE }
1.1 EnumTypeHandler
這個型別處理器是 MyBatis 中預設的列舉型別處理器,他的作用是將列舉的名字和列舉型別對應起來。對於Sex
列舉來說,存資料庫時會使用"MALE"
或者"FEMALE"
字串儲存,從資料庫取值時,會將字串轉換為對應的列舉。
1.2 EnumOrdinalTypeHandler
這是另一個列舉型別處理器,他的作用是將列舉的索引和列舉型別對應起來。對於YesNoEnum
列舉來說,存資料庫時會使用列舉對應的順序0(MALE)
或者1(FEMALE)
儲存,從資料庫取值時,會將整型順序號(int)轉換為對應的列舉。
1.3 如何配置這兩種列舉型別
因為EnumTypeHandler
是預設的列舉處理器,所以預設不做任何配置的情況下,就使用的這個型別處理器,因此如果需要儲存"MALE"
或者"FEMALE"
值,就不需要任何配置。
如果想儲存列舉對應的索引,可以按照下面的方式進行配置:
<typeHandlers> <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="tk.mybatis.enums.enumordinaltypehandler.Sex" jdbcType="VARCHAR"/> </typeHandlers>
還可以省略jdbcType="VARCHAR"
屬性,按下面方式進行配置:
<typeHandlers> <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="tk.mybatis.enums.enumordinaltypehandler.Sex"/> </typeHandlers>
按上述方式進行配置後,就可以使用索引值存庫,如果有很多列舉怎麼辦,難道還要一個個進行配置嗎?目前有很多方式可以解決這個問題,不同 MyBatis 版本可以通過不同的方式去處理,後面會一一說明。
當你看到上面這兩種配置的變化時,會不會有種心虛的感覺,以後遇到類似情況時會不會無從下手?
既然列舉用法只是型別處理器的一種,而型別處理器又存在著各種變化,我們不妨先深入看看型別處理器的處理過程。
本文主要的配置都使用的 mybatis-3-config 格式的配置檔案, 後續和 Spring 及 Spring Boot 整合部分也有相應的配置方式 。
2. 深入瞭解 TypeHandler 型別處理器
2.1 只有typeHandlerClass
時
2.2 當提供typeHandlerClass
和javaTypeClass
時
2.3 當這三個屬性都提供時
2.4 查詢型別處理器
3. 配置型別處理器
3.1 全域性配置
3.1.1<typeHandler>
方式
3.1.2<package>
方式
3.2 區域性配置
3.2.1 查詢結果的對映
3.2.2#{attr}
方式
4. MyBatis 3.4.5+
4.1 根據更新程式碼變化來學習新功能
4.1.1 MyBatis 3.2.8 版本程式碼
4.1.2 MyBatis 3.4.5 版本程式碼
4.1.3 對比版本變化
4.2 列舉介面的用法
4.2.1 定義介面
4.2.2 定義兩個列舉類
4.2.3 實現介面對應的型別處理器
4.2.4 配置型別處理器
4.3 預設列舉處理器
4.4 繼承形式的型別處理器
5. Spring 整合
由於 Spring 和 Spring Boot 配置方式不同,這裡分別講解各自的配置方式。
5.1 Spring XML 配置
Spring 整合 MyBatis 的時候,配置SqlSessionFactoryBean
時如果指定configLocation
,就可以用 MyBatis 配置方式配置,示例如下:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:tk/mybatis/enums/spring/mybatis-config.xml"/> </bean>
如果你真用的這種方式,也沒任何問題,如果我只提供這麼一個方案就有點說不過去了。下面看看純 Spring 的配置方式:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeHandlers"> <array> <!--很明顯這裡沒法配置 `javaType`,因此必須使用 @MappedTypes(LabelValue.class) 註解--> <bean class="tk.mybatis.enums.spring.LabelValueTypeHandler"> <!--由於沒有預設無參的構造方法,所以只能指定構造引數,實際上給這個型別處理器提供一個無參的構造方法會更簡單,也沒有錯--> <constructor-arg index="0" value="tk.mybatis.enums.spring.LabelValue"/> </bean> </array> </property> </bean>
SqlSessionFactoryBean
提供了typeHandlers
屬性配置,因此可以用這種方式進行配置。但是這種方式配置有點特殊的地方,在用這種方式時,無法指定javaType
型別,因此上面的例子用了@MappedTypes(LabelValue.class)
註解。
除此之外,配置LabelValueTypeHandler
因為構造方法的原因,要多配置一個<constructor-arg>
,如果增加一個預設無參的構造方法,例如下面的程式碼:
@MappedTypes(LabelValue.class) public class LabelValueTypeHandler<E extends LabelValue> extends BaseTypeHandler<E> { private Class<E> type; private Map<Integer, E> enumMap; public LabelValueTypeHandler() { } public LabelValueTypeHandler(Class<E> type) { //省略其他 }
此時上面的配置可以簡化為:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeHandlers"> <array> <bean class="tk.mybatis.enums.spring.LabelValueTypeHandler"/> </array> </property> </bean>
這些都是技巧,結合本文所有示例看2. 深入瞭解 TypeHandler 型別處理器 時會加深理解,對這種用法會了解的更多。
除了typeHandlers
配置外,SqlSessionFactoryBean
還提供了typeAliasesPackage
配置型別處理器的包名,通過掃描包獲取包下所有型別處理器,示例如下:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeHandlersPackage" value="tk.mybatis.enums.spring"/> </bean>
如果想在純 Spring 配置情況下配置預設列舉型別處理,可以用下面的方式:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configuration"> <bean class="org.apache.ibatis.session.Configuration"> <property name="defaultEnumTypeHandler" value="tk.mybatis.enums.spring.LabelValueTypeHandler"/> </bean> </property> </bean>
針對 Spring XML 配置方式就這幾種,下面看看 Spring Boot 如何配置。