# MyBatis配置

MyBatis配置

目標:MyBatis官網 https://mybatis.org/mybatis-3/zh/configuration.html

  1. 掌握properties 元素的用法

  2. 掌握setting 元素的用法

  3. 掌握typeAliases 的用法

  4. 重點掌握typeHandler在Mybatis中的用法

  5. 了解ObjectFactory的作用

  6. 了解environments 的配置

  7. 了解databaseIdProvider 的用法

  8. 掌握如何有效引入映射器

概述

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n22" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties></properties>
<setting></setting>
<typeAliases>
<typeAlias alias="role" type="com.zw.pojo.Role"/>
</typeAliases>
<typeHandler></typeHandler>
<ObjectFactory></ObjectFactory>
<plugins></plugins>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/chapter3"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<databaseIdProvider></databaseIdProvider>

<mappers>
<mapper resource="com/zw/mapper/RoleMapper.xml"/>

</mappers>
</configuration>
</pre>

properties 屬性

properties 屬性可以給系統配置一些運行參數缰盏,可以放在xml文件或者properties文件中滑凉,而不是java代碼中。

優(yōu)點:方便參數修改昵济,而不引起代碼重新編譯

Mybatis提供3種方式使用properties:

  • propertie子元素

  • properties文件

  • 程序代碼傳遞

propertie子元素

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n35" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties></properties>
<setting></setting>
<typeAliases>
<typeAlias alias="role" type="com.zw.pojo.Role"/>
</typeAliases>
<typeHandler></typeHandler>
<ObjectFactory></ObjectFactory>
<plugins></plugins>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/chapter3"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<databaseIdProvider></databaseIdProvider>

<mappers>
<mapper resource="com/zw/mapper/RoleMapper.xml"/>

</mappers>
</configuration>

</pre>

properti

es文件

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n39" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties">

</properties>
<typeAliases>

<package name="com.learn.ssm.chapter4.pojo" />
</typeAliases>
<typeHandlers>

<package name="com.learn.ssm.chapter4.typehandler" />

</typeHandlers>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource
type="com.learn.ssm.chapter4.datasource.DbcpDataSourceFactory">
<property name="driver" value="{database.driver}" /> <property name="url" value="{database.url}" />
<property name="username" value="{database.username}" /> <property name="password" value="{database.password}" />
</dataSource>
</environment>
</environments>

<databaseIdProvider
type="com.learn.ssm.chapter4.databaseidprovider.MyDatabaseIdProvider">
<property name="msg" value="自定義DatabaseIdProvider" />
</databaseIdProvider>
<mappers>
<package name="com.learn.ssm.chapter4.mapper" />
</mappers>
</configuration></pre>

properties

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="properties" cid="n41" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/chapter4
database.username=root
database.password=123456</pre>

程序代碼傳遞

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n43" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">public static SqlSessionFactory getSqlSessionFactory() {
synchronized (LOCK) {
if (sqlSessionFactory != null) {
return sqlSessionFactory;
}
String resource = "mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);

//采用程序傳遞加密參數,啟用它之前,修改用戶密碼為密文,可參考main方法......
// InputStream in = Resources.getResourceAsStream("jdbc.properties");
// Properties props = new Properties();
// props.load(in);
// String username = props.getProperty("database.username");
// String password = props.getProperty("database.password");
// // 解密用戶和密碼奇昙,并在屬性中重置
// props.put("database.username", CodeUtils.decode(username));
// props.put("database.password", CodeUtils.decode(password));
// inputStream = Resources.getResourceAsStream(resource);
// // 使用程序傳遞的方式覆蓋原有的properties屬性參數
// sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, props);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return sqlSessionFactory;
}
}</pre>

總結:Mybatis使用properties用36種方式,優(yōu)先級:properey--》 properties文件--》程式傳遞

setting 元素

setting是MyBatis中最復雜的配置才顿,它能深刻影響MyBatis底層運行恩商,但部分使用默認方式即可。

一般使用:自動映射贝搁,駝峰影視吗氏,級聯映射,是否啟動緩存雷逆,執(zhí)行器類型弦讽。

這是 MyBatis 中極為重要的調整設置,它們會改變 MyBatis 的運行時行為膀哲。 下表描述了設置中各項設置的含義坦袍、默認值等。

