Mybatis 學習筆記(四)——關聯(對映)關係(一對一,一對多)
阿新 • • 發佈:2018-12-15
一、背景知識
在介紹對映關係之前需要我們對 resultMap 要足夠了解。在 resultMap 中有如下節點可配置:
- id :唯一標識列,column 為資料庫ID列,property為 POJO 的id屬性,注意在查詢出的結果集中每一列都必須不一樣,標記結果作為 ID 可以幫助提高整體效能;
- constructor :類在例項化時,用來注入結果到構造方法中id – 一個 ID 結果;標記結果作為 ID 可以幫助提高整體效能;注意:一是 constructor 中欄位的順序一定要與POJO中定義的欄位順序相同且型別匹配;二是如果POJO中只有有參構造方法時則必須配置;
- idArg :ID 引數;標記結果作為 ID 可以幫助提高整體效能;
- arg :注入到構造方法的一個普通結果。
- result :注入到欄位或 POJO 屬性的普通結果
- association :用於對映關聯查詢到單個物件的資訊
- 嵌入結果對映 :結果對映自身的關聯,或者參考一個
- collection :對關聯查詢到多條記錄對映到集合物件中,其中屬性ofType表示指定對映到集合屬性中pojo的型別;
- 嵌入結果對映 :結果對映自身的關聯,或者參考一個
- discriminator :使用結果值來決定使用哪個結果對映
- case :基於某些值的結果對映
- 嵌入結果對映 :這種情形結果也對映它本身,因此可以包含很多相同的元素,或者它可以參照一個外部的結果對映。
- case :基於某些值的結果對映
二、一對一對映關係
1. 需求:查詢訂單資訊,關聯查詢建立訂單的使用者資訊,ResultMap實現
2. 資料庫表有 ORDERS,USER,ORDERDETAIL,ITEMS。點選下載
3. POJO類
Orders 與 User 是一對一的關係,在 Orders 中 加入 User 物件。
User.java
package com.po; import java.util.Date; import java.util.List; /** * 使用者類 * @author 歐陽 * */ public class User { private int id; //id private String username; //使用者名稱 private String sex; //性別 private Date birthday; //生日 private String address; //地址 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
Orders.java
package com.po;
import java.util.Date;
import java.util.List;
/**
* 訂單類
* @author 歐陽
*
*/
public class Orders {
private Integer id; //id
private Integer userId; //使用者id
private String number; //數量
private Date createtime; //建立時間
private String note; //備註
private User user; //使用者資訊
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number == null ? null : number.trim();
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note == null ? null : note.trim();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
4. 編寫Mapper.xml
OrdersCustomMapper.xml
<?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.mapper.OrdersCustomMapper">
<!--
查詢訂單資訊,關聯查詢建立訂單的使用者資訊(一對一查詢)
使用resultMap將結果對映到OrdersCustom類中
-->
<!-- 定義查詢訂單及關聯使用者資訊結果的resultMap -->
<resultMap type="com.po.Orders" id="OrdersUserResultMap">
<!-- 配置對映的訂單資訊 -->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 配置對映關係的使用者資訊 -->
<!--
association:用於對映關聯查詢單個物件的資訊
property:將要關聯查詢的使用者資訊對映到Orders的哪個屬性
-->
<association property="user" javaType="com.po.User">
<id column="id_" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
SELECT
ORDERS.*,
u.id id_,
u.USERNAME,
u.SEX,
u.address
FROM
ORDERS,
USER u
WHERE
ORDERS.user_id = u.ID
</select>
</mapper>
5. 編寫Mapper介面(採用Mapper代理的方式)
OrdersCustomMapper.java
package com.mapper;
import java.util.List;
import com.po.Orders;
public interface OrdersCustomMapper {
/*
* 查詢訂單資訊,關聯查詢建立訂單的使用者資訊,ResultMap實現
*/
public List<Orders> findOrdersUserResultMap() throws Exception;
}
6. 測試
使用JUnit4 進行測試,下面是測試的主要程式碼。OrdersCustomMapperTest.java
private SqlSessionFactory sqlSessionFactory;
//此方法是在執行testFindUserById之前執行
@Before
public void setUp() throws Exception {
String resource = "config/SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 建立會話工廠
this.sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
@Test
public void testFindOrdersUserResultMap() {
SqlSession sqlsession = sqlSessionFactory.openSession();
OrdersCustomMapper mapper = sqlsession
.getMapper(OrdersCustomMapper.class);
try {
List<Orders> orders = mapper.findOrdersUserResultMap();
System.out.println(orders.size());
} catch (Exception e) {
e.printStackTrace();
}
}
三、一對多對映關係
1. 需求:查詢訂單及訂單明細
2. POJO類
Orders.java
package com.po;
import java.util.Date;
import java.util.List;
/**
* 訂單類
* @author 歐陽
*
*/
public class Orders {
private Integer id; //id
private Integer userId; //使用者id
private String number; //數量
private Date createtime; //建立時間
private String note; //備註
private User user; //使用者資訊
private List<Orderdetail> orderdetail; //訂單明細
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number == null ? null : number.trim();
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note == null ? null : note.trim();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Orderdetail> getOrderdetail() {
return orderdetail;
}
public void setOrderdetail(List<Orderdetail> orderdetail) {
this.orderdetail = orderdetail;
}
}
User.java
package com.po;
import java.util.Date;
import java.util.List;
/**
* 使用者類
* @author 歐陽
*
*/
public class User {
private int id; //id
private String username; //使用者名稱
private String sex; //性別
private Date birthday; //生日
private String address; //地址
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Orderdetail.java
package com.po;
/**
* 訂單詳情類
* @author 歐陽
*
*/
public class Orderdetail {
private Integer id;
private Integer ordersId;
private Integer itemsId;
private Integer itemsNum;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getOrdersId() {
return ordersId;
}
public void setOrdersId(Integer ordersId) {
this.ordersId = ordersId;
}
public Integer getItemsId() {
return itemsId;
}
public void setItemsId(Integer itemsId) {
this.itemsId = itemsId;
}
public Integer getItemsNum() {
return itemsNum;
}
public void setItemsNum(Integer itemsNum) {
this.itemsNum = itemsNum;
}
}
3. 編寫對映關係
將下面的程式碼加入 OrdersCustomMapper.xml 中
<!--
查詢訂單及訂單明細(一對多查詢)
-->
<!-- 定義查詢訂單及關聯訂單資訊商品資訊結果的resultMap -->
<resultMap type="com.po.Orders" id="OrdersAndOrderDetailResultMap">
<!-- 配置對映的訂單資訊 -->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 配置對映關係的使用者資訊 -->
<association property="user" javaType="com.po.User">
<id column="u_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
<!-- 配置對映關係的訂單明細 -->
<!--
collection:對關聯查詢到多條記錄對映到集合物件中
property:將要關聯查詢的使用者資訊對映到Orders的哪個屬性
ofType:指定對映到集合屬性中pojo的型別
-->
<collection property="orderdetail" ofType="com.po.Orderdetail">
<id column="od_id" property="id"/>
<result column="orders_id" property="ordersId"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itemsNum"/>
</collection>
</resultMap>
<select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">
SELECT
o.*,
od.id od_id,
od.items_id,
od.items_num,
od.orders_id,
u.id u_id,
u.USERNAME,
u.SEX,
u.address
FROM
orders o,
orderDetail od,
user u
WHERE
o.id = od.orders_id
AND o.user_id = u.id
</select>
4. 編寫對映介面
將下面程式碼新增到 OrdersCustomMapper.java 中
/*
* 查詢訂單及訂單明細
*/
public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception;
5. 測試介面
將下面程式碼加入 OrdersCustomMapperTest.java 中
@Test
public void testFindOrdersAndOrderDetailResultMap() {
SqlSession sqlsession = sqlSessionFactory.openSession();
OrdersCustomMapper mapper = sqlsession
.getMapper(OrdersCustomMapper.class);
try {
List<Orders> orders = mapper.findOrdersAndOrderDetailResultMap();
System.out.println(orders.size());
} catch (Exception e) {
e.printStackTrace();
}
}