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

MyBatis學習筆記(1)—使用篇

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

MyBatis學習筆記(3)—高級映射之一對一映射sql

Mybatis學習筆記(4)-高級映射之一對多映射數據庫

Mybatis學習筆記(5)-高級映射之多對多映射bash

...敬請期待mybatis

上一節映射關係篇重點是闡述輸入映射和輸出映射,可是咱們發現全部的查詢都是基於單表的,因此這一節繼續說多表查詢,也就是咱們所謂的高級映射,高級映射仍是針對於輸出映射的,又分爲一對1、一對多、多對多。那麼前面的數據庫結構已經不夠用了,因此咱們這裏從新創建一個訂單商品數據模型,以該模型陸續講解以上的各類映射。app

數據庫準備

在咱們的數據庫中,包含如下表:post

顧客表(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關聯到下面的供應商表,表示該產品是哪家供應商生產的。ui

供應商

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標籤

相關文章
相關標籤/搜索