設置名 描述 有效值 默認值
cacheEnabled 全局性地開啟或關閉所有映射器配置文件中已配置的任何緩存等太。 true false true
lazyLoadingEnabled 延遲加載的全局開關捂齐。當開啟時,所有關聯對象都會延遲加載缩抡。 特定關聯關系中可通過設置 fetchType 屬性來覆蓋該項的開關狀態(tài)奠宜。 true false false
aggressiveLazyLoading 開啟時,任一方法的調用都會加載該對象的所有延遲加載屬性瞻想。 否則压真,每個延遲加載屬性會按需加載(參考 lazyLoadTriggerMethods)。 true false false (在 3.4.1 及之前的版本中默認為 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
autoMappingUnknownColumnBehavior 指定發(fā)現自動映射目標未知列(或未知屬性類型)的行為。NONE: 不做任何反應WARNING: 輸出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等級必須設置為 WARNFAILING: 映射失敗 (拋出 SqlSessionException) NONE, WARNING, FAILING NONE
defaultExecutorType 配置默認的執(zhí)行器啤斗。SIMPLE 就是普通的執(zhí)行器表箭;REUSE 執(zhí)行器會重用預處理語句(PreparedStatement); BATCH 執(zhí)行器不僅重用語句還會執(zhí)行批量更新争占。 SIMPLE REUSE BATCH SIMPLE
defaultStatementTimeout 設置超時時間燃逻,它決定數據庫驅動等待數據庫響應的秒數。 任意正整數 未設置 (null)
defaultFetchSize 為驅動的結果集獲取數量(fetchSize)設置一個建議值臂痕。此參數只可以在查詢設置中被覆蓋伯襟。 任意正整數 未設置 (null)
defaultResultSetType 指定語句默認的滾動策略。(新增于 3.5.2) FORWARD_ONLY SCROLL_SENSITIVE SCROLL_INSENSITIVE DEFAULT(等同于未設置) 未設置 (null)
safeRowBoundsEnabled 是否允許在嵌套語句中使用分頁(RowBounds)握童。如果允許使用則設置為 false姆怪。 true false False
safeResultHandlerEnabled 是否允許在嵌套語句中使用結果處理器(ResultHandler)。如果允許使用則設置為 false澡绩。 true false True
mapUnderscoreToCamelCase 是否開啟駝峰命名自動映射稽揭,即從經典數據庫列名 A_COLUMN 映射到經典 Java 屬性名 aColumn。 true false False
localCacheScope MyBatis 利用本地緩存機制(Local Cache)防止循環(huán)引用和加速重復的嵌套查詢肥卡。 默認值為 SESSION溪掀,會緩存一個會話中執(zhí)行的所有查詢。 若設置值為 STATEMENT步鉴,本地緩存將僅用于執(zhí)行語句揪胃,對相同 SqlSession 的不同查詢將不會進行緩存。 SESSION STATEMENT SESSION
jdbcTypeForNull 當沒有為參數指定特定的 JDBC 類型時氛琢,空值的默認 JDBC 類型喊递。 某些數據庫驅動需要指定列的 JDBC 類型,多數情況直接用一般類型即可阳似,比如 NULL骚勘、VARCHAR 或 OTHER。 JdbcType 常量撮奏,常用值:NULL俏讹、VARCHAR 或 OTHER。 OTHER
lazyLoadTriggerMethods 指定對象的哪些方法觸發(fā)一次延遲加載挽荡。 用逗號分隔的方法列表藐石。 equals,clone,hashCode,toString
defaultScriptingLanguage 指定動態(tài) SQL 生成使用的默認腳本語言。 一個類型別名或全限定類名定拟。 org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
defaultEnumTypeHandler 指定 Enum 使用的默認 TypeHandler 。(新增于 3.4.5) 一個類型別名或全限定類名。 org.apache.ibatis.type.EnumTypeHandler
callSettersOnNulls 指定當結果集中值為 null 的時候是否調用映射對象的 setter(map 對象時為 put)方法青自,這在依賴于 Map.keySet() 或 null 值進行初始化時比較有用株依。注意基本類型(int、boolean 等)是不能設置成 null 的延窜。 true false false
returnInstanceForEmptyRow 當返回行的所有列都是空時恋腕,MyBatis默認返回 null。 當開啟這個設置時逆瑞,MyBatis會返回一個空實例荠藤。 請注意,它也適用于嵌套的結果集(如集合或關聯)获高。(新增于 3.4.2) true false false
logPrefix 指定 MyBatis 增加到日志名稱的前綴哈肖。 任何字符串 未設置
logImpl 指定 MyBatis 所用日志的具體實現,未指定時將自動查找念秧。 SLF4J LOG4J LOG4J2 JDK_LOGGING COMMONS_LOGGING STDOUT_LOGGING NO_LOGGING 未設置
proxyFactory 指定 Mybatis 創(chuàng)建可延遲加載對象所用到的代理工具淤井。 CGLIB JAVASSIST JAVASSIST (MyBatis 3.3 以上)
vfsImpl 指定 VFS 的實現 自定義 VFS 的實現的類全限定名,以逗號分隔摊趾。 未設置
useActualParamName 允許使用方法簽名中的名稱作為語句參數名稱币狠。 為了使用該特性,你的項目必須采用 Java 8 編譯砾层,并且加上 -parameters 選項漩绵。(新增于 3.4.1) true false true
configurationFactory 指定一個提供 Configuration 實例的類。 這個被返回的 Configuration 實例用來加載被反序列化對象的延遲加載屬性值肛炮。 這個類必須包含一個簽名為static Configuration getConfiguration() 的方法止吐。(新增于 3.2.3) 一個類型別名或完全限定類名。 未設置
shrinkWhitespacesInSql 從SQL中刪除多余的空格字符铸董。請注意祟印,這也會影響SQL中的文字字符串。 (新增于 3.5.5) true false false
defaultSqlProviderType Specifies an sql provider class that holds provider method (Since 3.5.6). This class apply to the type(or value) attribute on sql provider annotation(e.g. @SelectProvider), when these attribute was omitted. A type alias or fully qualified class name Not set

一個配置完整的 settings 元素的示例如下:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n207" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings></pre>

類型別名(typeAliases)

類型別名可為 Java 類型設置一個縮寫名字粟害。 它僅用于 XML 配置蕴忆,意在降低冗余的全限定類名書寫。例如:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n211" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases></pre>

當這樣配置時悲幅,Blog 可以用在任何使用 domain.blog.Blog 的地方套鹅。

也可以指定一個包名,MyBatis 會在包名下面搜索需要的 Java Bean汰具,比如:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n214" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><typeAliases>
<package name="domain.blog"/>
</typeAliases></pre>

每一個在包 domain.blog 中的 Java Bean卓鹿,在沒有注解的情況下,會使用 Bean 的首字母小寫的非限定類名來作為它的別名留荔。 比如 domain.blog.Author 的別名為 author吟孙;若有注解,則別名為其注解值。見下面的例子:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n216" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">@Alias("author")
public class Author {
...
}</pre>

下面是一些為常見的 Java 類型內建的類型別名杰妓。它們都是不區(qū)分大小寫的藻治,注意,為了應對原始類型的命名重復巷挥,采取了特殊的命名風格桩卵。

別名 映射的類型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

類型處理器(typeHandlers)

MyBatis 在設置預處理語句(PreparedStatement)中的參數或從結果集中取出一個值時, 都會用類型處理器將獲取到的值以合適的方式轉換成 Java 類型倍宾。下表描述了一些默認的類型處理器雏节。

提示 從 3.4.5 開始,MyBatis 默認支持 JSR-310(日期和時間 API) 高职。

類型處理器 Java 類型 JDBC 類型
BooleanTypeHandler java.lang.Boolean, boolean 數據庫兼容的 BOOLEAN
ByteTypeHandler java.lang.Byte, byte 數據庫兼容的 NUMERICBYTE
ShortTypeHandler java.lang.Short, short 數據庫兼容的 NUMERICSMALLINT
IntegerTypeHandler java.lang.Integer, int 數據庫兼容的 NUMERICINTEGER
LongTypeHandler java.lang.Long, long 數據庫兼容的 NUMERICBIGINT
FloatTypeHandler java.lang.Float, float 數據庫兼容的 NUMERICFLOAT
DoubleTypeHandler java.lang.Double, double 數據庫兼容的 NUMERICDOUBLE
BigDecimalTypeHandler java.math.BigDecimal 數據庫兼容的 NUMERICDECIMAL
StringTypeHandler java.lang.String CHAR, VARCHAR
ClobReaderTypeHandler java.io.Reader -
ClobTypeHandler java.lang.String CLOB, LONGVARCHAR
NStringTypeHandler java.lang.String NVARCHAR, NCHAR
NClobTypeHandler java.lang.String NCLOB
BlobInputStreamTypeHandler java.io.InputStream -
ByteArrayTypeHandler byte[] 數據庫兼容的字節(jié)流類型
BlobTypeHandler byte[] BLOB, LONGVARBINARY
DateTypeHandler java.util.Date TIMESTAMP
DateOnlyTypeHandler java.util.Date DATE
TimeOnlyTypeHandler java.util.Date TIME
SqlTimestampTypeHandler java.sql.Timestamp TIMESTAMP
SqlDateTypeHandler java.sql.Date DATE
SqlTimeTypeHandler java.sql.Time TIME
ObjectTypeHandler Any OTHER 或未指定類型
EnumTypeHandler Enumeration Type VARCHAR 或任何兼容的字符串類型钩乍,用來存儲枚舉的名稱(而不是索引序數值)
EnumOrdinalTypeHandler Enumeration Type 任何兼容的 NUMERICDOUBLE 類型,用來存儲枚舉的序數值(而不是名稱)初厚。
SqlxmlTypeHandler java.lang.String SQLXML
InstantTypeHandler java.time.Instant TIMESTAMP
LocalDateTimeTypeHandler java.time.LocalDateTime TIMESTAMP
LocalDateTypeHandler java.time.LocalDate DATE
LocalTimeTypeHandler java.time.LocalTime TIME
OffsetDateTimeTypeHandler java.time.OffsetDateTime TIMESTAMP
OffsetTimeTypeHandler java.time.OffsetTime TIME
ZonedDateTimeTypeHandler java.time.ZonedDateTime TIMESTAMP
YearTypeHandler java.time.Year INTEGER
MonthTypeHandler java.time.Month INTEGER
YearMonthTypeHandler java.time.YearMonth VARCHARLONGVARCHAR
JapaneseDateTypeHandler java.time.chrono.JapaneseDate DATE

mybatis-自定義TypeHandler

步驟1:實現TypeHandler接口

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n463" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

/**

  • @author

  • java中的boolean和jdbc中的char之間轉換;true-Y;false-N
    */
    //方式一:
    @MappedJdbcTypes(JdbcType.CHAR)
    @MappedTypes(Boolean.class)
    public class BooleanTypeHandler implements TypeHandler {

    /* (non-Javadoc)

    • @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.ResultSet, java.lang.String)
      */
      @Override
      public Object getResult(ResultSet resultSet, String columnLabel) throws SQLException {
      String str = resultSet.getString(columnLabel);
      Boolean rt = Boolean.FALSE;
      if (str.equalsIgnoreCase("Y")){
      rt = Boolean.TRUE;
      }
      return rt;
      }

    @Override
    public Object getResult(ResultSet resultSet, int columnIndex) throws SQLException {
    String str = resultSet.getString(columnIndex);
    Boolean rt = Boolean.FALSE;
    if (str.equalsIgnoreCase("Y")){
    rt = Boolean.TRUE;
    }
    return rt;
    }

    /* (non-Javadoc)

    • @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.CallableStatement, int)
      */
      @Override
      public Object getResult(CallableStatement arg0, int arg1)
      throws SQLException {
      Boolean b = arg0.getBoolean(arg1);
      return b == true ? "Y" : "N";
      }

    /* (non-Javadoc)

    • @see org.apache.ibatis.type.TypeHandler#setParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)
      */
      @Override
      public void setParameter(PreparedStatement arg0, int arg1, Object arg2,
      JdbcType arg3) throws SQLException {
      Boolean b = (Boolean) arg2;
      String value = (Boolean) b == true ? "Y" : "N";
      arg0.setString(arg1, value);
      }
      } </pre>

步驟2:在Mybatis配置中注冊該TypeHandler

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n466" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:dao/mapper/*.xml"></property>
<property name="typeHandlers" >
<array>
<bean class="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" />
</array>
</property>
<property name="plugins">
<array>
<bean class="com.sankuai.travel.csc.test.dao.interceptor.SqlMonitorInterceptor" />
</array>
</property>
</bean></pre>

步驟3:在映射配置文件中使用該TypeHander(如果第一步使用了注解件蚕,此處可以省略)

3.1在resultMap的定義中對對應列定義typeHandler

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n470" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><resultMap id="BaseResultMap" type="com.sankuai.travel.csc.test.dao.domain.CategoryDO" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="category_type" property="categoryType" jdbcType="INTEGER" />
<result column="category_name" property="categoryName" jdbcType="VARCHAR" />
<result column="allocate_time" property="allocateTime" jdbcType="INTEGER" />
<result column="promise_time" property="promiseTime" jdbcType="INTEGER" />
<result column="last_operator" property="lastOperator" jdbcType="VARCHAR" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />

<!--寫在這里,僅對select語句有效产禾,typeHandler="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" -->
<result column="is_cancel" property="isCancel" jdbcType="CHAR" typeHandler="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler"/>

<result column="status1" property="status1" jdbcType="CHAR" />
<result column="status2" property="status2" jdbcType="CHAR" />
<result column="phone_list" property="phoneList" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />

</resultMap></pre>

這里只能是在select的時候才會使用自定義的TypeHandler處理對應的映射關系排作,如果要在insert或者update時使用則需要在sql定義中添加相應的內容

3.2在resultMap的定義中對對應列定義typeHandler

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n474" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><insert id="insert" parameterType="com.sankuai.travel.csc.test.dao.domain.CategoryDO" >
<selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER" >
SELECT LAST_INSERT_ID()
</selectKey>
insert into hotel_order_category (category_type, category_name, allocate_time,
promise_time, last_operator, update_time,
is_cancel, status1, status2,
phone_list, create_time)
values (#{categoryType,jdbcType=INTEGER}, #{categoryName,jdbcType=VARCHAR}, #{allocateTime,jdbcType=INTEGER},
#{promiseTime,jdbcType=INTEGER}, #{lastOperator,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP},

#{isCancel,jdbcType=CHAR,typeHandler=com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler},
#{status1,jdbcType=CHAR}, #{status2,jdbcType=CHAR},
#{phoneList,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP})
</insert></pre>

#mybatis-enumtypehandler和enumordinaltypehandler的區(qū)別

mybatis對枚舉類型提供了兩種類型支持:EnumTypeHandler和EnumOrdinalTypeHandler。

  • EnumTypeHandler是mybatis默認的枚舉類型轉換器亚情,如果pojo類中使用了枚舉類型妄痪,而配置文件沒有指定類型轉換類,mybatis將使用EnumTypeHandler處理枚舉屬性楞件。EnumTypeHandler的將把枚舉類的name進行存儲衫生,枚舉類的name即枚舉類名。參考:http://mybatis.github.io/mybatis-3/zh/configuration.html

  • EnumOrdinalTypeHandler是mybatis提供的另一種轉換器土浸,顧名思義這個轉換類使用了枚舉類的ordinal屬性作為數據庫存儲信息罪针,由于ordinal屬性是int類型的,按照官網的說明數據庫中對應資源應該是int或double類型的黄伊,但是個人測試過程中MYSQL的varchar字段也可以存儲泪酱。

  • 總結:EnumTypeHandler和EnumOrdinalTypeHandler的區(qū)別主要是數據庫中存儲字段的類型差別,由于EnumOrdinalTypeHandler使用枚舉類型的ordinal作為存儲还最,所以必須使用數字類型字段存儲墓阀。

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n486" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:dao/mapper/*.xml"></property>
<property name="typeHandlers" >
<array>
<bean class="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" />
<bean class="com.sankuai.travel.csc.test.dao.typehandler.StringArrayTypeHandler" />

<bean class="org.apache.ibatis.type.EnumTypeHandler" >
<constructor-arg name="type" value="com.sankuai.travel.csc.test.enums.SimpleStatusEnum" />
</bean>

<bean class="org.apache.ibatis.type.EnumOrdinalTypeHandler" >
<constructor-arg name="type" value="com.sankuai.travel.csc.test.enums.SimpleStatusEnum" />
</bean>
</array>
</property>
<property name="plugins">
<array>
<bean class="com.sankuai.travel.csc.test.dao.interceptor.SqlMonitorInterceptor" />
</array>
</property>
</bean></pre>

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n488" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><resultMap id="BaseResultMap" type="com.sankuai.travel.csc.test.dao.domain.CategoryDO" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="category_type" property="categoryType" jdbcType="INTEGER" />
<result column="category_name" property="categoryName" jdbcType="VARCHAR" />
<result column="allocate_time" property="allocateTime" jdbcType="INTEGER" />
<result column="promise_time" property="promiseTime" jdbcType="INTEGER" />
<result column="last_operator" property="lastOperator" jdbcType="VARCHAR" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />

<!--方式二:寫在這里,僅對select語句有效拓轻,typeHandler="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" -->
<result column="is_cancel" property="isCancel" jdbcType="CHAR" />


<result column="status1" property="status1" jdbcType="CHAR" />

<result column="status2" property="status2" jdbcType="CHAR" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
<result column="phone_list" property="phoneList" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" /></pre>

MyBatis中ObjectFactory簡介

MyBatis 每次創(chuàng)建結果對象實例時,它使用一個 ObjectFactory 實例來完成斯撮。默認的ObjectFactory僅會按照配置結果類型的默認構造方法或者指定構造方法來創(chuàng)建對象實例。如果想重寫默認的 ObjectFactory,你可以創(chuàng)建你自己的扶叉。比如:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="jsx" cid="n492" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">// ExampleObjectFactory.java
//自定義的ObjectFactory
public class ExampleObjectFactory extends DefaultObjectFactory {
//使用默認構造方法創(chuàng)建對象實例
public Object create(Class type) {
return super.create(type);
}

//有構造參數列表和構造參數值列表的創(chuàng)建對象實例的方式
public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) {
return super.create(type, constructorArgTypes, constructorArgs);
}

//為自定義ObjectFactory設置配置參數
public void setProperties(Properties properties) {
super.setProperties(properties);
}
}


<objectFactory type="org.mybatis.example.ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory></pre>

ObjectFactory 接口很簡單勿锅。它包含兩個創(chuàng)建用的方法,一個是處理默認構造方法的,另外一個是處理帶參數構造方法的帕膜。最終,setProperties 方法可以被用來配置 ObjectFactory。在 初 始化 你 的 ObjectFactory 實例 后 , objectFactory 元素 體 中定 義的 屬 性會 被傳 遞 給setProperties 方法粱甫。

一個例子: 假設實體對象實現了自定義的InitialEntity接口泳叠,則在創(chuàng)建對象完成之后必須調用InitialEntity接口的init方法:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n496" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">package cd.itcast.mybatis.myobjectfactory;
public interface InitialEntity {
void init();
}</pre>

假設有一個實體StockOutcomeBillItem對象用來記錄銷售出庫單明細作瞄,該對象再設置完值后茶宵,需要調用count()方法來完成總金額的計算:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="kotlin" cid="n499" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">package cd.itcast.mybatis.myobjectfactory;
public class StockOutcomeBillItem {
private Long id;
private Product product;
private Integer number;
private BigDecimal price;
private BigDecimal totalAmount;
//getter & setter
public void count(){
this.totalAmount=this.number*this.price;
}
}</pre>

該對象在實例化完成后需要調用count()方法來完成totalAmount屬性的計算。要完成這個邏輯宗挥,只需要讓該類實現定義的InitialEntity接口即可:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n502" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">package cd.itcast.mybatis.myobjectfactory;
public class StockOutcomeBillItem implements InitialEntity{
private Long id;
//other properties;
//getter & setter
public void init() {
this.count();
}
private void count(){
this.totalAmount=this.number*this.price;
}
}</pre>

接下來乌庶,只需要完成能辨別InitialEntity接口的對象并調用其中的方法即可:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n505" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">package cd.itcast.mybatis.myobjectfactory;
public class InitialObjectFactory extends DefaultObjectFactory {
private static final long serialVersionUID = 1L;
@Override
public <T> T create(Class<T> type) {
return super.create(type);
}

@Override
//注意,在DefaultObjectFactory的create(Class type)方法中調用的是
//create(Class,List<Class> constructorArgTypes,List<Object> constructorArgs)方法契耿,
//所以瞒大,只需要在這個方法中完成自定義初始化邏輯即可。 
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes,List<Object> constructorArgs){ 
    T ret= super.create(type, constructorArgTypes, constructorArgs); 
    //判斷接口類型和執(zhí)行接口方法搪桂。
    if(InitialEntity.class.isAssignableFrom(type)){ 
        InitialEntity entity=(InitialEntity)ret; entity.init(); 
    } 
    return ret; 
}

}</pre>

