Mybatis一對多查詢列表屬性處理示例詳解
一、說明
1.<collection>標簽屬性說明
- property:指定主對象中的集合屬性名稱。
- ofType:指定集合元素的類型。默認值為java.lang.Object。可以通過指定 ofType 屬性來指定集合元素的類型。
- column:指定集合元素所用的列名,用於匹配結果集中的列。(內層select關聯字段,若不指定則默認使用外鍵對應的主鍵作為column屬性的值)
- columnPrefix: 指定集合元素所用的列名前綴,用於匹配結果集中的列。(用於平鋪查詢方式下內層列映射自動匹配)
- select:指定獲取集合元素的 SQL 查詢語句。
- resultSetType:指定 SQL 查詢結果集的類型,默認值為FORWARD_ONLY,還可以設置為SCROLL_SENSITIVE和SCROLL_INSENSITIVE,具體的用法可以參考JDBC文檔。
- fetchType:指定集合的加載方式,默認值為“lazy”,可選值為“eager”,當 fetchType 屬性設置為“eager”時,MyBatis會在執行 SQL 語句返回結果集後,立即加載集合元素。
- javaType: 指定集合的 Java 類型,通常不需要指定,MyBatis會根據集合屬性的類型自動推斷。
- jdbcType: 指定集合屬性在數據庫中的類型,可以參考 JDBC 中的類型定義。如果不指定,MyBatis會自動推斷。
- notNullColumn:指定一個或多個屬性列的名稱,這些列不能為空。當這些屬性列為空時,MyBatis會拋出異常。notNullColumn 屬性可以使用逗號(,)分隔,以指定多個屬性列。
- columnOverride:指定一個或多個元素屬性與結果集中列的映射關系。
- typeHandler:指定一個元素屬性的類型處理器。
- ofTypeHandler:指定集合元素的類型處理器。
- resultMap:指定集合元素的映射器,通常是通過嵌套 result 標簽來定義,並使用該 resultMap 的 id 來指定。
- orderBy:指定升序或降序。多個排序條件時,用空格分開。例如orderBy="id desc,create_time asc"表示先按id降序,再按createTime升序排列。(不推薦使用,建議在SQL中手動指定排序方式)
- notNullColumn:指定一個或多個屬性列的名稱,這些列不能為空。當這些屬性列為空時,MyBatis會拋出異常。notNullColumn 屬性可以使用逗號(,)分隔,以指定多個屬性列。
- statementType:指定操作執行的SQL類型,有STATEMENT,PREPARED和CALLABLE三種,分別代表簡單語句、預處理語句和調用存儲過程。默認值為PREPARED。
columnPrefix用法
如果使用瞭 columnPrefix 屬性,可以省略 result 標簽中的 column 屬性,並且 MyBatis 會自動完成屬性與列名之間的映射。
<resultMap id="userResultMap" type="User"> <id column="user_id" property="id"/> <result column="user_name" property="name"/> <collection property="roles" ofType="Role"> <id column="role_id" property="id"/> <result column="role_name" property="name"/> </collection> </resultMap>
改用
columnPrefix
前綴寫法簡化代碼,使用使用時,多使用表別名作為列前綴,例如columnPrefix="r."
<resultMap id="userResultMap" type="User"> <id column="user_id" property="id"/> <result column="user_name" property="name"/> <collection property="roles" ofType="Role" columnPrefix="role_"> <id column="role_id" property="id"/> <result property="name"/> </collection> </resultMap>
mybatis 官方文檔
2. 示例代碼
實體類
public class User { private Integer id; private String name; private Integer age; private List<Order> orders; // 省略 getter 和 setter 方法 } public class Order { private Integer id; private String orderNo; private Date createTime; // 省略 getter 和 setter 方法 }
二、平鋪查詢
可結合
columnPrefix
、resultMap
使用
Mybatis XML
<select id="getUserOrdersById" resultMap="userResultMap"> SELECT u.id, u.name, u.age, o.id AS order_id, o.order_no, o.create_time FROM user u INNER JOIN `order` o ON u.id = o.user_id WHERE u.id = #{id} </select> <resultMap id="userResultMap" type="com.example.User"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="age" column="age" /> <collection property="orders" ofType="com.example.Order" resultMap="orderResultMap" /> </resultMap> <resultMap id="orderResultMap" type="com.example.Order"> <id property="id" column="order_id" /> <result property="orderNo" column="order_no" /> <result property="createTime" column="create_time" /> </resultMap>
三、 嵌套查詢(Nested Select for Collection)
嵌套查詢支持惰性加載,可通過設置
fetchType
調整集合加載方式,默認值為“lazy”,可選值為“eager”。
3.1 外鍵查詢
<select id="getUserOrdersById" resultMap="userResultMap"> SELECT u.id, u.name, u.age FROM user u WHERE u.id = #{id} </select> <select id="getOrderByUserId" resultMap="orderResultMap"> SELECT o.id, o.order_no, o.create_time FROM `order` o WHERE o.user_id = #{userId} </select> <resultMap id="orderResultMap" type="com.example.Order"> <id property="id" column="order_id" /> <result property="orderNo" column="order_no" /> <result property="createTime" column="create_time" /> </resultMap> <resultMap id="userResultMap" type="com.example.User"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="age" column="age" /> <collection property="orders" ofType="com.example.Order" resultMap="orderResultMap" select="getOrderByUserId" column="id"> <!-- 這裡使用 column="id",指定瞭內層 select 語句的參數值為外層查詢語句結果集中的 id 屬性值(即用戶ID) --> </collection> </resultMap>
3.2 select傳入多個參數
上面講到指定
select
嵌套sql時,需要指定column="id"
,如果內層SQL需要傳入多個參數時,可采用如下方式
public class OrderQuery { private Long userId; // 用戶id private Integer status; // 訂單狀態 // getter和setter方法 }
<select id="getOrdersByUserId" resultType="Order"> SELECT * FROM `order` WHERE user_id = #{userId} AND status = #{status} </select> <resultMap id="userMap" type="User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <!-- 註意這裡的association標簽的select屬性使用瞭OrderQuery對象的屬性 --> <result property="orders" column="id" select="com.example.mapper.OrderMapper.getOrdersByUserId"> <association property="param" javaType="OrderQuery"> <result property="userId" column="id"/> <result property="status" value="1"/> <!-- 這裡傳遞的是固定值,也可以替換為動態的表達式 --> </association> </result> </resultMap>
association一對一屬性處理
上面介紹一對多查詢列表屬性處理,其實association更常用於一對一屬性的處理上
package com.example; public class Order { private int orderId; private String orderName; private Customer customer; // getters and setters for orderId, orderName, customer } package com.example; public class Customer { private int customerId; private String customerName; // getters and setters for customerId, customerName }
<resultMap id="orderMap" type="com.example.Order"> <id property="orderId" column="order_id"/> <result property="orderName" column="order_name"/> <association property="customer" javaType="com.example.Customer"> <id property="customerId" column="customer_id"/> <result property="customerName" column="customer_name"/> </association> </resultMap>
在這個例子中,Order類有一個Customer屬性,我們使用Association關聯對象將query出的Customer映射到Order對象的Customer屬性上。
需要註意的是,Association也可以嵌套使用,我們可以通過多層Association實現多個對象之間的關聯。此外,需要註意的是,在映射關聯對象Association時要確保SQL語句中的JOIN操作正確無誤。
總結
到此這篇關於Mybatis一對多查詢列表屬性處理的文章就介紹到這瞭,更多相關Mybatis一對多查詢列表屬性內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- autoMapping和autoMappingBehavior的區別及說明
- 關於Mybatis使用collection分頁問題
- 關於mybatis一對一查詢一對多查詢遇到的問題
- MyBatis映射關系詳解
- Mybatis中resultMap的Colum和property屬性詳解