一、商品订单数据模型

1、数据表

这里定义了四个表,分别表示用户,商品,订单,和订单详情。

用户表user

CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` date DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8

表中的数据如下图:

商品表items

CREATE TABLE `items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL COMMENT '商品名称',
`price` float(10,1) NOT NULL COMMENT '商品定价',
`detail` text COMMENT '商品描述',
`pic` varchar(64) DEFAULT NULL COMMENT '商品图片',
`createtime` datetime NOT NULL COMMENT '生产日期',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

表中的数据如下图:



订单表orders

CREATE TABLE `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '下单用户id',
`number` varchar(32) NOT NULL COMMENT '订单号',
`createtime` datetime NOT NULL COMMENT '创建订单时间',
`note` varchar(100) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `FK_orders_1` (`user_id`),
CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8

在订单表中有一个外键user_id,和用户表user中的id相关联。

表中的数据如下图:





订单详情orderdetail

CREATE TABLE `orderdetail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`orders_id` int(11) NOT NULL COMMENT '订单id',
`items_id` int(11) NOT NULL COMMENT '商品id',
`items_num` int(11) DEFAULT NULL COMMENT '商品购买数量',
PRIMARY KEY (`id`),
KEY `FK_orderdetail_1` (`orders_id`),
KEY `FK_orderdetail_2` (`items_id`),
CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8

在订单详情表中有两个外键:orders_id和订单表orders中的id相关联;items_id和商品表items中的id相关联。

表中的数据如下图:



综合以上四张表,结合里面已有的数据,最终整合得到如下信息:

张三有编号为1000010和1000011两个订单。其中1000010订单包含1个台式机和3个笔记本;1000011订单包含4个IPAD和3个笔记本。

而李四有一个编号为1000012的订单,包含2个IPAD。

信息如下图:





2、表与表之间的关系

先分析明确有外键关联的数据表。

user和orders:

user---->orders:一个用户可以创建多个订单,一对多。

orders--->user:一个订单只能属于一个用户,一对一。



orders和orderdetail:

orders--->orderdetail:一个订单可以包括多个订单明细。因为一个订单可以购买多个商品,每个商品的购买信息都在orderdetail有一行记录。一对多关系。

orderdetail--->orders:一个订单明细只能属于一个订单,一对一。



orderdetail和items:

orderdetail--->items:一个订单明细只对应一个商品信息,一对一。

items---> orderdetail:一个商品可以属于多个订单明细(在不同的订单中) ,一对多。



再分析没有明确关系的表之间是否有业务关系:

orders和items:

通过订单明细表orderdetail,orders和items可以建立关系。

orders--->items一个订单可以包含多个商品,一对多。

items--->orders一个商品可以属于多个订单,一对多。

订单表和商品表是多对多关系。





二、建立数据表对应的POJO类

1、user.java

package com.kang.pojo;

import java.io.Serializable;
import java.util.Date;
import java.util.List; public class user implements Serializable { //属性名和数据库表的字段对应
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址 //用户创建的订单列表
private List<Orders> ordersList; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getusername() {
return username;
}
public void setusername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}
@Override
public String toString() {
return "user [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
+ address + ", ordersList=" + ordersList + "]";
} }

2、Items.java

package com.kang.pojo;

import java.util.Date;

public class Items {
private Integer id;
private String name;
private Float price;
private String pic;
private Date createtime;
private String detail; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name == null ? null : name.trim();
} public Float getPrice() {
return price;
} public void setPrice(Float price) {
this.price = price;
} public String getPic() {
return pic;
} public void setPic(String pic) {
this.pic = pic == null ? null : pic.trim();
} public Date getCreatetime() {
return createtime;
} public void setCreatetime(Date createtime) {
this.createtime = createtime;
} public String getDetail() {
return detail;
} public void setDetail(String detail) {
this.detail = detail == null ? null : detail.trim();
} @Override
public String toString() {
return "Items [id=" + id + ", name=" + name + ", price=" + price
+ ", pic=" + pic + ", createtime=" + createtime + ", detail="
+ detail + "]";
} }

3、Orders.java

package com.kang.pojo;

import java.util.Date;
import java.util.List; public class Orders {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//用户信息
private user user;
//订单明细
private List<Orderdetail> orderdetails; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public Integer getuserId() {
return userId;
} public void setuserId(Integer userId) {
this.userId = userId;
} public String getNumber() {
return number;
} public void setNumber(String number) {
this.number = number == null ? null : number.trim();
} public Date getCreatetime() {
return createtime;
} public void setCreatetime(Date createtime) {
this.createtime = createtime;
} public String getNote() {
return note;
} public void setNote(String note) {
this.note = note == null ? null : note.trim();
} 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 "Orders [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + ", user=" + user + ", orderdetails=" + orderdetails + "]";
} }

4、Orderdetail.java

package com.kang.pojo;

public class Orderdetail {
private Integer id;
private Integer ordersId;
private Integer itemsId;
private Integer itemsNum;
//明细对应的商品信息
private Items items; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public Integer getOrdersId() {
return ordersId;
} public void setOrdersId(Integer ordersId) {
this.ordersId = ordersId;
} public Integer getItemsId() {
return itemsId;
} public void setItemsId(Integer itemsId) {
this.itemsId = itemsId;
} public Integer getItemsNum() {
return itemsNum;
} public void setItemsNum(Integer itemsNum) {
this.itemsNum = itemsNum;
} public Items getItems() {
return items;
} public void setItems(Items items) {
this.items = items;
} @Override
public String toString() {
return "Orderdetail [id=" + id + ", ordersId=" + ordersId
+ ", itemsId=" + itemsId + ", itemsNum=" + itemsNum + "]";
} }

二、一对一查询

这里对Mybatis的基础配置信息不再列出,只分析对应的映射文件的内容。

业务需求:查询出订单信息,并且关联查询出创建订单的用户信息。

1、构想查询的SQL语句

查询涉及的数据表:orders和user。

查询的结果信息:orders表的全部字段信息和user的三个信息。

如何关联:通过外键orders.user_id = user.id。

SQL查询语句如下:

SELECT
orders.*,
user.username,
user.sex,
user.address
FROM
orders,
user
WHERE orders.user_id = user.id

2、实现方案

第一种:使用POJO扩展类来映射,从而避免使用resultMap。

首先根据查询结果的形式定义POJO类:这个类继承自Orders类。

package com.kang.pojo;
//通过此类映射订单和用户查询的结果,让此类继承包括字段较多的pojo类。
public class OrdersCustom extends Orders{ //添加用户属性
/*user.username,
user.sex,
user.address */ private String username;
private String sex;
private String address;
public String getusername() {
return username;
}
public void setusername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "OrdersCustom [username=" + username + ", sex=" + sex + ", address=" + address + "]";
} }

然后再映射XML文件中用resultType来指定。

<!-- 查询订单关联查询用户信息,使用 resultType -->
<select id="findOrdersuser" resultType="com.kang.pojo.OrdersCustom">
SELECT
orders.*,
user.username,
user.sex,
user.address
FROM
orders,
user
WHERE orders.user_id
= user.id
</select>

之后在接口类中定义相关的方法

public interface OrdersMapperCustom {
//查询订单关联查询用户信息
public List<OrdersCustom> findOrdersuser()throws Exception;
}

最后进行测试

public class OrderTest {
// 会话工厂
private SqlSessionFactory sqlSessionFactory;
@Before
public void createSqlSessionFactory() throws IOException {
// 配置文件SqlMapConfig.xml在类路径下
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test
public void testFindOrdersuser() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
// 调用maper的方法
List<OrdersCustom> list = ordersMapperCustom.findOrdersuser(); //System.out.println(list); for (OrdersCustom ordersCustom : list) {
System.out.println(ordersCustom);
}
sqlSession.close();
}
}

测试结果:









第二种:不使用POJO扩展类

我们可以在Orders类中添加一个属性user,然后把查询结果映射到Orders即可。

//用户信息
private user user;
//提供get/set方法。

在XML中使用resultMap来映射。

首先定义一个resultMap片段,以供引用。