接下來只需要注冊這個ObjectFactory即可:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n508" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">
<objectFactory type="org.mybatis.example.ExampleObjectFactory"/> </pre>

以上就是mybatis中objectfactory的簡單應用透敌,關于objectfactory更多的實現細節(jié),可以通過閱讀mybatis代碼去研究踢械。

叩丁狼教育關注

MyBatis配置文件environments和子元素transactionManager酗电、dataSource解析

< MyBatis ObjectFactoryMyBatis與Spring的整合步驟 >

Java一對一答疑,幫助有志青年内列!使用QQ在線輔導撵术,哪里不懂問哪里,整個過程都是一對一话瞧,學習更有針對性嫩与。和作者直接交流,不但提升技能交排,還提升 Level划滋;當你決定加入我們,你已然超越了 90% 的程序員埃篓。猛擊這里了解詳情处坪。

在 MyBatis 中,運行環(huán)境主要的作用是配置數據庫信息都许,它可以配置多個數據庫稻薇,一般而言只需要配置其中的一個就可以了。

它下面又分為兩個可配置的元素:事務管理器(transactionManager)胶征、數據源(dataSource)塞椎。

在實際的工作中,大部分情況下會采用 Spring 對數據源和數據庫的事務進行管理睛低,這些我們教程后面都會進行講解案狠。本節(jié)我們會探討 MyBatis 自身實現的類服傍。

運行環(huán)境配置,代碼如下所示骂铁。

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n519" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="{database.driver}" /> <property name="url" value="{database.url}" /> <property name="username" value="{database.username}" /> <property name="password" value="{database.password}" /> </dataSource> </environment></environments></pre>

這里用到兩個元素:transactionManager 和 environment吹零。

transactionManager(事務管理器)

在 MyBatis 中,transactionManager 提供了兩個實現類拉庵,它需要實現接口 Transaction(org.apache.ibatis.transaction.Transaction)灿椅,它的定義代碼如下所示。

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n523" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">public interface Transaction { Connection getConnection() throws SQLException; void commit() throws SQLException; void rollback() throws SQLException; void close() throws SQLException; Integer getTimeout() throws SQLException;}</pre>

從方法可知钞支,它主要的工作就是提交(commit)茫蛹、回滾(rollback)和關閉(close)數據庫的事務。MyBatis 為 Transaction 提供了兩個實現類:JdbcTransaction 和 ManagedTransaction烁挟,如圖 1 所示婴洼。

Transaction的實現類

圖 1 Transaction的實現類

于是它對應著兩種工廠:JdbcTransactionFactory 和 ManagedTransactionFactory,這個工廠需要實現 TransactionFactory 接口撼嗓,通過它們會生成對應的 Transaction 對象柬采。于是可以把事務管理器配置成為以下兩種方式:

