簡介
MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL恭陡、存儲過程以及高級映射蹬音。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數(shù)以及獲取結(jié)果集。MyBatis 可以使用簡單的 XML 或注解來配置和映射原生信息休玩,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數(shù)據(jù)庫中的記錄著淆。
安裝
使用maven構(gòu)建項目,需要在pom文件中引入依賴拴疤。
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
SqlSessionFactory
每個基于 MyBatis 的應用都是以一個 SqlSessionFactory 的實例為中心的永部。SqlSessionFactory 的實例可以通過 SqlSessionFactoryBuilder 獲得。而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個預先定制的 Configuration 的實例構(gòu)建出 SqlSessionFactory 的實例呐矾。
SqlSession
SqlSession 完全包含了面向數(shù)據(jù)庫執(zhí)行 SQL 命令所需的所有方法苔埋。可以通過 SqlSession 實例來直接執(zhí)行已映射的 SQL 語句蜒犯。
SqlSession session = sqlSessionFactory.openSession();
try{
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.findUserByPrimaryKey(1);
}catch{
session.close();
}
在實際開發(fā)過程中组橄,我們會將spring與mybatis進行整合,Spring將會加載SqlSessionFactory類以及SqlSession類愧薛。
XML映射配置文件
在類路徑下的資源文件下創(chuàng)建mybatis-config.xml晨炕,MyBatis 的配置文件包含了會深深影響 MyBatis 行為的設置(settings)和屬性(properties)信息。文檔的頂層結(jié)構(gòu)如下:
mybatis-config.xml格式如下:
<?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>
//進行相應的配置
</configuration>
properties
properties屬性都是可外部配置且可動態(tài)替換的毫炉,既可以在典型的 Java 屬性文件中配置瓮栗,亦可通過 properties 元素的子元素來傳遞。
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
settings
settings是MyBatis 中極為重要的調(diào)整設置,它們會改變 MyBatis 的運行時行為费奸。完整settings配置如下:
<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>
typeHandler
typeAliases是為 Java 類型設置一個短的名字弥激。它只和 XML 配置有關,存在的意義僅在于用來減少類完全限定名的冗余愿阐。例如:
<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>
這樣配置時微服,Blog就可以在在Mapper文件中代替domain.blog.Blog。
也可以指定包名缨历,Mybatis會在相應的包下搜索需要的javaBean以蕴,如下所示
<typeAliases>
<package name="com.jack.pojo.entity"/>
</typeAliases>
每一個在包 domain.blog 中的 Java Bean,在沒有注解的情況下辛孵,會使用 Bean 的首字母小寫的非限定類名來作為它的別名丛肮。 比如 domain.blog.Author 的別名為 author;若有注解魄缚,則別名為其注解值宝与。
無論是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數(shù)時,還是從結(jié)果集中取出一個值時冶匹, 都會用typeHandler將獲取的值以合適的方式轉(zhuǎn)換成 Java 類型习劫。簡而言之,typeHandler的作用就是在javaType-jdbcType相互轉(zhuǎn)化過程嚼隘。Mybatis有許多默認的類型處理器诽里,這些默認的類型處理器包括絕大部分的基礎類型的轉(zhuǎn)化
,已經(jīng)足夠日常開發(fā)嗓蘑,不需要自定義的類型處理器须肆。但是匿乃,當遇到一些特殊情況時桩皿,為了開發(fā)的方便性,我們才需要自定義一些類型轉(zhuǎn)換器幢炸⌒垢簦可以重寫類型處理器或創(chuàng)建你自己的類型處理器來處理不支持的或非標準的類型。 具體做法為:實現(xiàn) org.apache.ibatis.type.TypeHandler 接口宛徊, 或繼承一個很便利的類 org.apache.ibatis.type.BaseTypeHandler佛嬉, 然后可以選擇性地將它映射到一個 JDBC 類型。
objectFactroy
MyBatis 每次創(chuàng)建結(jié)果對象的新實例時闸天,它都會使用一個對象工廠(ObjectFactory)實例來完成暖呕。 默認的對象工廠需要做的僅僅是實例化目標類,要么通過默認構(gòu)造方法苞氮,要么在參數(shù)映射存在的時候通過參數(shù)構(gòu)造方法來實例化湾揽。 如果想覆蓋對象工廠的默認行為,則可以通過創(chuàng)建自己的對象工廠來實現(xiàn)。就個人理解來說库物,這個對象工廠就是用來創(chuàng)建實體類的霸旗,Mybatis有一個DefaultObjectFactory默認對象工廠類,就像上面所說的默認的對象工廠需要做的僅僅是實例化目標實體類戚揭,它不做其他任何處理诱告,如果我們想創(chuàng)建一個目標實體類的時候,想要完成某些功能的話民晒,可以繼承DefaultObjectFactory精居,覆寫父類的方法,并在mybatis-config.xml注冊配置這個工廠類潜必。配置如下:
<objectFactory type="com.lumia.factory.ExampleObjectFactory"/>
plugins
MyBatis 允許你在已映射語句執(zhí)行過程中的某一點進行攔截調(diào)用箱蟆。默認情況下,MyBatis 允許使用插件來攔截的方法調(diào)用包括:
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters
- StatementHandler (prepare, parameterize, batch, update, query)
這些類中方法的細節(jié)可以通過查看每個方法的簽名來發(fā)現(xiàn)刮便,或者直接查看 MyBatis 發(fā)行包中的源代碼空猜。 如果你想做的不僅僅是監(jiān)控方法的調(diào)用,那么你最好相當了解要重寫的方法的行為恨旱。 因為如果在試圖修改或重寫已有方法的行為的時候辈毯,你很可能在破壞 MyBatis 的核心模塊。 這些都是更低層的類和方法搜贤,所以使用插件的時候要特別當心谆沃。
environments
MyBatis 可以配置成適應多種環(huán)境,這種機制有助于將 SQL 映射應用于多種數(shù)據(jù)庫之中仪芒, 現(xiàn)實情況下有多種理由需要這么做唁影。例如,開發(fā)掂名、測試和生產(chǎn)環(huán)境需要有不同的配置据沈;或者共享相同 Schema 的多個生產(chǎn)數(shù)據(jù)庫, 想使用相同的 SQL 映射饺蔑。許多類似的用例锌介。
不過要記住:盡管可以配置多個環(huán)境猾警,每個 SqlSessionFactory 實例只能選擇其一孔祸。所以,如果你想連接兩個數(shù)據(jù)庫发皿,就需要創(chuàng)建兩個 SqlSessionFactory 實例崔慧,每個數(shù)據(jù)庫對應一個。配置如下:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
配置關鍵點:
- 默認的環(huán)境 ID(比如:default="development")穴墅。
- 每個 environment 元素定義的環(huán)境 ID(比如:id="development")惶室。
- 事務管理器的配置(比如:type="JDBC")匣屡。
- 數(shù)據(jù)源的配置(比如:type="POOLED")。
默認的環(huán)境和環(huán)境 ID 是自解釋的拇涤,因此一目了然紫皇。你可以對環(huán)境隨意命名甜奄,但一定要保證默認的環(huán)境 ID 要匹配其中一個環(huán)境 ID。也就是說當前工作的環(huán)境由default來指定。
databaseIdProvider
MyBatis 可以根據(jù)不同的數(shù)據(jù)庫廠商執(zhí)行不同的語句造成,這種多廠商的支持是基于映射語句中的 databaseId 屬性愤诱。 MyBatis 會加載不帶 databaseId 屬性和帶有匹配當前數(shù)據(jù)庫 databaseId 屬性的所有語句占婉。 如果同時找到帶有 databaseId 和不帶 databaseId 的相同語句赃阀,則后者會被舍棄。
在xml映射文件中的select趾痘、insert慢哈、update、delete標簽中可以配置databaseId屬性永票,如果配置了 databaseIdProvider卵贱,MyBatis 會加載所有的不帶 databaseId 或匹配當前 databaseId 的語句;如果帶或者不帶的語句都有侣集,則不帶的會被忽略键俱。配置如下:
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle" />
</databaseIdProvider>
mappers
既然 MyBatis 的行為已經(jīng)由上述元素配置完了,我們現(xiàn)在就要定義 SQL 映射語句了世分。但是首先我們需要告訴 MyBatis 到哪里去找到這些語句编振。 Java 在自動查找這方面沒有提供一個很好的方法,所以最佳的方式是告訴 MyBatis 到哪里去找映射文件臭埋。你可以使用相對于類路徑的資源引用踪央, 或完全限定資源定位符(包括 file:/// 的 URL),或類名和包名等瓢阴。配置如下:
<!-- 使用相對于類路徑的資源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定資源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口實現(xiàn)類的完全限定類名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 將包內(nèi)的映射器接口實現(xiàn)全部注冊為映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>