1.先說resultMap比較容易混淆的點,

2.
高級結果映射
MyBatis的創建基於這樣一個思想:數據庫並不是您想怎樣就怎樣的。雖然我們希望所有的數據庫遵守第三范式或BCNF(修正的第三范式),但它們不是。如果有一個數據庫能夠完美映射到所有應用程序,也將是非常棒的,但也沒有。結果集映射就是MyBatis為解決這些問題而提供的解決方案。
resultMap
·constructor–實例化的時候通過構造器將結果集注入到類中
oidArg– ID 參數; 將結果集標記為ID,以方便全局調用
oarg–注入構造器的結果集
·id–結果集ID,將結果集標記為ID,以方便全局調用
·result–注入一個字段或者javabean屬性的結果
·association–復雜類型聯合;許多查詢結果合成這個類型
o嵌套結果映射– associations能引用自身,或者從其它地方引用,
·collection–復雜類型集合
o嵌套結果映射– collections能引用自身,或者從其它地方引用
·discriminator–使用一個結果值以決定使用哪個resultMap
ocase–基於不同值的結果映射
§嵌套結果映射–case也能引用它自身, 所以也能包含這些同樣的元素。它也可以從外部引用resultMap
注意:
public class A{
private B b1;
private List<B> b2;
}
在映射b1屬性時用association標簽, 映射b2時用collection標簽,分別是一對一,一對多的關系
id, result元素
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
這是最基本的結果集映射。id 和result 將列映射到屬性或簡單的數據類型字段(String, int, double, Date等)。
這兩者唯一不同的是,在比較對象實例時id 作為結果集的標識屬性。這有助於提高總體性能,特別是應用緩存和嵌套結果映射的時候。
Id、result屬性如下:
| Attribute |
Description |
| property |
映射數據庫列的字段或屬性。如果JavaBean 的屬性與給定的名稱匹配,就會使用匹配的名字。否則,MyBatis 將搜索給定名稱的字段。兩種情況下您都可以使用逗點的屬性形式。比如,您可以映射到“username”,也可以映射到“address.street.number”。 |
| column |
數據庫的列名或者列標簽別名。與傳遞給resultSet.getString(columnName)的參數名稱相同。 |
| javaType |
完整java類名或別名(參考上面的內置別名列表)。如果映射到一個JavaBean,那MyBatis 通常會自行檢測到。然而,如果映射到一個HashMap,那您應該明確指定javaType 來確保所需行為。 |
| jdbcType |
這張表下面支持的JDBC類型列表列出的JDBC類型。這個屬性只在insert,update或delete 的時候針對允許空的列有用。JDBC 需要這項,但MyBatis 不需要。如果您直接編寫JDBC代碼,在允許為空值的情況下需要指定這個類型。 |
| typeHandler |
我們已經在文檔中討論過默認類型處理器。使用這個屬性可以重寫默認類型處理器。它的值可以是一個TypeHandler實現的完整類名,也可以是一個類型別名。 |
支持的JDBC類型
MyBatis支持如下的JDBC類型:
| BIT |
FLOAT |
CHAR |
TIMESTAMP |
OTHER |
UNDEFINED |
| TINYINT |
REAL |
VARCHAR |
BINARY |
BLOB |
NVARCHAR |
| SMALLINT |
DOUBLE |
LONGVARCHAR |
VARBINARY |
CLOB |
NCHAR |
| INTEGER |
NUMERIC |
DATE |
LONGVARBINARY |
BOOLEAN |
NCLOB |
| BIGINT |
DECIMAL |
TIME |
NULL |
CURSOR |
|
Constructor元素
<constructor>
<idArg column="id" javaType="int"/>
<arg column=”username” javaType=”String”/>
</constructor>
當屬性與DTO,或者與您自己的域模型一起工作的時候,許多場合要用到不變類。通常,包含引用,或者查找的數據很少或者數據不會改變的的表,適合映射到不變類中。構造器注入允許您在類實例化后給類設值,這不需要通過public方法。MyBatis同樣也支持private屬性和JavaBeans的私有屬性達到這一點,但是一些用戶可能更喜歡使用構造器注入。構造器元素可以做到這點。
考慮下面的構造器:
public class User {
//…
public User(int id, String username) {
//…
}
//…
}
為了將結果注入構造器,MyBatis需要使用它的參數類型來標記構造器。Java沒有辦法通過參數名稱來反射獲得。因此當創建constructor 元素,確保參數是按順序的並且指定了正確的類型。
<constructor>
<idArg column="id" javaType="int"/>
<arg column=”username” javaType=”String”/>
</constructor>
其它的屬性與規則與id、result元素的一樣。
| Attribute |
Description |
| column |
數據庫的列名或者列標簽別名。與傳遞給resultSet.getString(columnName)的參數名稱相同。 |
| javaType |
完整java類名或別名(參考上面的內置別名列表)。如果映射到一個JavaBean,那MyBatis 通常會自行檢測到。然而,如果映射到一個HashMap,那您應該明確指定javaType 來確保所需行為。 |
| jdbcType |
支持的JDBC類型列表中列出的JDBC類型。這個屬性只在insert,update 或delete 的時候針對允許空的列有用。JDBC 需要這項,但MyBatis 不需要。如果您直接編寫JDBC代碼,在允許為空值的情況下需要指定這個類型。 |
| typeHandler |
我們已經在文檔中討論過默認類型處理器。使用這個屬性可以重寫默認類型處理器。它的值可以是一個TypeHandler實現的完整類名,也可以是一個類型別名。 |
Association元素
<association property="author" column="blog_author_id" javaType=" Author">
<id property="id" column="author_id"/>
<result property="username" column="author_username"/>
</association>
Association元素處理“has-one”(一對一)這種類型關系。比如在我們的例子中,一個Blog有一個Author。聯合映射與其它的結果集映射工作方式差不多,指定property、column、javaType(通常MyBatis會自動識別)、jdbcType(如果需要)、typeHandler。
不同的地方是您需要告訴MyBatis 如何加載一個聯合查詢。MyBatis使用兩種方式來加載:
·Nested Select:通過執行另一個返回預期復雜類型的映射SQL語句(即引用外部定義好的SQL語句塊)。
·Nested Results:通過嵌套結果映射(nested result mappings)來處理聯接結果集(joined results)的重復子集。
首先,讓我們檢查一下元素屬性。正如您看到的,它不同於普通只有select和resultMap屬性的結果映射。
| Attribute |
Description |
| property |
映射數據庫列的字段或屬性。如果JavaBean 的屬性與給定的名稱匹配,就會使用匹配的名字。否則,MyBatis 將搜索給定名稱的字段。兩種情況下您都可以使用逗點的屬性形式。比如,您可以映射到”username”,也可以映射到更復雜點的”address.street.number”。 |
| column |
數據庫的列名或者列標簽別名。與傳遞給resultSet.getString(columnName)的參數名稱相同。 注意: 在處理組合鍵時,您可以使用column= “{prop1=col1,prop2=col2}”這樣的語法,設置多個列名傳入到嵌套查詢語句。這就會把prop1和prop2設置到目標嵌套選擇語句的參數對象中。 |
| javaType |
完整java類名或別名(參考上面的內置別名列表)。如果映射到一個JavaBean,那MyBatis 通常會自行檢測到。然而,如果映射到一個HashMap,那您應該明確指定javaType 來確保所需行為。 |
| jdbcType |
支持的JDBC類型列表中列出的JDBC類型。這個屬性只在insert,update 或delete 的時候針對允許空的列有用。JDBC 需要這項,但MyBatis 不需要。如果您直接編寫JDBC代碼,在允許為空值的情況下需要指定這個類型。 |
| typeHandler |
我們已經在文檔中討論過默認類型處理器。使用這個屬性可以重寫默認類型處理器。它的值可以是一個TypeHandler實現的完整類名,也可以是一個類型別名。 |
聯合嵌套選擇(Nested Select for Association)
| select |
通過這個屬性,通過ID引用另一個加載復雜類型的映射語句。從指定列屬性中返回的值,將作為參數設置給目標select 語句。表格下方將有一個例子。注意:在處理組合鍵時,您可以使用column=”{prop1=col1,prop2=col2}”這樣的語法,設置多個列名傳入到嵌套語句。這就會把prop1和prop2設置到目標嵌套語句的參數對象中。 |
參考:https://www.cnblogs.com/yansum/p/5774873.html也有自己的總結
下面是我的對應的association和collection對照截圖