<!-- type表示订单查询关联用户的resultMap 将整个查询的结果映射到com.kang.pojo.Orders中 -->
<resultMap type="com.kang.pojo.Orders" id="OrdersuserResultMap">
<!-- 配置映射的订单信息 -->
<!-- id:指定查询列中的唯一标识,也就是订单信息的中的唯一标识。如果有多个列组成唯一标识,配置多个id。
column:数据库中订单信息表的唯一标识列,通常就是主键。
property:订单信息表的唯一标识列所映射到Orders类中哪个属性。
-->
<id column="id" property="id" />
<result column="user_id" property="userId" />
<result column="number" property="number" />
<result column="createtime" property="createtime" />
<result column="note" property="note" /> <!-- 配置映射的关联的用户信息 -->
<!-- association:用于映射关联查询单个对象的信息。
property:要将关联查询的用户信息映射到Orders中哪个属性。
-->
<association property="user" javaType="com.kang.pojo.user">
<!-- id:关联查询用户的唯一标识。column:指定唯一标识用户信息的列,通常就是外键。 javaType:映射到user的哪个属性 -->
<id column="user_id" property="id" />
<result column="username" property="username" />
<result column="sex" property="sex" />
<result column="address" property="address" /> </association>
</resultMap>

然后在XML映射文件中引用该resultMap。

<!-- 查询订单关联查询用户信息,使用resultmap -->
<select id="findOrdersuserResultMap" resultMap="OrdersuserResultMap">
SELECT
orders.*,
user.username,
user.sex,
user.address
FROM
orders,
user
WHERE orders.user_id
= user.id
</select>

在接口中添加相应的方法

//查询订单关联查询用户使用resultMap
public List<Orders> findOrdersuserResultMap()throws Exception;

在测试类中添加测试方法:

       

 @Test
public void testFindOrdersuserResultMap() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class); // 调用maper的方法
List<Orders> list = ordersMapperCustom.findOrdersuserResultMap(); //System.out.println(list);
for (Orders orders : list) {
System.out.println(orders);
} sqlSession.close();
}

测试结果:





详细结果:

DEBUG [main] - <==      Total: 3
Orders [id=3, userId=1, number=1000010, createtime=Mon Feb 27 13:22:35 CST 2017, note=尽快发货, user=User [id=1, username=张三, sex=2, birthday=null, address=成都市, ordersList=null], orderdetails=null]
Orders [id=4, userId=1, number=1000011, createtime=Mon Feb 27 14:22:35 CST 2017, note=买来看看, user=User [id=1, username=张三, sex=2, birthday=null, address=成都市, ordersList=null], orderdetails=null]
Orders [id=5, userId=2, number=1000012, createtime=Mon Mar 27 22:46:36 CST 2017, note=记得发中通, user=User [id=2, username=李四, sex=1, birthday=null, address=北京市, ordersList=null], orderdetails=null]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5d76b067]

3、resultType和resultMap实现一对一查询的比较

resultType:使用resultType实现较为简单,如果pojo类中没有包括查询出来的列名,需要在其中增加列名对应的属性,即可完成映射。

resultMap:需要单独定义resultMap,实现较为麻烦。如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。

如果没有查询结果的特殊要求建议使用resultType。resultMap可以实现延迟加载,resultType无法实现延迟加载。





三、实现一对多查询

业务需求:查询出所有的订单并关联查询出订单的用户和其中的订单明细。

1、构想查询的SQL语句

查询涉及的数据表:orders,user和orderdetail。

查询的结果信息:orders表的全部字段信息+user的三个信息+订单明细的四个信息。

如何关联:通过外键orders.user_id = user.id关联用户查询;通过外键orders.id=orderdetail.orders_id关联查询订单明细。

SQL查询语句如下:

SELECT
orders.*,
user.username,
user.sex,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
FROM
orders,
user,
orderdetail
WHERE orders.user_id = user.id AND orders.id=orderdetail.orders_id

2、实现方案

使用resultMap来实现一对多关联。

首先需要在Orders的类中添加一个属性,来表示订单明细表。

//订单明细
private List<Orderdetail> orderdetails;
//提供get/set方法。

然后在XML中使用resultMap来映射,这里采用了继承。

<!-- 订单关联用户和订单明细的resultMap。使用extends继承,不用在中配置订单信息和用户信息的映射 -->
<resultMap type="com.kang.pojo.Orders" id="OrdersAndOrderDetailResultMap"
extends="OrdersuserResultMap">
<!-- 订单信息继承而来 -->
<!-- 用户信息继承而来 -->
<!-- 使用extends继承,不用配置订单信息和用户信息的映射 -->
<!-- 订单明细信息:一个订单关联查询出了多条明细,要使用collection进行一对多映射。
collection:对关联查询到多条记录映射到集合对象中。
property:将关联查询到多条记录映射到com.kang.pojo.Orders哪个属性 。
ofType:指定映射到list集合属性中pojo的类型。
-->
<collection property="orderdetails" ofType="com.kang.pojo.Orderdetail">
<!-- id:订单明细唯一标识,一般就是主键,注意这里使用了别名,结合SQL语句一看便知。
property:要将订单明细的唯一标识映射到com.kang.pojo.Orderdetail的哪个属性 -->
<id column="orderdetail_id" property="id" />
<result column="items_id" property="itemsId" />
<result column="items_num" property="itemsNum" />
<result column="orders_id" property="ordersId" />
</collection>
</resultMap>