<transactionManager type="JDBC"/> <transactionManager type="MANAGED"/>

這里做簡要的說明。

JDBC 使用 JdbcTransactionFactory 生成的 JdbcTransaction 對象實現且警。它是以 JDBC 的方式對數據庫的提交和回滾進行操作粉捻。

MANAGED 使用 ManagedTransactionFactory 生成的 ManagedTransaction 對象實現。它的提交和回滾方法不用任何操作振湾,而是把事務交給容器處理杀迹。在默認情況下,它會關閉連接押搪,然而一些容器并不希望這樣树酪,因此需要將 closeConnection 屬性設置為 false 來阻止它默認的關閉行為。

不想采用 MyBatis 的規(guī)則時大州,我們可以這樣配置:

<transactionManager type="com.mybatis.transaction.MyTransactionFactory"/>

實現一個自定義事務工廠续语,代碼如下所示。

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n534" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">public class MyTransactionFactory implements TransactionFactory {
@Override public void setProperties(Properties props) { } @Override public Transaction newTransaction(Connection conn) {
return new MyTransaction(conn);
}
@Override public Transaction newTransaction(DataSource dataSource, TransactionlsolationLevel level, boolean autoCommit) {
return new MyTransaction(dataSource, level, autoCommit);
}}</pre>

這里就實現了 TransactionFactory 所定義的工廠方法厦画,這個時候還需要事務實現類 MyTransaction疮茄,它用于實現 Transaction 接口,代碼如下所示根暑。

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n536" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">public class MyTransaction extends JdbcTransaction implements Transaction {
public MyTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
super(ds, desiredLevel, desiredAutoCommit);
}
public MyTransaction(Connection connection) {
super(connection);
}
public Connection getConnection() throws SQLException {
return super.getConnection();
}
public void commit() throws SQLException {
super.commit();
}
public void rollback() throws SQLException {
super.rollback();
}
public void close() throws SQLException {
super.close();
}
public Integer getTimeout() throws SQLException {
return super.getTimeout();
}}</pre>

