您的位置:首页 > 其它

Mybatis中的关联映射和查询

2017-03-28 10:34 471 查看
一、商品订单数据模型

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集合中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: