...敬請期待
上一節對映關係篇重點是闡述輸入對映和輸出對映,但是我們發現所有的查詢都是基於單表的,所以這一節繼續說多表查詢,也就是我們所謂的高階對映,高階對映還是針對於輸出對映的,又分為一對一、一對多、多對多。那麼前面的資料庫結構已經不夠用了,所以我們這裡重新建立一個訂單商品資料模型,以該模型陸續講解以上的各種對映。
資料庫準備
在我們的資料庫中,包含以下表:
顧客表(customers)
CREATE TABLE customers
(
cust_id int NOT NULL AUTO_INCREMENT,
cust_name char(50) NOT NULL ,
cust_address char(50) NULL ,
cust_city char(50) NULL ,
cust_state char(5) NULL ,
cust_zip char(10) NULL ,
cust_country char(50) NULL ,
cust_contact char(50) NULL ,
cust_email char(255) NULL ,
PRIMARY KEY (cust_id)
) ENGINE=InnoDB;
複製程式碼
訂單表(orders)
CREATE TABLE orders
(
order_num int NOT NULL AUTO_INCREMENT,
order_date datetime NOT NULL ,
cust_id int NOT NULL ,
PRIMARY KEY (order_num)
) ENGINE=InnoDB;
複製程式碼
訂單表包含cust_id,可以關聯到customers表,表示下了該訂單的客戶
訂單項(orderitems)
CREATE TABLE orderitems
(
order_num int NOT NULL ,
order_item int NOT NULL ,
prod_id char(10) NOT NULL ,
quantity int NOT NULL ,
item_price decimal(8,2) NOT NULL ,
PRIMARY KEY (order_num, order_item)
) ENGINE=InnoDB;
複製程式碼
訂單項包含order_num,關聯到orders表,記錄該訂單項屬於哪一個訂單。 prod_id表示該訂單項是什麼產品,關聯到下面的products表。
商品(products)
CREATE TABLE products
(
prod_id char(10) NOT NULL,
vend_id int NOT NULL ,
prod_name char(255) NOT NULL ,
prod_price decimal(8,2) NOT NULL ,
prod_desc text NULL ,
PRIMARY KEY(prod_id)
) ENGINE=InnoDB;
複製程式碼
vend_id關聯到下面的供應商表,表示該產品是哪家供應商生產的。
供應商
CREATE TABLE vendors
(
vend_id int NOT NULL AUTO_INCREMENT,
vend_name char(50) NOT NULL ,
vend_address char(50) NULL ,
vend_city char(50) NULL ,
vend_state char(5) NULL ,
vend_zip char(10) NULL ,
vend_country char(50) NULL ,
PRIMARY KEY (vend_id)
) ENGINE=InnoDB;
複製程式碼
有了以上這些表,我們來看看幾種對映關係吧。
一對一對映
假設我們需要查詢所有的訂單資訊,關聯查詢建立訂單的顧客資訊,因為一個訂單隻能有一個顧客,所以是一對一查詢。根據前面的知識,我們可以使用resultType或者resultMap設定返回型別。
使用resultType進行一對一對映
查詢語句:
SELECT o.order_num,o.order_date, c.*
FROM orders AS o, customers AS c
WHERE o.cust_id = c.cust_id
複製程式碼
建立POJO,由於我們的查詢結果包含兩個表的內容,我們先定義Orders
public class Orders {
private Integer orderNum;
private Date orderDate;
private Integer custId;
//setter and getter
...
}
複製程式碼
繼承Orders自定義一個OrdersCustomers類,用於承載查詢結果。
public class OrdersCustomers extends Orders {
private String custName;
private String custAddress;
private String custCity;
private String custState;
private String custZip;
private String custCountry;
private String custContact;
private String custEmail;
//setter and getter
...
}
複製程式碼
因為POJO中的屬性都是駝峰式命名,資料庫列名都是下劃線式的,所以這裡我們在mybatis的配置檔案裡設定上:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
複製程式碼
這樣就可以實現資料庫到POJO物件的自動對映了。
在Mapper中定義:
<select id="findOrdersCustomer" resultType="com.shuqing28.pojo.OrdersCustomers">
SELECT o.order_num,o.order_date, c.*
FROM orders AS o, customers AS c
WHERE o.cust_id = c.cust_id
</select>
複製程式碼
DAO中定義好介面:
List<OrdersCustomers> findOrdersCustomer();
複製程式碼
測試程式碼:
@Test
public void getOrdersCustomers(){
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
OrdersDao ordersDao = sqlSession.getMapper(OrdersDao.class);
List<OrdersCustomers> orders = ordersDao.findOrdersCustomer();
System.out.println(orders);
} finally {
sqlSession.close();
}
}
複製程式碼
查詢結果:
使用resultMap進行一對一對映
SQL語句不會變,我們首先在Orders中新增Customer屬性:
private Customer customer;
複製程式碼
定義resultMap:
<resultMap id="OrdersCustomerResultMap" type="com.shuqing28.pojo.Orders">
<id column="order_num" property="orderNum"/>
<result column="order_date" property="orderDate"/>
<result column="cust_id" property="custId"/>
<association property="customer" javaType="com.shuqing28.pojo.Customer">
<id column="cust_id" property="custId"/>
<result column="cust_name" property="custName"/>
<result column="cust_address" property="custAddress"/>
<result column="cust_city" property="custCity"/>
<result column="cust_state" property="custState"/>
<result column="cust_zip" property="custZip"/>
<result column="cust_country" property="custCountry"/>
<result column="cust_contact" property="custContact"/>
<result column="cust_email" property="custEmail"/>
</association>
</resultMap>
複製程式碼
注意到使用association標籤來配置對映關聯的customer資訊。該Map的id為OrdersCustomerResultMap
,後面就可以使用了。
定義select語句:
<select id="findOrdersCustomerMap" resultMap="OrdersCustomerResultMap">
SELECT o.order_num,o.order_date, c.*
FROM orders AS o, customers AS c
WHERE o.cust_id = c.cust_id
</select>
複製程式碼
我們使用上了前面定義的resultMap
定義介面
public List<Orders> findOrdersCustomerMap();
複製程式碼
測試程式碼
@Test
public void getOrdersCustomersMap(){
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
OrdersDao ordersDao = sqlSession.getMapper(OrdersDao.class);
List<Orders> orders = ordersDao.findOrdersCustomerMap();
System.out.println(orders);
} finally {
sqlSession.close();
}
}
複製程式碼
測試結果
總結:一對一對映,重點在於resultMap的association標籤