1. 程式人生 > >02.MyBatis配置檔案詳解

02.MyBatis配置檔案詳解

1.properties 屬性

1.在MyBatis配置檔案中引用屬性檔案MyBatis允許在mybatis-config.xml配置檔案中載入*.properties屬性檔案,並使用屬性檔案的屬性值,以提高應用的配置能力。例如在mybatis-config.xml檔案所在目錄下建立檔案config.properties,其內容如下:
  1. mysql.driver = com.mysql.jdbc.Driver
  2. mysql.url = jdbc:mysql://localhost:3306/test
  3. mysql.username = root
  4. mysql.password = lizhiwei
  5. oracle.driver
    =oracle.jdbc.driver.OracleDriver
  6. oracle.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
  7. oracle.username=
  8. oracle.password=
mybatis-config.xml檔案中的使用如下:
  1. <propertiesresource="config.properties">
  2. <propertyname="property_0"value="value_1"/>
  3. <propertyname="property_2"value="value_2"/>
  4. </properties>
  5. <environments
    default="development">
  6. <environmentid="development">
  7. <transactionManagertype="JDBC"/>
  8. <dataSourcetype="POOLED">
  9. <propertyname="driver"value="${mysql.driver}"/>
  10. <propertyname="url"value="${mysql.url}"/>
  11. <propertyname="username"value="${mysql.username}"/>
  12. <propertyname="password"
    value="${mysql.password}"/>
  13. </dataSource>
  14. </environment>
  15. </environments>
    在元素properties中也可以定義屬性。2.使用程式碼載入屬性    屬性也可以被傳遞到 SqlSessionBuilder.build()方法中。例如:
  1. SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, props);
  2. // ... or ...
  3. SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment, props);
    使用這種方法可以使用加密的屬性檔案!在不想讓使用者開啟config.properties檔案就知道使用者名稱密碼時,對使用者名稱密碼加密特別有用。3.屬性的載入順序如果屬性在不只一個地方進行了配置,那麼 MyBatis 將按照下面的順序來載入:
  1. 在 properties元素體內指定的屬性首先被讀取。
  2. 然後根據properties元素中的resource屬性讀取類路徑下屬性檔案或根據url屬性指定的路徑讀取屬性檔案,並覆蓋已讀取的同名屬性。
  3. 最後讀取作為方法引數傳遞的屬性,並覆蓋已讀取的同名屬性。
因此,通過方法引數傳遞的屬性具有最高優先順序,resource/url屬性中指定的配置檔案次之,最低優先順序的是properties屬性中指定的屬性。

2.settings 設定

