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的比較重要的總結先這么多