然后在XML映射文件中引用该resultMap。

<!-- 查询订单关联查询用户及订单明细,使用resultmap -->
<select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">
SELECT
orders.*,
user.username,
user.sex,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
FROM
orders,
user,
orderdetail
WHERE orders.user_id = user.id AND orders.id=orderdetail.orders_id
</select>

在接口中添加相应的方法

//查询订单(关联用户)及订单明细
public List<Orders> findOrdersAndOrderDetailResultMap()throws Exception;

在测试类中添加测试方法:

        @Test
public void testFindOrdersAndOrderDetailResultMap() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class); // 调用maper的方法
List<Orders> list = ordersMapperCustom.findOrdersAndOrderDetailResultMap();
for (Orders orders : list) {
System.out.println(orders);
}
sqlSession.close();
}

测试结果:





详细结果:

DEBUG [main] - <==      Total: 5
Orders [id=3, userId=1, number=1000010, createtime=Mon Feb 27 13:22:35 CST 2017, note=尽快发货, user=User [id=1, username=张三, sex=2, birthday=null, address=成都市, ordersList=null], orderdetails=[Orderdetail [id=1, ordersId=3, itemsId=1, itemsNum=1], Orderdetail [id=2, ordersId=3, itemsId=2, itemsNum=3]]]
Orders [id=4, userId=1, number=1000011, createtime=Mon Feb 27 14:22:35 CST 2017, note=买来看看, user=User [id=1, username=张三, sex=2, birthday=null, address=成都市, ordersList=null], orderdetails=[Orderdetail [id=3, ordersId=4, itemsId=3, itemsNum=4], Orderdetail [id=4, ordersId=4, itemsId=2, itemsNum=3]]]
Orders [id=5, userId=2, number=1000012, createtime=Mon Mar 27 22:46:36 CST 2017, note=记得发中通, user=User [id=2, username=李四, sex=1, birthday=null, address=北京市, ordersList=null], orderdetails=[Orderdetail [id=5, ordersId=5, itemsId=3, itemsNum=2]]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5d76b067]

3、总结

mybatis使用resultMap中collection实现一对查询,它可以把关联查询的多条记录映射到一个list集合属性中。

一对多查询也可以使用resultType实现:

我们将订单明细映射到orders中的orderdetails中,需要自己处理,使用双重循环遍历,去掉重复记录,将订单明细放在orderdetails中。





四、实现多对多查询

业务需求:查询出所有订单,并关联查询出订单的用户,订单的明细以及订单中的商品信息。而订单和商品信息之间就是多对多关系。

1、构想查询的SQL语句

查询涉及的数据表:orders,user,orderdetail和items。

查询的结果信息:orders表的全部字段信息+user的四个信息+orderdetail的四个信息+items的三个信息。

如何关联:通过外键orders.user_id = user.id关联用户查询;通过外键orders.id=orderdetail.orders_id关联查询订单明细;通过外键orderdetail.items_id = items.id关联查询商品信息;

SQL查询语句如下:

SELECT
orders.*,
user.username,
user.sex,
user.birthday,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id,
items.name items_name,
items.detail items_detail,
items.price items_price
FROM
orders,
user,
orderdetail,
items
WHERE orders.user_id = user.id
AND orderdetail.orders_id=orders.id
AND orderdetail.items_id = items.id

2、实现方案

使用resultMap来实现多对多关联。

我们可以将查询结果映射到user中。

首先在user类中添加订单列表属性List<Orders> orderslist,将用户创建的订单映射到orderslist。

然后在Orders中添加订单明细列表属性List<OrderDetail>orderdetials,将订单的明细映射到orderdetials。

最后在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items。

这样我们通过user类就可得到所有我们查询到的信息。

这里不去展示具体过程,可参考上面提供的POJO类即可。