1.settings配置說明    settings配置是MyBatis的全域性配置引數,全域性引數的修改將會影響MyBatis的執行行為。MyBatis會自動進行效能優化。下表描述了設定中各項的意圖、預設值等:
設定引數描述有效值預設值
cacheEnabled 該配置影響的所有對映器中配置的快取的全域性開關。 true | false true
lazyLoadingEnabled 延遲載入的全域性開關。當開啟時,所有關聯物件都會延遲載入。 特定關聯關係中可通過設定fetchType屬性來覆蓋該項的開關狀態。 true | false false
aggressiveLazyLoading 當啟用時,對任意延遲屬性的呼叫會使帶有延遲載入屬性的物件完整載入;反之,每種屬性將會按需載入。 true | false true
multipleResultSetsEnabled 是否允許單一語句返回多結果集(需要相容驅動)。 true | false true
useColumnLabel 使用列標籤代替列名。不同的驅動在這方面會有不同的表現, 具體可參考相關驅動文件或通過測試這兩種不同的模式來觀察所用驅動的結果。 true | false true
useGeneratedKeys 允許 JDBC 支援自動生成主鍵,需要驅動相容。 如果設定為 true 則這個設定強制使用自動生成主鍵,儘管一些驅動不能相容但仍可正常工作(比如 Derby)。 true | false False
autoMappingBehavior 指定 MyBatis 應如何自動對映列到欄位或屬性。 NONE 表示取消自動對映;PARTIAL 只會自動對映沒有定義巢狀結果集對映的結果集。 FULL 會自動對映任意複雜的結果集(無論是否巢狀)。 NONE, PARTIAL, FULL PARTIAL
defaultExecutorType 配置預設的執行器。SIMPLE 就是普通的執行器;REUSE 執行器會重用預處理語句(prepared statements); BATCH 執行器將重用語句並執行批量更新。 SIMPLE REUSE BATCH SIMPLE
defaultStatementTimeout 設定超時時間,它決定驅動等待資料庫響應的秒數。 Any positive integer Not Set (null)
defaultFetchSize Sets the driver a hint as to control fetching size for return results. This parameter value can be override by a query setting. Any positive integer Not Set (null)
safeRowBoundsEnabled 允許在巢狀語句中使用分頁(RowBounds)。 true | false False
mapUnderscoreToCamelCase 是否開啟自動駝峰命名規則(camel case)對映,即從經典資料庫列名 A_COLUMN 到經典 Java 屬性名 aColumn 的類似對映。 true | false False
localCacheScope MyBatis 利用本地快取機制(Local Cache)防止迴圈引用(circular references)和加速重複巢狀查詢。 預設值為 SESSION,這種情況下會快取一個會話中執行的所有查詢。 若設定值為 STATEMENT,本地會話僅用在語句執行上,對相同 SqlSession 的不同調用將不會共享資料。 SESSION | STATEMENT SESSION
jdbcTypeForNull 當沒有為引數提供特定的 JDBC 型別時,為空值指定 JDBC 型別。 某些驅動需要指定列的 JDBC 型別,多數情況直接用一般型別即可,比如 NULL、VARCHAR 或 OTHER。 JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER OTHER
lazyLoadTriggerMethods 指定哪個物件的方法觸發一次延遲載入。 A method name list separated by commas equals,clone,hashCode,toString
defaultScriptingLanguage 指定動態 SQL 生成的預設語言。 A type alias or fully qualified class name. org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver
callSettersOnNulls 指定當結果集中值為 null 的時候是否呼叫對映物件的 setter(map 物件時為 put)方法,這對於有 Map.keySet() 依賴或 null 值初始化的時候是有用的。注意基本型別(int、boolean等)是不能設定成 null 的。 true | false false
logPrefix 指定 MyBatis 增加到日誌名稱的字首。 Any String Not set
logImpl 指定 MyBatis 所用日誌的具體實現,未指定時將自動查詢。 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING Not set
proxyFactory 指定 Mybatis 建立具有延遲載入能力的物件所用到的代理工具。 CGLIB | JAVASSIST JAVASSIST (MyBatis 3.3 or above)
vfsImpl Specifies VFS implementations Fully qualified class names of custom VFS implementation separated by commas. Not set
2.settings配置示例settings配置在mybatis-config.xml檔案中,一個配置完整的 settings 元素的示例如下: 
  1. <settings>
  2. <settingname="cacheEnabled"value="true"/>
  3. <settingname="lazyLoadingEnabled"value="true"/>
  4. <settingname="multipleResultSetsEnabled"value="true"/>
  5. <settingname="useColumnLabel"value="true"/>
  6. <settingname="useGeneratedKeys"value="false"/>
  7. <settingname="autoMappingBehavior"value="PARTIAL"/>
  8. <settingname="defaultExecutorType"value="SIMPLE"/>
  9. <settingname="defaultStatementTimeout"value="25"/>
  10. <settingname="defaultFetchSize"value="100"/>
  11. <settingname="safeRowBoundsEnabled"value="false"/>
  12. <settingname="mapUnderscoreToCamelCase"value="false"/>
  13. <settingname="localCacheScope"value="SESSION"/>
  14. <settingname="jdbcTypeForNull"value="OTHER"/>
  15. <settingname="lazyLoadTriggerMethods"value="equals,clone,hashCode,toString"/>
  16. </settings>

3.typeAliases 型別命名

1.MyBatis設定別名類型別名是為Java型別設定一個短的名字。它只和XML配置有關,存在的意義僅在於用來減少類完全限定名的冗餘。別名的設定可以通過配置檔案或註解來定義。通過配置檔案配置如下:(取自mybatis-config.xml檔案)
  1. <typeAliases>
  2. <typeAliasalias="Author"type="domain.blog.Author"/>
  3. <typeAliasalias="Blog"type="domain.blog.Blog"/>
  4. <typeAliasalias="Comment"type="domain.blog.Comment"/>
  5. <typeAliasalias="Section"type="domain.blog.Section"/>
  6. </typeAliases>
當這樣配置時,Blog可以用在任何使用domain.blog.Blog的地方。也可以指定一個包名,MyBatis會在包名下面搜尋需要的Java Bean,比如: 
  1. <typeAliases>
  2. <packagename="domain.blog"/>
  3. </typeAliases>