這樣就能夠通過自定義事務規(guī)則力试,滿足特殊的需要了。

environment 數據源環(huán)境

environment 的主要作用是配置數據庫排嫌,在 MyBatis 中畸裳,數據庫通過 PooledDataSource Factory、UnpooledDataSourceFactory 和 JndiDataSourceFactory 三個工廠類來提供淳地,前兩者對應產生 PooledDataSource怖糊、UnpooledDataSource 類對象帅容,而 JndiDataSourceFactory 則會根據 JNDI 的信息拿到外部容器實現的數據庫連接對象。

無論如何這三個工廠類伍伤,最后生成的產品都會是一個實現了 DataSource 接口的數據庫連接對象并徘。

由于存在三種數據源,所以可以按照下面的形式配置它們扰魂。

<dataSource type="UNPOOLED"> <dataSource type="POOLED"> <dataSource type="JNDI">

論述一下這三種數據源及其屬性麦乞。

1. UNPOOLED

UNPOOLED 采用非數據庫池的管理方式,每次請求都會打開一個新的數據庫連接阅爽,所以創(chuàng)建會比較慢路幸。在一些對性能沒有很高要求的場合可以使用它。

對有些數據庫而言付翁,使用連接池并不重要,那么它也是一個比較理想的選擇晃听。UNPOOLED 類型的數據源可以配置以下幾種屬性:

  • driver 數據庫驅動名百侧,比如 MySQL 的 com.mysql.jdbc.Driver。

  • url 連接數據庫的 URL能扒。

  • username 用戶名佣渴。

  • password 密碼。

  • defaultTransactionIsolationLevel 默認的連接事務隔離級別初斑,關于隔離級別辛润,后面教程中會討論挠铲。

