MyBatis 学习笔记 (1) 使用篇
MyBatis 学习笔记 (2) 映射关系篇
MyBatis 学习笔记 (3) 高级映射之一对一映射
... 敬请期待
上一节映射关系篇重点是阐述输入映射和输出映射, 但是我们发现所有的查询都是基于单表的, 所以这一节继续说多表查询, 也就是我们所谓的高级映射, 高级映射还是针对于输出映射的, 又分为一对一一对多多对多那么前面的数据库结构已经不够用了, 所以我们这里重新建立一个订单商品数据模型, 以该模型陆续讲解以上的各种映射
数据库准备
在我们的数据库中, 包含以下表:
顾客表(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 标签
来源: https://juejin.im/post/5a6e7d0651882573421724e4