定义好POJO了类后,我们在XML中使用resultMap来映射,这里进行了collection的嵌套。

<!-- 查询用户及购买的商品 -->
<resultMap type="com.kang.pojo.user" id="userAndItemsResultMap">
<!-- 用户信息 -->
<id column="user_id" property="id" />
<result column="username" property="username" />
<result column="sex" property="sex" />
<result column="address" property="address" />
<result column="birthday" property="birthday" /> <!-- 订单信息 一个用户对应多个订单,使用collection映射 -->
<collection property="ordersList" ofType="com.kang.pojo.Orders">
<id column="id" property="id" />
<result column="user_id" property="userId" />
<result column="number" property="number" />
<result column="createtime" property="createtime" />
<result column="note" property="note" /> <!-- 订单明细,一个订单包括多个明细 -->
<collection property="orderdetails" ofType="com.kang.pojo.Orderdetail">
<id column="orderdetail_id" property="id" />
<result column="items_id" property="itemsId" />
<result column="items_num" property="itemsNum" />
<result column="orders_id" property="ordersId" /> <!-- 商品信息 一个订单明细对应一个商品 -->
<association property="items" javaType="com.kang.pojo.Items">
<id column="items_id" property="id" />
<result column="items_name" property="name" />
<result column="items_detail" property="detail" />
<result column="items_price" property="price" />
</association>
</collection>
</collection>
</resultMap>

然后在XML映射文件中引用该resultMap。

<!-- 查询用户及购买的商品信息,使用resultmap -->
<select id="finduserAndItemsResultMap" resultMap="userAndItemsResultMap">
SELECT
orders.*,
user.username,
user.sex,
user.birthday,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id,
items.name items_name,
items.detail items_detail,
items.price items_price
FROM
orders,
user,
orderdetail,
items
WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND
orderdetail.items_id = items.id
</select>

在接口中添加相应的方法

//查询用户购买商品信息
public List<User> findUserAndItemsResultMap()throws Exception;

在测试类中添加测试方法:

        @Test
public void testFindUserAndItemsResultMap() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class); // 调用maper的方法
List<User> list = ordersMapperCustom.findUserAndItemsResultMap(); //System.out.println(list);
for (User user : list) {
System.out.println(user);
}
sqlSession.close();
}

测试结果:









详细结果:

DEBUG [main] - <==      Total: 5
User [id=1, username=张三, sex=2, birthday=Tue Oct 27 00:00:00 CST 1998, address=成都市, ordersList=[Orders [id=3, userId=1, number=1000010, createtime=Mon Feb 27 13:22:35 CST 2017, note=尽快发货, user=null, orderdetails=[Orderdetail [id=1, ordersId=3, itemsId=1, itemsNum=1], Orderdetail [id=2, ordersId=3, itemsId=2, itemsNum=3]]], Orders [id=4, userId=1, number=1000011, createtime=Mon Feb 27 14:22:35 CST 2017, note=买来看看, user=null, orderdetails=[Orderdetail [id=3, ordersId=4, itemsId=3, itemsNum=4], Orderdetail [id=4, ordersId=4, itemsId=2, itemsNum=3]]]]]
User [id=2, username=李四, sex=1, birthday=Fri Oct 01 00:00:00 CST 1993, address=北京市, ordersList=[Orders [id=5, userId=2, number=1000012, createtime=Mon Mar 27 22:46:36 CST 2017, note=记得发中通, user=null, orderdetails=[Orderdetail [id=5, ordersId=5, itemsId=3, itemsNum=2]]]]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5d76b067]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5d76b067]

3、总结

一对多是多对多的特例,查询用户购买的商品信息,用户和商品的关系是多对多关系。

需求1:

查询字段:用户账号、用户名称、用户性别、商品名称、商品价格(最常见)。

企业开发中常见明细列表,用户购买商品明细列表,使用resultType将上边查询列映射到pojo输出。

需求2:

查询字段:用户账号、用户名称、购买商品数量、商品明细。

使用resultMap将用户购买的商品明细列表映射到user对象中。

五、总结

1、resultType

作用:

将查询结果按照sql列名pojo属性名一致性映射到pojo中。

使用场合:

常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。





2、resultMap

使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。

association:

作用:

将关联查询信息映射到一个pojo对象中。

使用场合:

为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。

使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。

collection:

作用:

将关联查询信息映射到一个list集合中。

使用场合:

为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。