傳遞屬性給數據庫驅動也是一個可選項结耀,注意屬性的前綴為“driver.”,例如 driver.encoding=UTF8谭跨。它會通過 DriverManager.getConnection(url,driverProperties)方法傳遞值為 UTF8 的 encoding 屬性給數據庫驅動鹃答。

2. POOLED

數據源 POOLED 利用“池”的概念將 JDBC 的 Connection 對象組織起來乎澄,它開始會有一些空置,并且已經連接好的數據庫連接测摔,所以請求時置济,無須再建立和驗證,省去了創(chuàng)建新的連接實例時所必需的初始化和認證時間锋八。它還控制最大連接數浙于,避免過多的連接導致系統瓶頸。

除了 UNPOOLED 下的屬性外挟纱,會有更多屬性用來配置 POOLED 的數據源羞酗,如表 1 所示:

名稱 說明
poolMaximumActiveConnections 是在任意時間都存在的活動(也就是正在使用)連接數量,默認值為 10
poolMaximumIdleConnections 是任意時間可能存在的空閑連接數
poolMaximumCheckoutTime 在被強制返回之前樊销,池中連接被檢出(checked out)的時間整慎,默認值為 20 000 毫秒(即 20 秒)
poolTimeToWait 是一個底層設置脏款,如果獲取連接花費相當長的時間,它會給連接池打印狀態(tài)日志裤园,并重新嘗試獲取一個連接(避免在誤配置的情況下一直失敵肥Α),默認值為 20 000 毫秒(即 20 秒)拧揽。
poolPingQuery 為發(fā)送到數據庫的偵測查詢剃盾,用來檢驗連接是否處在正常工作秩序中,并準備接受請求淤袜。默認是“NO PING QUERY SET”痒谴,這會導致多數數據庫驅動失敗時帶有一個恰當的錯誤消息。
poolPingEnabled 為是否啟用偵測查詢铡羡。若開啟积蔚,也必須使用一個可執(zhí)行的 SQL 語句設置 poolPingQuery 屬性(最好是一個非常快的 SQL)烦周,默認值為 false尽爆。
poolPingConnectionsNotUsedFor 為配置 poolPingQuery 的使用頻度。這可以被設置成匹配具體的數據庫連接超時時間读慎,來避免不必要的偵測漱贱,默認值為 0(即所有連接每一時刻都被偵測——僅當 poolPingEnabled 為 true 時適用)。

3. JNDI

數據源 JNDI 的實現是為了能在如 EJB 或應用服務器這類容器中使用夭委,容器可以集中或在外部配置數據源幅狮,然后放置一個 JNDI 上下文的引用。這種數據源配置只需要兩個屬性:

1)initial_context

用來在 InitialContext 中尋找上下文(即株灸,initialContext.lookup(initial_context))崇摄。initial_context 是個可選屬性,如果忽略蚂且,那么 data_source 屬性將會直接從 InitialContext 中尋找配猫。

2)data_source

是引用數據源實例位置上下文的路徑。當提供 initial_context 配置時杏死,data_source 會在其返回的上下文中進行查找泵肄;當沒有提供 initial_context 時,data_source 直接在 InitialContext 中查找淑翼。

與其他數據源配置類似腐巢,它可以通過添加前綴“env.”直接把屬性傳遞給初始上下文(InitialContext)。比如 env.encoding=UTF8玄括,就會在初始上下文實例化時往它的構造方法傳遞值為 UTF8 的 encoding 屬性冯丙。

MyBatis 也支持第三方數據源,例如使用 DBCP 數據源遭京,那么需要提供一個自定義的 DataSourceFactory胃惜,代碼如下所示泞莉。

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n596" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">public class DbcpDataSourceFactory implements DataSourceFactory {
private Properties props = null;
public void setProperties(Properties props) {
this.props = props;
}
public DataSource getDataSource() {
DataSource dataSource = null;
dataSource = BasicDataSourceFactory.createDataSource(props);
return dataSource;
}}</pre>

然后進行如下配置:

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n598" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><dataSource type="com.mybatis.dataSource.DbcpDataSourceFactory">
<property name="driver" value="{database.driver}" /> <property name="url" value="{database.url}" />
<property name="username" value="{database.username}" /> <property name="password" value="{database.password}" />
</dataSource></pre>

這樣 MyBatis 就會采用配置的數據源工廠來生成數據源了。

databaseIdProvider 用法

databaseIdProvider 元素主要是支持多種不同廠商的數據庫

<databaseIdProvider
    type="com.learn.ssm.chapter4.databaseidprovider.MyDatabaseIdProvider">
    <property name="msg" value="自定義DatabaseIdProvider" />
</databaseIdProvider></pre>

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n603" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">package com.learn.ssm.chapter4.databaseidprovider;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.log4j.Logger;

public class MyDatabaseIdProvider implements DatabaseIdProvider {

private static final String DATEBASE_TYPE_DB2 = "DB2";
private static final String DATEBASE_TYPE_MYSQL = "MySQL";
private static final String DATEBASE_TYPE_ORACLE = "Oralce";

private Logger log = Logger.getLogger(MyDatabaseIdProvider.class);

@Override
public void setProperties(Properties props) {
    log.info(props);
}

@Override
public String getDatabaseId(DataSource dataSource) throws SQLException {
    Connection connection = dataSource.getConnection();
    String dbProductName = connection.getMetaData().getDatabaseProductName();
    if (MyDatabaseIdProvider.DATEBASE_TYPE_DB2.equals(dbProductName)) {
        return "db2";
    } else if (MyDatabaseIdProvider.DATEBASE_TYPE_MYSQL
            .equals(dbProductName)) {
        return "mysql";
    } else if (MyDatabaseIdProvider.DATEBASE_TYPE_ORACLE
            .equals(dbProductName)) {
        return "oracle";
    } else {
        return null;
    }
}

}
</pre>

