Mybatis學習筆記(3)—高階對映之一對一對映

卡巴拉的樹發表於2018-02-01

Mybatis學習筆記(3)—高階對映之一對一對映
MyBatis學習筆記(1)—使用篇

MyBatis學習筆記(2)—對映關係篇

MyBatis學習筆記(3)—高階對映之一對一對映

Mybatis學習筆記(4)-高階對映之一對多對映

Mybatis學習筆記(5)-高階對映之多對多對映

...敬請期待

上一節對映關係篇重點是闡述輸入對映和輸出對映,但是我們發現所有的查詢都是基於單表的,所以這一節繼續說多表查詢,也就是我們所謂的高階對映,高階對映還是針對於輸出對映的,又分為一對一、一對多、多對多。那麼前面的資料庫結構已經不夠用了,所以我們這裡重新建立一個訂單商品資料模型,以該模型陸續講解以上的各種對映。

資料庫準備

在我們的資料庫中,包含以下表:

顧客表(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();
    }
}
複製程式碼

查詢結果:

Mybatis學習筆記(3)—高階對映之一對一對映

使用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();
    }
}
複製程式碼

測試結果

Mybatis學習筆記(3)—高階對映之一對一對映

總結:一對一對映,重點在於resultMap的association標籤

相關文章