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