終極殺招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">
<!-- 屬性標簽 ,引入外部的properties的文件內容
resource:引入類路徑的
url:引入網絡路徑或者磁盤路徑下的資源
-->
<configuration>
<!-- setting標簽:用來設置每個選項 name:設置選項的名字 value:值 -->
<properties resource="jdbc.properties">
</properties>
<settings>
<!-- 駝峰:emp_name-> empName-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/><!-- 延遲加載 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!-- 起實體類類名簡化全類名代碼 -->
<typeAliases>
<!-- 給java類型起別名 默認首字母小寫,指定別名:alias匹配 -->
<!-- <typeAlias type="com.tz.domain.Employee" alias="employee"/> -->
<!-- 批量起別名 為某個包下的所有類起別名 可以使用@Alias注解 為某個類型指定新的別名,別名不區分大小寫 -->
<package name="com.tz.domain"/>
</typeAliases>
<!-- 環境,mybatis可以配置多種環境 -->
<environments default="mysql"><!-- 配置環境的唯一標識 -->
<environment id="development">
<!-- 配置事務管理器的類型
事務管理器(transactionManager)
在 MyBatis 中有兩種類型的事務管理器(也就是 type=”[JDBC|MANAGED]”):
JDBC – 這個配置就是直接使用了 JDBC 的提交和回滾設置,它依賴於從數據源得到的連接來管理事務作用域。
MANAGED – 這個配置幾乎沒做什么。它從來不提交或回滾一個連接,而是讓容器來管理事務的整個生命周期(比如 JEE 應用服務器的上下文)。 默認情況下它會關閉連接,然而一些容器並不希望這樣,因此需要將 closeConnection 屬性設置為 false 來阻止它默認的關閉行為。例如:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
一般用spring的事務管理器
-->
<transactionManager type="JDBC"/>
<!-- 數據源類型 type="數據源類型"
POOLED– 這種數據源的實現利用“池”的概念將 JDBC 連接對象組織起來,避免了創建新的連接實例時所必需的初始化和認證時間。
UNPOOLED– 這個數據源的實現只是每次被請求時打開和關閉連接。
JNDI – 這個數據源的實現是為了能在如 EJB 或應用服務器這類容器中使用,容器可以集中或在外部配置數據源,然后放置一個 JNDI 上下文的引用。
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.jdbcUrl}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.jdbcUrl}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 數據庫廠商標識 type指定數據庫標識 -->
<databaseIdProvider type="DB_VENDOR">
<!-- 為不同的數據庫廠商標識別名 -->
<property name="MySQL" value="mysql"/>
<!-- <property name="Oracle" value="oracle"/> -->
</databaseIdProvider>
<!-- 將sql映射到全局配置文件中 -->
<mappers>
<!-- mapper:指定一個sql映射文件 resource:引用類路徑下的sql文件 url:引入網絡路徑或者磁盤路徑下的資源
class:引用接口全類名
1.有映射文件,文件名必須和ji接口名一致,並且還需要與接口在同一目錄下
2.沒有映射文件,所有的sql語句可以利用注解卸載接口的方法上(不推薦使用)@select(...)
-->
<!-- <mapper resource="EmployeeMapper.xml"/> -->
<!-- 批量配置 -->
<package name="com.tz.dao"/>
</mappers>
</configuration>
這個mybatis的比較重要的總結先這么多
