以及四个数据库表:
user表
orders表
orderdetail表
items表
这四张表的关系模型图:
1.创建一个com.langsin.mapper包,在mapper包下,创建一个UserMapper.xml文件
2.定义mapper接口OrderMapper.java,接口与mapper配置文件在同一个包下,这里的User类和ResultExtendUser都是定义在pojo包下,User类只是和数据库简单的映射。
package com.langsin.pojo;
public class ResultExtendUser extends User{
private String orderPrice;
private String orderDate;
private String userphone;
public String getUserphone() {
return userphone;
}
public void setUserphone(String userphone) {
this.userphone = userphone;
}
private String useraddress;
public String getOrderPrice() {
return orderPrice;
}
public void setOrderPrice(String orderPrice) {
this.orderPrice = orderPrice;
}
public String getOrderDate() {
return orderDate;
}
public void setOrderDate(String orderDate) {
this.orderDate = orderDate;
}
public String getUseraddress() {
return useraddress;
}
public void setUseraddress(String useraddress) {
this.useraddress = useraddress;
}
@Override
public String toString() {
return "ResultExtendUser [orderPrice=" + orderPrice + ", orderDate=" + orderDate + ", userphone=" + userphone
+ ", useraddress=" + useraddress + ", toString()=" + super.toString() + "]";
}
}
3.通过JUnit进行测试
@Test
public void queryUserOrder() throws Exception{
UserMapper mapper = session.getMapper(UserMapper.class);
Integer userId = 3;
List list = mapper.queryUserOrder(userId);
session.close();
for (ResultExtendUser resultExtendUser : list) {
System.out.println(resultExtendUser);
}
}
如果在进行关联查询时,几乎两个表中所有的列都被当做查询结果,那么在扩展类中再定义另外一个表中所有的列,显然不是很合适了,这种情况下最常见的方式,就是把另外一个表所对应的POJO对象组合进来,这时使用mybatis进行输出映射就只能使用resultMap元素了,这就是resultMap的高级使用。
1.通过组合创建一个扩展类,扩展User
package com.langsin.pojo;
public class ResultMapExtendUser extends User{
private Orders orders = null;
public Orders getOrders() {
return orders;
}
public void setOrders(Orders orders) {
this.orders = orders;
}
@Override
public String toString() {
return "ResultMapExtendUser [orders=" + orders + ", toString()=" + super.toString() + "]";
}
}
2.在配置映射时,必须设定唯一标识ID,例如配置订单信息,订单的唯一标识为:user_id
查询用户表并关联查询订单表。在没有使用框架时,针对于这种情况,一般我们都是service层进行业务处理,首先组装一个用户扩展类,在用户扩展类中定义一个List集合来存放此用户所对应的订单。即:先调用dao层查询用户表,然后再根据用户表与订单表的主外键关联字段,再调用订单的dao再查询订单,最终完成数据组装。通过mybatis框架collection集合,可以很轻松的完成此项工作。
1.UserMapper.xml文件
colloction标签中的属性property为resultUserList的属性,ofType为orderList组成这个List集合的类型。
2.UserMapper.java中的配置
public ResultUserList queryUserListAndOrder(Integer userId) throws Exception;
3.JUnit测试方法
@Test
public void queryUserListOrderResultMap() throws Exception{
UserMapper mapper = session.getMapper(UserMapper.class);
Integer userId = 3;
ResultUserList queryUserListAndOrder = mapper.queryUserListAndOrder(userId);
for (Orders or : queryUserListAndOrder.getOrderList()) {
System.out.println(or);
}
session.close();
}
使用mybatis实现多对多关联查询,操作内容为:查询用户及用户购买的商品的信息。
首先进行分析,查询主表为用户表user
通过订单商品数据模型图可以看出,用户表与商品表没有直接的关联关系,但可以通过中间表:订单表orders、订单明细表orderdetail、商品表item进行关联。
UserMapper.xml中的配置
2.下面开始进行配置映射关系,因为是多对多的查询,所以应该如下定义类
1)将用户信息映射到User对象中
2)在User对象中定义List orderList订单列表属性,将用户的订单映射到orderList中
3)Order中添加List detailList订单明细列表属性,将订单的明细映射到detailList中
4)在OrderDetail中添加Item item商品属性,将商品明细映射到Item中
这里没有任何扩展的类的代码就不贴了,只贴带有组合之后的类代码。
扩展User类
package com.langsin.pojo;
import java.util.List;
public class ResultUserLists extends User {
private List orderList = null;
public List getOrderList() {
return orderList;
}
public void setOrderList(List orderList) {
this.orderList = orderList;
}
@Override
public String toString() {
return "ResultUserList [toString()=" + super.toString() + "]";
}
}
扩展Orders
package com.langsin.pojo;
import java.util.List;
public class ResultExtendOrders extends Orders {
private List detailList = null;
public List getDetailList() {
return detailList;
}
public void setDetailList(List detailList) {
this.detailList = detailList;
}
}
OrderDetail组合items
package com.langsin.pojo;
public class OrderDetail {
private Items items = null;
public Items getItems() {
return items;
}
public void setItems(Items items) {
this.items = items;
}
private Integer detailId = null;
private String orderNum =null;
private String itemId = null;
private Integer buyNum = null;
private Integer orderId = null;
public Integer getDetilId() {
return detailId;
}
public void setDetilId(Integer detailId) {
this.detailId = detailId;
}
public String getOrderNum() {
return orderNum;
}
public void setOrderNum(String orderNum) {
this.orderNum = orderNum;
}
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public Integer getBuyNum() {
return buyNum;
}
public void setBuyNum(Integer buyNum) {
this.buyNum = buyNum;
}
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
@Override
public String toString() {
return "OrderDetail [items=" + items + ", detailId=" + detailId + ", orderNum=" + orderNum + ", itemId=" + itemId
+ ", buyNum=" + buyNum + ", orderId=" + orderId + "]";
}
}
JUnit测试
@Test
public void queryAllUserListOrderResultMap() throws Exception{
UserMapper mapper = session.getMapper(UserMapper.class);
Integer userId = 3;
List findUserItemDetail = mapper.findUserItemDetail(userId);
for (ResultUserLists resultUserList : findUserItemDetail) {
System.out.println(resultUserList);
}
session.close();
}
1、对于单表的查询基本上都用resultType实现即可。
2、 对于一对一的联合查询,如果作为查询结果的第二张的表字段不多,定义一个扩展类,然后使用resultType实现即可。
3、 如果一对一的联合查询,两个表的字段都大量的使用作为查询结果,那么在一个类中,组合另外一个类,使用resultMap进行映射实现。使用association将关联信息映射到一个对象中。
4、 对于一对多,多对多的联合查询,如果查询结果数据特殊使用resultMap,使用collection将关联信息映射到一个集合中去,如果只是针对明细的数据,建议定义扩展类,使用resultType映射实现。