执行查询操作的时候,通常返回的结果集会出现一下几种情况:
1. 一对一查询:返回的结果集的唯一主键是非重复的。(下面会标出唯一主键,和 oracle 的主键有区别)
查询订单以及订单的用户信息,两种接收结果集的方式:
1)使用 pojo 对象去接收结果集(唯一主键:)

public class OrderCustom extends User {
private int orderId; //订单id
private int user_id; //用户id
private String orderNumber; //订单号
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
@Override
public String toString() {
String userString = super.toString();
return "OrderCustom {orderId=" + orderId + ", user_id=" + user_id
+ ", orderNumber=" + orderNumber + "[" + userString + "]" + "}";
}
}
<!-- 查询订单及用户信息,resultType --> <select databaseId="oracle" id="findOrdersUsers_resultType" resultType="orderCustom"> select orders.*, users.* from orders, users where orders.user_id = users.userid </select>
public class OrderMapperTest extends TestCase {
private SqlSessionFactory sqlSessionFactory;
private String resource = "SqlMapConfig.xml";
@Override
protected void setUp() throws Exception {
super.setUp();
//通过输入流读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "development_oracle");
}
//一对一查询,使用resultType
@Test
public void testFindOrdersUsers_resultType() throws Exception {
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//指定 mapper 接口的类型,MyBatis通过动态代理的方式实现mapper接口
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
List<OrderCustom> list = orderMapper.findOrdersUsers_resultType();
System.out.println(list.size());
Iterator<OrderCustom> iterator = list.iterator();
while (iterator.hasNext()) {
OrderCustom orderCustom = (OrderCustom) iterator.next();
System.out.println(orderCustom);
}
}
}
执行结果:

2)使用resultMap接收结果集
public class Order {
private int orderId; //订单id
private int user_id; //用户id
private String orderNumber; //订单号
private User user; //用户信息
private List<OrderDetail> orderDetails; //订单明细
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<OrderDetail> getOrderDetails() {
return orderDetails;
}
public void setOrderDetails(List<OrderDetail> orderDetails) {
this.orderDetails = orderDetails;
}
@Override
public String toString() {
return "Order [orderId=" + orderId + ", user_id=" + user_id
+ ", orderNumber=" + orderNumber + ", user=" + user
+ ", orderDetails=" + orderDetails + "]";
}
}
<!-- 查询订单及用户信息,resultMap --> <resultMap id="orderUserMap" type="mybatis_b.model.Order"> <!-- order信息 --> <!-- 这里的id 是mybatis在进行一对一查询时,将orderId字段映射为Order 对象使用,必须写 --> <id property="orderId" column="orderId"/> <result property="user_id" column="user_id"/> <result property="orderNumber" column="orderNumber"/> <!-- 用户信息 --> <!-- 将用户信息 使用 association 封装成一个user对象--> <!-- association:用于一对一查询,将查询出来的以下字段映射到单个对象 property="user" : 指定封装对象存储的属性在orders中 javaType : 指定属性的javaType user.username, user.sex, user.address --> <association property="user" javaType="mybatis_b.model.User"> <!-- 这里的id为user的id,如果写表示给user的id属性赋值 --> <id property="userId" column="userId"/> <result property="username" column="username"/> <result property="sex" column="sex"/> <result property="birthday" column="birthday"/> <result property="address" column="address"/> <result property="detail" column="detail"/> <result property="score" column="score"/> </association> </resultMap> <select id="findOrdersUsers_resultMap" resultMap="orderUserMap"> select orders.*, users.* from orders, users where orders.user_id = users.userid </select>
java调用代码同上,只需修改
List<OrderCustom> list = orderMapper.findOrdersUsers_resultMap();
2. 一对多查询:返回的结果集的唯一主键是非重复的。如下:
查询订单以及订单明细信息,可以看出记录中存在 两个订单明细是属于同一个订单的 情况,这就是一对多的查询结果集。结果集有5条记录,但是应该只存在四个OrderId(因为两个重复的)。

一对多查询结果需要使用 resultMap 来接收,代码如下:
<!-- 订单及明细信息 --> <resultMap id="orderDetails" type="mybatis_b.model.Order"> <!-- id 这里表示结果集的唯一主键,虽然出现重复的orderDetail,但是属于同一个orderId --> <id property="orderId" column="orderId"/> <result property="user_id" column="user_id"/> <result property="orderNumber" column="orderNumber"/> <!-- collect:用于一对多查询,接收 List<object> 对象; ofType表示 List 中对象的类型 --> <!-- 上面 Order 类中的List<OrderDetail> 就是用来接收一对多的结果集 --> <collection property="orderDetails" ofType="mybatis_b.model.OrderDetail"> <id property="orderDetailId" column="orderDetailId"/> <result property="item_id" column="item_id"/> <result property="item_number" column="item_number"/> <result property="item_price" column="item_price"/> </collection> </resultMap> <select id="findOrderDetails" resultMap="orderDetails"> select orders.*, orderDetail.orderDetailId, orderDetail.item_id, orderDetail.item_number, orderDetail.item_price from orders, orderDetail where orders.orderId = orderDetail.order_id </select>
OrderDetail 类:
public class OrderDetail {
private int orderDetailId; //order明细id
private int order_id; //订单id
private int item_id; //商品id
private int item_number; //商品数量
private Float item_price; //单价
public int getOrderDetailId() {
return orderDetailId;
}
public void setOrderDetailId(int orderDetailId) {
this.orderDetailId = orderDetailId;
}
public int getOrder_id() {
return order_id;
}
public void setOrder_id(int order_id) {
this.order_id = order_id;
}
public int getItem_id() {
return item_id;
}
public void setItem_id(int item_id) {
this.item_id = item_id;
}
public int getItem_number() {
return item_number;
}
public void setItem_number(int item_number) {
this.item_number = item_number;
}
public Float getItem_price() {
return item_price;
}
public void setItem_price(Float item_price) {
this.item_price = item_price;
}
@Override
public String toString() {
return "OrderDetail [orderDetailId=" + orderDetailId + ", order_id="
+ order_id + ", item_id=" + item_id + ", item_number="
+ item_number + ", item_price=" + item_price + "]";
}
}
java调用代码同上,只需修改
List<OrderCustom> list = orderMapper.findOrderDetails();
执行结果:可以看出,第二条order信息中,有两条 orderDetail 信息

3. resultMap 继承
MyBatis 的 mapper.xml 配置文件中可以使用 resultMap 的继承。如下:
查询订单、订单明细以及订单的用户信息。上面我们已经有 orderUserMap 这个resultMap 来接收 订单以及用户信息了。下面继承这个 resultMap:
<!-- 订单、订单明细及用户信息 --> <resultMap id="orderDetailsAndUser" type="mybatis_b.model.Order" extends="orderUserMap"> <collection property="orderDetails" ofType="mybatis_b.model.OrderDetail"> <id property="orderDetailId" column="orderDetailId"/> <result property="item_id" column="item_id"/> <result property="item_number" column="item_number"/> <result property="item_price" column="item_price"/> </collection> </resultMap> <select id="findOrderDetailsAndUser" resultMap="orderDetailsAndUser"> select orders.*,users.*, orderDetail.orderDetailId, orderDetail.item_id, orderDetail.item_number, orderDetail.item_price from orders, users, orderDetail where orders.user_id = users.userid and orders.orderId = orderDetail.order_id </select>
代码中 orderDetailsAndUser 这个 resultMap 继承了 orderUserMap, 所以 order 和 user 属性配置可以省略,减少代码量。
原文:http://my.oschina.net/u/1757476/blog/505914