如果使用resultType无法将查询结果映射到list集合中。

Mybatis中的关联映射和查询的更多相关文章

  1. 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多

    学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...

  2. 【mybatis深度历险系列】mybatis中的输入映射和输出映射

    在前面的博文中,小编介绍了mybatis的框架原理以及入门程序,还有mybatis中开发到的两种方法,原始开发dao的方法和mapper代理方法,今天博文,我们来继续学习mybatis中的相关知识,随 ...

  3. Mybatis中多表联查,查询出来的字段出现重名,造成数据异常的解决方法!

    在做一对多出现的问题,引发的思考:当数据库表中,主表的主键id和明细表的中的字段名相同时怎么办?Mybatis进行自动映射赋值的时候会不会出现异常?                      注意:M ...

  4. Mybatis中动态SQL多条件查询

    Mybatis中动态SQL多条件查询 mybatis中用于实现动态SQL的元素有: if:用if实现条件的选择,用于定义where的字句的条件. choose(when otherwise)相当于Ja ...

  5. mybatis标签之——关联映射

    关联关系是面向对象分析.面向对象设计最重要的知识.合理的关联映射将大大简化持久层数据的访问.关联关系大致分为以下三类: 一对一 一对多 多对多 1. 一对一 一对一关系推荐使用唯一主外键关联,即两张表 ...

  6. Mybatis笔记四:Mybatis中的resultType和resultMap查询操作实例详解

    resultType和resultMap只能有一个成立,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,resultMap解决复杂查询是的映射问题.比 ...

  7. Mybatis 中的转义字符及常用查询

    转译符 1.特殊字符转译 < < 小于 > > 大于 & & 与 ' ’ 单引号 " " 双引号 需要注意的是分号是必不可少的. 比如 a ...

  8. mybatis中一对一关系映射

    一对一关系中普通的配置方式 一.多表连接查询语句: <select id="selectStudentWithAddress" parameterType="int ...

  9. Mybatis中对象关系映射

    在实际开发中,实体类之间有一对一.一对多.多对多的关系,所以需要正确配置它们对应关系,Mybatis通过配置文件能够从数据库中获取列数据后自动封装成对象. 如:一个订单Orders类对应一个用户Use ...

随机推荐

  1. 【AS3 Coder】任务五:Flash 2D游戏的第二春(下)

    在上一节中,我们基本上已经讲完了游戏中最主要的逻辑部分,不过为了更加全面地运用Starling中的一些特性,在本节中我们将一起来看看如何实现多面板切换以及粒子效果,这两个玩意儿可是比较频繁会出现于St ...

  2. 怎么将JSP页面的ID值传给Action进行更新和删除

    这里只是单纯的SH整合. JSP页面代码 <!-- value=action中数据库的User对象集合list必须和action定义的名字一样, 且为了在这里能够访问,需要生成get/set方法 ...

  3. nodeJs-autoBulid

    /** * Created by Administrator on 2016/1/16. */ var projectData = { 'name' : 'autobulid', 'fileData' ...

  4. iOS block用作属性封装代码

    @property (copy, nonatomic) void (^actionBlock)(); @property (copy, nonatomic) void (^actionWithPapa ...

  5. bat 处理文件路径 (所在目录,文件名,文件后缀名,完整文件名,无后缀路径)

    echo off setlocal enabledelayedexpansion set "EXCEL_DIR=%cd%\excel" for /R %EXCEL_DIR% %%f ...

  6. python pip install error

    使用pip install的时候报错 解决方法是使用如下的命令进行安装 python -m pip install sqlalchemy 升级pip的命令python2 -m pip install ...

  7. 拒绝IP登陆

    tail -n 30 /var/log/messages 发现很多IP尝试登陆,直接封禁. 解决方案:1. vi /etc/hosts.allow 添加 sshd:143.63.182.238 [注意 ...

  8. SQL Server变量赋值的方法

    SQL Server变量赋值我们经常会遇到,下面就为您介绍SQL Server变量赋值的两种方法,希望可以对您学习SQL Server变量赋值有所帮助. SQL Server中对已经定义的SQL Se ...

  9. xml格式发送

    1. namespace xml格式发送 { /// <summary> /// 实体转Xml,Xml转实体类 /// </summary> /// <typeparam ...

  10. 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生

    [转].NET(C#):浅谈程序集清单资源和RESX资源   目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...