每一個在包domain.blog中的Java Bean,在沒有註解的情況下,會使用Bean的首字母小寫的非限定類名來作為它的別名。 比如domain.blog.Author的別名為author;若有註解,則別名為其註解值。看下面的例子:
  1. @Alias("author")
  2. publicclassAuthor{
  3. ...
  4. }
2.MyBatis內建的別名定義說明Mybatis已經為許多常見的 Java 型別內建了相應的類型別名。它們都是大小寫不敏感的,需要注意的是由基本型別名稱重複導致的特殊處理。參考如下表格:
  1. 別名對映的型別
  2. _byte byte
  3. _long long
  4. _short short
  5. _int int
  6. _integer int
  7. _double double
  8. _float float
  9. _boolean boolean
  10. string String
  11. byteByte
  12. longLong
  13. shortShort
  14. intInteger
  15. integer Integer
  16. doubleDouble
  17. floatFloat
  18. booleanBoolean
  19. date Date
  20. decimal BigDecimal
  21. bigdecimal BigDecimal
  22. object Object
  23. map Map
  24. hashmap HashMap
  25. list List
  26. arraylist ArrayList
  27. collection Collection
  28. iterator Iterator

4.typeHandlers 型別處理器

1.typeHandlers介紹無論是MyBatis在預處理語句(PreparedStatement)中設定一個引數時,還是從結果集中取出一個值時,都會用型別處理器將獲取的值以合適的方式轉換成Java型別。型別處理器就是把java型別轉成資料庫型別,把資料庫型別轉成java型別。下表描述了一些預設的型別處理器:
型別處理器 Java 型別 JDBC 型別
BooleanTypeHandlerjava.lang.Boolean, boolean 資料庫相容的 BOOLEAN
ByteTypeHandlerjava.lang.Byte, byte 資料庫相容的 NUMERICBYTE
ShortTypeHandlerjava.lang.Short, short 資料庫相容的 NUMERICSHORT INTEGER
IntegerTypeHandlerjava.lang.Integer, int 資料庫相容的 NUMERICINTEGER
LongTypeHandlerjava.lang.Long, long 資料庫相容的 NUMERICLONG INTEGER
FloatTypeHandlerjava.lang.Float, float 資料庫相容的 NUMERICFLOAT
DoubleTypeHandlerjava.lang.Double, double 資料庫相容的 NUMERICDOUBLE
BigDecimalTypeHandlerjava.math.BigDecimal 資料庫相容的 NUMERICDECIMAL
StringTypeHandlerjava.lang.StringCHAR, VARCHAR
ClobTypeHandlerjava.lang.StringCLOB, LONGVARCHAR
NStringTypeHandlerjava.lang.StringNVARCHAR, NCHAR
NClobTypeHandlerjava.lang.StringNCLOB
ByteArrayTypeHandlerbyte[] 資料庫相容的位元組流型別
BlobTypeHandlerbyte[]BLOB, LONGVARBINARY
DateTypeHandlerjava.util.DateTIMESTAMP
DateOnlyTypeHandlerjava.util.DateDATE
TimeOnlyTypeHandlerjava.util.DateTIME
SqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMP
SqlDateTypeHandlerjava.sql.DateDATE
SqlTimeTypeHandlerjava.sql.TimeTIME
ObjectTypeHandler Any OTHER 或未指定型別
EnumTypeHandler Enumeration Type VARCHAR-任何相容的字串型別,儲存列舉的名稱(而不是索引)
EnumOrdinalTypeHandler Enumeration Type 任何相容的 NUMERICDOUBLE 型別,儲存列舉的索引(而不是名稱)。               
你可以重寫型別處理器或建立你自己的型別處理器來處理不支援的或非標準的型別。 具體做法為:實現 org.apache.ibatis.type.TypeHandler 介面, 或繼承一個很便利的類 org.apache.ibatis.type.BaseTypeHandler, 然後可以選擇性地將它對映到一個 JDBC 型別。比如: 
  1. @MappedJdbcTypes(JdbcType.VARCHAR)
  2. publicclassExampleTypeHandlerextendsBaseTypeHandler<String>
  3. {
  4. @Override
  5. publicvoid setNonNullParameter(PreparedStatement ps,int i,String parameter,JdbcType jdbcType)throwsSQLException
  6. {
  7. ps.setString(i, parameter);
  8. }
  9. @Override
  10. publicString getNullableResult(ResultSet rs,String columnName)throwsSQLException
  11. {
  12. return rs.getString(columnName);
  13. }
  14. @Override
  15. publicString getNullableResult(ResultSet rs,int columnIndex)throwsSQLException
  16. {
  17. return rs.getString(columnIndex);
  18. }
  19. @Override
  20. publicString getNullableResult(CallableStatement cs,int columnIndex)throwsSQLException
  21. {
  22. return cs.getString(columnIndex);
  23. }
  24. }