有效引入映射器

首先定義接口

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="java" cid="n606" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">package com.learn.ssm.chapter4.mapper;
import java.util.List;
import com.learn.ssm.chapter4.pojo.Role;
public interface RoleMapper {
public int insertRole(Role role);
public int deleteRole(Long id);
public int updateRole(Role role);
public Role getRole(Long id);
public List<Role> findRoles(String roleName);
}</pre>

其次船殉,給出xml

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n608" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.learn.ssm.chapter4.mapper.RoleMapper">

<resultMap id="roleMapper" type="role">
    <result property="id" column="id" />
    <result property="roleName" column="role_name" jdbcType="VARCHAR"
        javaType="string" />
    <result property="note" column="note"
        typeHandler="com.learn.ssm.chapter4.typehandler.MyTypeHandler" />
</resultMap>

<select id="getRole" parameterType="long" resultMap="roleMapper">
    select id, role_name, note from t_role where id = #{id}
</select>

<select id="findRoles" parameterType="string" resultMap="roleMapper">
    select id, role_name, note from t_role
    where role_name like concat('%', #{roleName, jdbcType=VARCHAR,
    javaType=string}, '%')
</select>

<select id="findRoles2" parameterType="string" resultMap="roleMapper">
    select id, role_name, note from t_role
    where note like concat('%', #{note,
    typeHandler=com.learn.ssm.chapter4.typehandler.MyTypeHandler}, '%')
</select>

</mapper></pre>

  1. 用文件路勁引入映射器

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n612" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><mappers>
    <mapper resource="com/learn/ssm/chapter4/mapper/RoleMapper"/>
    </mappers></pre>

  2. 用包名引入引射器

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n615" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"><mappers>
    <package name="com.learn.ssm.chapter4.mapper" />
    </mappers></pre>

    1. 用類注冊引入映射器

      <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n619" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><mappers>
      <mapper class="com.learn.ssm.chapter4.mapper.RoleMapper"/>
      </mappers></pre>

      4.用userMapperxml 引入映射器

      <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="xml" cid="n621" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><mappers>
      <mapper url="file:///Chapter4/src/com/learn/ssm/chapter4/mapper/RoleMapper.xml"/>
      </mappers></pre>

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末鲫趁,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子利虫,更是在濱河造成了極大的恐慌挨厚,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糠惫,死亡現場離奇詭異疫剃,居然都是意外死亡,警方通過查閱死者的電腦和手機硼讽,發(fā)現死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門巢价,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人理郑,你說我怎么就攤上這事蹄溉。” “怎么了您炉?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長役电。 經常有香客問我赚爵,道長,這世上最難降的妖魔是什么法瑟? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任冀膝,我火速辦了婚禮,結果婚禮上霎挟,老公的妹妹穿的比我還像新娘窝剖。我一直安慰自己,他們只是感情好酥夭,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布赐纱。 她就那樣靜靜地躺著,像睡著了一般熬北。 火紅的嫁衣襯著肌膚如雪疙描。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天讶隐,我揣著相機與錄音起胰,去河邊找鬼。 笑死巫延,一個胖子當著我的面吹牛效五,可吹牛的內容都是我干的地消。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼畏妖,長吁一口氣:“原來是場噩夢啊……” “哼脉执!你這毒婦竟也來了?” 一聲冷哼從身側響起瓜客,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤适瓦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谱仪,有當地人在樹林里發(fā)現了一具尸體玻熙,經...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年疯攒,在試婚紗的時候發(fā)現自己被綠了嗦随。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡敬尺,死狀恐怖枚尼,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情砂吞,我是刑警寧澤署恍,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站蜻直,受9級特大地震影響盯质,放射性物質發(fā)生泄漏。R本人自食惡果不足惜概而,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一呼巷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赎瑰,春花似錦王悍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晋辆,卻和暖如春渠脉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓶佳。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工芋膘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓为朋,卻偏偏與公主長得像臂拓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子习寸,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內容

  • 字節(jié)跳動飛書內推胶惰!北京、杭州霞溪、武漢孵滞、廣州、深圳鸯匹、上海坊饶,六大城市等你來投。感興趣的朋友可以私我咨詢&內推殴蓬,也可以通過...
    盧卡斯嗶嗶嗶閱讀 9,847評論 0 4
  • 概要 通篇了解,后期與spring集成 配置連接數據庫的四個元素 注冊實體類的權限定性類名的別名 配置MyBati...
    唯老閱讀 1,740評論 1 0
  • 概要 配置連接數據庫的四個元素注冊實體類的權限定性類名的別名配置MyBatis運行環(huán)境染厅,即數據源與事務管理器注冊映...
    任未然閱讀 685評論 0 0
  • Mybatis配置文件并不復雜痘绎,它的所有元素如下: 需要注意的是,順序不能顛倒肖粮,否則啟動會發(fā)生異常. 1孤页、prop...
    靈臺悠步閱讀 1,588評論 0 0
  • 初始typeHandler 在JDBC中,需要在PreparedStatement對象中設置那些已經預編譯過的SQ...
    最最最最醉人閱讀 3,420評論 0 4