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();
    }
}
复制代码
查询结果:

使用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标签

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值