在配置檔案mybatis-config.xml中配置自定義的型別處理器如下:
  1. <typeHandlers>
  2. <typeHandlerhandler="org.mybatis.example.ExampleTypeHandler"/>
  3. </typeHandlers>
使用這個的型別處理器將會覆蓋已經存在的處理 Java 的 String 型別屬性和 VARCHAR 引數及結果的型別處理器。 要注意 MyBatis 不會窺探資料庫元資訊來決定使用哪種型別,所以你必須在引數和結果對映中指明那是 VARCHAR 型別的欄位, 以使其能夠繫結到正確的型別處理器上。 這是因為:MyBatis 直到語句被執行才清楚資料型別    在設定型別處理器時也可以使用掃描包的方式,在配置檔案mybatis-config.xml中如下配置:
  1. <typeHandlers>
  2. <packagename="org.mybatis.example"/>
  3. </typeHandlers>
    注意:使用掃描包的方式註冊型別處理器時,只能通過註解方式來指定 JDBC 的型別。2.設定型別處理器轉換型別方法通過型別處理器的泛型,MyBatis 可以得知該型別處理器處理的 Java 型別,不過這種行為可以通過兩種方法改變:
  1. 在型別處理器的配置元素(typeHandler element)上增加一個 javaType 屬性(比如:javaType="String")
  2. 在型別處理器的類上(TypeHandler class)增加一個 @MappedTypes 註解來指定與其關聯的 Java 型別列表。 如果在 javaType 屬性中也同時指定,則註解方式將被忽略。
可以通過兩種方式來指定被關聯的 JDBC 型別:
  1. 在型別處理器的配置元素上增加一個 javaType 屬性(比如:javaType="VARCHAR")
  2. 在型別處理器的類上(TypeHandler class)增加一個 @MappedJdbcTypes 註解來指定與其關聯的 JDBC 型別列表。 如果在 javaType 屬性中也同時指定,則註解方式將被忽略。
3.處理列舉型別    你能建立一個泛型型別處理器,它可以處理多於一個類。為達到此目的, 需要增加一個接收該類作為引數的構造器,這樣在構造一個型別處理器的時候 MyBatis 就會傳入一個具體的類。
  1. publicclassGenericTypeHandler<E extendsMyObject>extendsBaseTypeHandler<E>{
  2. privateClass<E> type;
  3. publicGenericTypeHandler(Class<E> type){
  4. if(type ==null)thrownewIllegalArgumentException("Type argument cannot be null");
  5. this.type = type;
  6. }
  7. ...
EnumTypeHandler 和 EnumOrdinalTypeHandler 都是泛型型別處理器(generic TypeHandlers), 我們將會在接下來的部分詳細探討。若想對映列舉型別 Enum,則需要從 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中選一個來使用。比如說我們想儲存取近似值時用到的舍入模式。預設情況下,MyBatis 會利用 EnumTypeHandler 來把 Enum 值轉換成對應的名字。注意:EnumTypeHandler 在某種意義上來說是比較特別的,其他的處理器只針對某個特定的類,而它不同,它會處理任意繼承了 Enum 的類。
不過,我們可能不想在資料庫中儲存列舉的名字,相反我們的 DBA 會堅持使用整形值程式碼。這樣做一樣輕而易舉:在配置檔案中把 EnumOrdinalTypeHandler 加到 typeHandlers 中即可, 這樣每個 RoundingMode 將通過他們的序數值來對映成對應的整形。
  1. <!-- mybatis-config.xml -->
  2. <typeHandlers>
  3. <typeHandlerhandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"javaType="java.math.RoundingMode"/>
  4. </typeHandlers>
但是怎樣能將同樣的 Enum 既對映成字串又對映成整形呢?自動對映器(auto-mapper)會自動地選用 EnumOrdinalTypeHandler 來處理, 所以如果我們想用普通的 EnumTypeHandler,就非要為那些 SQL 語句顯式地設定要用到的型別處理器不可。
  1. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  2. <mappernamespace="org.apache.ibatis.submitted.rounding.Mapper">
  3. <resultMaptype="org.apache.ibatis.submitted.rounding.User"id="usermap">
  4. <idcolumn="id"property="id"/>
  5. <resultcolumn="name"property="name"/>