一、订单商品数据模型

1、数据库执行脚本

创建数据库表代码:

/*Table structure for table `t_user` */
CREATE TABLE t_user (
id INT 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`)
) DEFAULT CHARSET=utf8; /*Table structure for table `items` */
CREATE TABLE items (
id INT NOT NULL AUTO_INCREMENT,
itemsname 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)
) DEFAULT CHARSET=utf8; /*Table structure for table `orders` */
CREATE TABLE orders (
id INT NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL COMMENT '下单用户id',
number VARCHAR(30) 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 `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) DEFAULT CHARSET=utf8; /*Table structure for table `orderdetail` */
CREATE TABLE orderdetail (
id INT NOT NULL AUTO_INCREMENT,
orders_id INT NOT NULL COMMENT '订单id',
items_id INT NOT NULL COMMENT '商品id',
items_num INT 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
) DEFAULT CHARSET=utf8;

测试数据:

/*Data for the table `user` */
INSERT INTO `t_user`(`username`,`birthday`,`sex`,`address`) VALUES
('王五',NULL,'',NULL),
('张三','2014-07-10','','北京市'),
('张小明',NULL,'','河南郑州'),
('陈小明',NULL,'','河南郑州'),
('张三丰',NULL,'','河南郑州'),
('陈小东',NULL,'','河南郑州'),
('王五',NULL,NULL,NULL),
('小A','2015-06-27','','北京'),
('小B','2015-06-27','','北京'),
('小C','2015-06-27','','北京'),
('小D','2015-06-27','','北京'); /*Data for the table `items` */
INSERT INTO items(itemsname,price,detail,pic,createtime) VALUES
('台式机',3000.0,'该电脑质量非常好!',NULL,'2015-07-07 13:28:53'),
('笔记本',6000.0,'笔记本性能好,质量好!',NULL,'2015-07-08 13:22:57'),
('背包',200.0,'名牌背包,容量大质量好!',NULL,'2015-07-010 13:25:02'); /*Data for the table `orders` */
INSERT INTO `orders`(`user_id`,`number`,`createtime`,`note`) VALUES
(1,'','2015-06-04 13:22:35',NULL),
(1,'','2015-07-08 13:22:41',NULL),
(2,'','2015-07-17 14:13:23',NULL),
(3,'','2015-07-16 18:13:23',NULL),
(4,'','2015-07-15 19:13:23',NULL),
(5,'','2015-07-14 17:13:23',NULL),
(6,'','2015-07-13 16:13:23',NULL); /*Data for the table `orderdetail` */
INSERT INTO `orderdetail`(`orders_id`,`items_id`,`items_num`) VALUES
(1,1,1),
(1,2,3),
(2,3,4),
(3,2,3);

2、数据模型分析思路

(1).每张表记录的数据内容:分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程;

(2).每张表重要的字段设置:非空字段、外键字段;

(3).数据库级别表与表之间的关系:外键关系;

(4).表与表之间的业务关系:在分析表与表之间的业务关系时一定要建立在某个业务意义基础上去分析。

3、针对订单商品模型的数据库思路分析:

用户表:t_user-->记录了购买商品的用户信息

订单表:orders-->记录了用户所创建的订单(购买商品的订单)

订单明细表:orderdetail-->记录了订单的详细信息即购买商品的信息

商品表:items-->记录了商品信息

表与表之间的业务关系:

  在分析表与表之间的业务关系时需要建立 在某个业务意义基础上去分析。

  先分析数据级别之间有关系的表之间的业务关系:

t_user和orders:

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

  orders--->t_user:一个订单只由一个用户创建,一对一

orders和orderdetail:

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

  orderdetail--> orders:一个订单明细只能包括在一个订单中,一对一

orderdetail和items:

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

  items--> orderdetail:一个商品可以包括在多个订单明细 ,一对多

再分析数据库级别没有关系的表之间是否有业务关系:

orders和items:

  orders和items之间可以通过orderdetail表建立关系。

4、分析之后画出对应的图,方便直观的了解业务关系

二、一对一查询

2.1、需求:查询订单信息,关联查询用户信息。

2.2、resultType实现

2.2.1、sql语句   

确定查询的主表:订单表,确定查询的关联表:用户表。

SELECT    t1.*,t2.username,t2.sex,t2.address
FROM orders t1,t_user t2
WHERE t1.user_id=t2.id

2.2.2、创建entity实体

用户实体:User.java

package com.mybatis.entity;

import java.util.Date;
import java.util.List; /**
* @ClassName: User
* @Description: TODO(用户实体)
* @author lixiaoxi
* @date 2015-6-27 下午1:56:02
*
*/
public class User {
// 属性名称和数据库字段名称保持一致
private Integer id;
// 姓名
private String username;
// 性别
private String sex;
// 地址
private String address;
// 生日
private Date birthday;
// 用户创建的订单列表
private List<Orders> ordersList; public Integer getId() {
return id;
} public void setId(Integer 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 String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
} public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} 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
+ ", address=" + address + ", birthday=" + birthday + "]";
} }

订单实体:Orders.java

package com.mybatis.entity;

import java.util.Date;
import java.util.List; /**
* @ClassName: Orders
* @Description: TODO(订单实体)
* @author lixiaoxi
*/
public class Orders { /** 主键订单Id */
private Integer id;
/** 下单用户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;
}
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;
}
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;
} }

商品实体:Items.java

package com.mybatis.entity;

import java.util.Date;

/**
* @ClassName: Items
* @Description: TODO(商品实体类)
* @author lixiaoxi
*/
public class Items { /** 商品表主键Id */
private Integer id;
/** 商品名称 */
private String itemsName;
/** 商品定价 */
private float price;
/** 商品描述 */
private String detail;
/** 商品图片 */
private String picture;
/** 生产日期 */
private Date createTime; public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getItemsName() {
return itemsName;
}
public void setItemsName(String itemsName) {
this.itemsName = itemsName;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
} }

订单明细实体:OrderDetail.java

package com.mybatis.entity;

/**
* @ClassName: OrderDetail
* @Description: TODO(订单明细实体)
* @author lixiaoxi
*/
public class OrderDetail { /** 主键,订单明细表Id */
private Integer id;
/** 订单Id */
private Integer ordersId;
/** 商品id */
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;
}
}

创建一个包装类,将查询到的信息可以全部映射到此类:OrdersCustom.java

/**
* @ClassName: OrdersCustom
* @Description: TODO(订单的扩展类,通过此类映射订单和用户的查询结果,让此类继承字段较多的实体类)
* @author: 阿赫瓦里
*/
public class OrdersCustom extends Orders {
// 添加用户的属性
private String username;
private String sex;
private String address;
// getter and setter......
}

2.2.3、创建OrdersCustomMapper.java

package com.mybatis.mapper;

import java.util.List;
import com.mybatis.entity.OrdersCustom; public interface OrdersCustomMapper { /** 查询订单,关联查询用户信息 */
public List<OrdersCustom> findOrdersUser(); }

 2.2.4、创建OrdersCustomMapper.xml和上面对应的接口名称一致,以便通过mapper接口加载配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mybatis.mapper.OrdersCustomMapper"> <!-- 查询订单,关联查询用户信息 -->
<select id="findOrdersUser" resultType="com.mybatis.entity.OrdersCustom">
select t1.*,t2.username,t2.sex,t2.address from orders t1,t_user t2
where t1.user_id = t2.id
</select> </mapper>

2.3、resultMap实现

2.3.1、sql语句同上

2.3.2、resultMap映射思路:

使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中(上面orders实体中已经添加)。

2.3.3、ordersCustomMapper.xml

1、定义resultMap

<!-- 定义查询订单关联用户的 resultMap,将整个的查询结果映射到com.mybatis.entity.Orders中 -->
<resultMap type="com.mybatis.entity.Orders" id="OrdersUserResultMap">
<!-- 1.配置映射的订单信息 -->
<!-- id:查询列中的唯一标识,订单信息中的唯一标识,如果多列组成唯一标识(如:一般数据库设计中的字典表 使用联合主键),
就需要配置多个id.
column:订单信息的唯一标识 列
property:订单信息的唯一标识列所映射到orders中的那个属性(假如:数据库中orders表中的主键为orders_id,而实体属性名称
为ordersId,则这个配置应为<id column="orders_id" property="ordersId"/>,类似hibernate实体映射文件配置)。
-->
<id column="id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createTime"/>
<result column="note" property="note"/> <!-- 2.配置映射的关联用户信息 -->
<!--association:用于映射关联查询单个对象的信息
property:要将关联查询的用户信息映射到Orders中那个属性
-->
<association property="user" javaType="com.mybatis.entity.User">
<!-- id:关联查询用户的唯一标识
column:指定唯一标识用户信息的列
property:映射到user的那个属性
-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association> </resultMap>

2、statement定义

<!-- 查询订单,关联查询用户信息,使用resultMap实现 -->
<select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
SELECT t1.*,t2.username,t2.sex,t2.address FROM orders t1,t_user t2
WHERE t1.user_id=t2.id
</select>

3、OrdersCustomMapper.java接口中添加下面的方法

 /** 查询订单关联查询用户信息,使用reslutMap实现*/
public List<Orders>findOrdersUserResultMap();

4、对resultType和resultMap实现的一对一查询进行Junit测试:

package com.mybatis.test;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test; import com.mybatis.entity.OrderDetail;
import com.mybatis.entity.Orders;
import com.mybatis.entity.OrdersCustom;
import com.mybatis.mapper.OrdersCustomMapper; public class OrdersCustomMapperTest { private SqlSessionFactory sqlSessionFactory;
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 此方法是在执行@Test方法之前执行
@Before
public void setUp() throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建SqlSessionFcatory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} // 查询订单,关联查询用户信息,使用resultType实现的测试
@Test
public void TestFindOrdersUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersCustomMapper oc = sqlSession.getMapper(OrdersCustomMapper.class);
// 调用mapper的方法
List<OrdersCustom> list = oc.findOrdersUser();
if(list !=null && list.size()>0){
System.out.println("一对一使用resultType实现:");
for(int i=0;i<list.size();i++){
OrdersCustom entity = (OrdersCustom)list.get(i);
System.out.println("订单id:"+entity.getId()+"----订单号:"+entity.getNumber()+
"----创建时间:"+DATE_FORMAT.format(entity.getCreateTime())+"----用户:"+entity.getUsername()); }
}
//System.out.println(list);
sqlSession.close();
} // 查询订单,关联查询用户信息,使用resultMap实现的测试
@Test
public void TestFindOrdersUserResultMap() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersCustomMapper oc = sqlSession.getMapper(OrdersCustomMapper.class);
// 调用mapper的方法
List<Orders> list = oc.findOrdersUserResultMap();
if(list !=null && list.size()>0){
System.out.println("\n一对一使用resultMap实现:");
for(int i=0;i<list.size();i++){
Orders entity = (Orders)list.get(i);
System.out.println("订单id:"+entity.getId()+"----订单号:"+entity.getNumber()+
"----创建时间:"+DATE_FORMAT.format(entity.getCreateTime())+
"----用户id:"+entity.getUser().getId()+
"----用户名:"+entity.getUser().getUsername()); }
}
System.out.print("\n");
sqlSession.close();
} }

运行结果:

一对一使用resultType实现:
订单id:1----订单号:1000010----创建时间:2015-06-04 13:22:35----用户:王五
订单id:2----订单号:1000011----创建时间:2015-07-08 13:22:41----用户:王五
订单id:3----订单号:1000012----创建时间:2015-07-17 14:13:23----用户:张三
订单id:4----订单号:1000013----创建时间:2015-07-16 18:13:23----用户:张小明
订单id:5----订单号:1000014----创建时间:2015-07-15 19:13:23----用户:陈小明
订单id:6----订单号:1000015----创建时间:2015-07-14 17:13:23----用户:张三丰
订单id:7----订单号:1000016----创建时间:2015-07-13 16:13:23----用户:陈小东 一对一使用resultMap实现:
订单id:1----订单号:1000010----创建时间:2015-06-04 13:22:35----用户id:1----用户名:王五
订单id:2----订单号:1000011----创建时间:2015-07-08 13:22:41----用户id:1----用户名:王五
订单id:3----订单号:1000012----创建时间:2015-07-17 14:13:23----用户id:2----用户名:张三
订单id:4----订单号:1000013----创建时间:2015-07-16 18:13:23----用户id:3----用户名:张小明
订单id:5----订单号:1000014----创建时间:2015-07-15 19:13:23----用户id:4----用户名:陈小明
订单id:6----订单号:1000015----创建时间:2015-07-14 17:13:23----用户id:5----用户名:张三丰
订单id:7----订单号:1000016----创建时间:2015-07-13 16:13:23----用户id:6----用户名:陈小东

5、resultType和resultMap实现一对一查询小结

实现一对一查询:

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

b.如果没有查询结果的特殊要求建议使用resultType。

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

d.resultMap可以实现延迟加载,resultType无法实现延迟加载。

三、一对多查询

3.1、需求:查询订单(关联用户)及订单明细;

3.2、在orders.java类中添加List<orderDetail> orderDetails属性(上面实体已添加)

最终会将订单信息映射到orders中,订单所对应的订单明细映射到orders中的orderDetails属性中.

3.3、在ordersCustomMapper.xml中添加如下代码

1、定义resultMap

<!-- 查询订单(关联用户)及订单明细的resultMap -->
<resultMap type="com.mybatis.entity.Orders" id="ordersAndOrderDetailResultMap" extends="OrdersUserResultMap">
<!-- 订单信息 -->
<!-- 关联用户信息 -->
<!-- 使用extends继承,不用再配置订单信息和用户信息的映射--> <!-- 关联订单明细信息 , 一个订单关联查询出了多条订单明细,要使用collection映射
collection:对关联查询到的多条记录映射到集合中
property:将关联查询到的多条记录映射到orders类的那个属性
ofType:指定映射的集合属性中pojo的类型
-->
<collection property="orderdetails" ofType="com.mybatis.entity.OrderDetail">
<!-- id:唯一标识
property:要将订单明细的唯一标识映射到com.mybatis.entity.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>

2、statement定义

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

3.4、在OrdersCustomMapper.java接口类中添加一个方法

/**查询订单(关联用户)以及订单明细*/
public List<OrderDetail>findOrdersAndOrderDetailResultMap();

3.5、在Junit测试类中添加测试方法

// 查询订单(关联用户)以及订单明细的测试
@Test
public void TestFindOrdersAndOrderDetailResultMap() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersCustomMapper oc = sqlSession.getMapper(OrdersCustomMapper.class);
// 调用mapper的方法
List<Orders> list = oc.findOrdersAndOrderDetailResultMap();
if(list !=null && list.size()>0){
System.out.println("一对多测试:");
for(int i=0;i<list.size();i++){
System.out.println("订单关联用户信息:");
Orders entity = (Orders)list.get(i);
System.out.println("订单id:"+entity.getId()+"----订单号:"+entity.getNumber()+
"----创建时间:"+DATE_FORMAT.format(entity.getCreateTime())+
"----用户id:"+entity.getUser().getId()+
"----用户名:"+entity.getUser().getUsername());
List orderDetailList = entity.getOrderdetails();
if(orderDetailList!=null && orderDetailList.size()>0){
System.out.println("订单明细:");
for(int k=0;k<orderDetailList.size();k++){
OrderDetail od = (OrderDetail)orderDetailList.get(k);
System.out.println("商品id:"+od.getItemsId()+"----商品数量:"+od.getItemsNum());
}
}
System.out.print("\n");
}
} sqlSession.close();
}

运行结果:

一对多测试:
订单关联用户信息:
订单id:1----订单号:1000010----创建时间:2015-06-04 13:22:35----用户id:1----用户名:王五
订单明细:
商品id:1----商品数量:1
商品id:2----商品数量:3 订单关联用户信息:
订单id:2----订单号:1000011----创建时间:2015-07-08 13:22:41----用户id:1----用户名:王五
订单明细:
商品id:3----商品数量:4 订单关联用户信息:
订单id:3----订单号:1000012----创建时间:2015-07-17 14:13:23----用户id:2----用户名:张三
订单明细:
商品id:2----商品数量:3

3.6、小结 

mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。

四、多对多查询

4.1、需求:查询用户以及用户购买的商品信息

4.2、映射思路

将用户信息映射到user中;

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

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

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

4.3、在ordersCustomMapper.xml中添加如下代码

1、定义resultMap

<!-- 查询用户即购买的商品信息的ResultMap -->
<resultMap type="com.mybatis.entity.User" id="userAndItemsResultMap">
<!-- 用户信息 -->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/> <!-- 订单信息, 一个用户对应多个订单,使用collection映射 -->
<collection property="ordersList" ofType="com.mybatis.entity.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.mybatis.entity.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.mybatis.entity.Items">
<id column="items_id" property="id"/>
<result column="items_name" property="itemsName"/>
<result column="items_detail" property="detail"/>
<result column="items_price" property="price"/>
</association>
</collection>
</collection> </resultMap>

2、statement定义

<!-- 查询用户及用户购买的商品信息,使用resultMap-->
<select id="findUserAndItemsResultMap" resultMap="userAndItemsResultMap">
SELECT t1.*,t2.username,t2.sex,t2.address,t3.id orderdetail_id,t3.items_id,
t3.items_num,t3.orders_id,t4.itemsname items_name,t4.detail items_detail,t4.price items_price
FROM orders t1,t_user t2,orderdetail t3,items t4
WHERE t1.user_id = t2.id AND t3.orders_id=t1.id AND t3.items_id = t4.id
</select>

4.4、在OrdersCustomMapper.java添加如下方法

/** 多对多:查询用户及用户所购买的商品信息 */
public List<User> findUserAndItemsResultMap();

4.5、在Junit测试类中添加测试方法

/**
* 多对多查询
* 查询用户及用户购买的商品的信息
*/
@Test
public void TestFindUserAndItemsResultMap() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersCustomMapper oc = sqlSession.getMapper(OrdersCustomMapper.class);
// 调用mapper的方法
List<User> list = oc.findUserAndItemsResultMap();
if(list !=null && list.size()>0){
System.out.println("多对多测试:");
for(int i=0;i<list.size();i++){
System.out.println("用户信息:");
User entity = (User)list.get(i);
System.out.println("用户id:"+entity.getId()+
"----用户名:"+entity.getUsername()); List ordersList = entity.getOrdersList();
if(ordersList!=null && ordersList.size()>0){
System.out.println("\n用户购买的商品:");
for(int k=0;k<ordersList.size();k++){
Orders o = (Orders)ordersList.get(k);
List orderDetailList = o.getOrderdetails(); if(orderDetailList!=null && orderDetailList.size()>0){
for(int m=0;m<orderDetailList.size();m++){
OrderDetail d = (OrderDetail)orderDetailList.get(m);
Items item = d.getItems();
if(item != null){
System.out.println("商品id:"+item.getId()+
"----商品名:"+item.getItemsName()+"----价格:"+item.getPrice()+
"----商品描述:"+item.getDetail());
}
}
}
}
System.out.print("\n");
}
}
} sqlSession.close();
}

测试结果:

多对多测试:
用户信息:
用户id:1----用户名:王五 用户购买的商品:
商品id:1----商品名:台式机----价格:3000.0----商品描述:该电脑质量非常好!
商品id:2----商品名:笔记本----价格:6000.0----商品描述:笔记本性能好,质量好!
商品id:3----商品名:背包----价格:200.0----商品描述:名牌背包,容量大质量好! 用户信息:
用户id:2----用户名:张三 用户购买的商品:
商品id:2----商品名:笔记本----价格:6000.0----商品描述:笔记本性能好,质量好!

五、resultType和resultMap总结

1、resultType:

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

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

2、resultMap

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

(1)association:

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

场合:为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。

(2)collection:

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

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

Mybatis学习总结(六)——高级映射(一对一,一对多,多对多)的更多相关文章

  1. mybatis入门基础(六)----高级映射(一对一,一对多,多对多)

    一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id INT NOT NULL AUTO_INCREMENT, itemsname ) NOT ...

  2. 【MyBatis学习08】高级映射之一对一查询

    从这一篇博文开始,将总结一下mybatis中的几个高级映射,即一对一.一对多.多对多查询,这篇先总结一下mybatis中的一对一查询.  为了模拟这些需求,事先要建立几个表,不同的表之间将对应上面提到 ...

  3. 【MyBatis学习09】高级映射之一对多查询

    上一篇博文总结了一下一对一的映射,本文主要总结一下一对多的映射,从上一篇文章中的映射关系图中可知,订单项和订单明细是一对多的关系,所以本文主要来查询订单表,然后关联订单明细表,这样就有一对多的问题出来 ...

  4. 【MyBatis学习10】高级映射之多对多查询

    本文来总结一下mybatis中的多对多映射,从第8节的文章中可以看出,用户表和商品表示多对多关系,它们两的多对多是通过订单项和订单明细这两张表所关联起来的,那么这一节主要来总结一下用户表和商品表之间的 ...

  5. mybatis关联查询基础----高级映射

    本文链接地址:mybatis关联查询基础----高级映射(一对一,一对多,多对多) 前言: 今日在工作中遇到了一个一对多分页查询的问题,主表一条记录对应关联表四条记录,关联分页查询后每页只显示三条记录 ...

  6. Mybatis学习(三)————— 映射文件详解

    前面说了全局配置文件中内容的详解,大家应该清楚了,现在来说说这映射文件,这章就对输入映射.输出映射.动态sql这几个知识点进行说明,其中高级映射(一对一,一对多,多对多映射)在下一章进行说明. 一.输 ...

  7. mybatis学习笔记(7)-输出映射

    mybatis学习笔记(7)-输出映射 标签: mybatis mybatis学习笔记7-输出映射 resultType 输出简单类型 输出pojo对象和pojo列表 resultMap result ...

  8. mybatis 一对一 一对多 多对多

    一对一 一对多 多对多

  9. JPA级联(一对一 一对多 多对多)注解【实际项目中摘取的】并非自己实际应用

    下面把项目中的用户类中有个:一对一  一对多  多对多的注解对应关系列取出来用于学习      说明:项目运行正常 问题类:一对多.一对一.多对多 ============一对多 一方的设置 @One ...

  10. Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作

    Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作,单表查询,多表查询 一丶表与表之间的关系 背景: ​ ​ ​  ​ ​ 由于如果只使用一张表存储所有的数据,就会操作数 ...

随机推荐

  1. Windows下git设置代理服务器

    SVN中,使用TortoiseSVN来进行版本控制时,设置代理非常简单,只需要在设置里面添加代理的信息即可.而 git 在GUI(v0.17.GITGUI)中却无法找到类似的设置,只能求助 git b ...

  2. Java 线程方法

    线程标识相关 方法 描述 public Thread(Runnable target, String name)  带参数的构造方法, 第二个参数是线程名称 public static Thread ...

  3. Salesforce 大量数据部署的最佳实践

    本文参考自官方文档.原文链接 大量数据部署对Salesforce的影响 当用户需要在Salesforce中部署大量数据的时候,部署的过程往往会变慢.这时就需要架构师或开发者设计出更好的过程来提高大量数 ...

  4. 17.Odoo产品分析 (二) – 商业板块(10) – 电子商务(1)

    查看Odoo产品分析系列--目录 安装电子商务模块 1. 主页 点击"商店"菜单:  2. 添加商品 在odoo中,你不用进入"销售"模块,再进入产品列表添加产 ...

  5. Javascript 流程控制

    流程控制 JavaScript通过流程语句来执行程序流,程序流有若干语句组成.在正常情况下,程序中 的语句时按照书写顺序执行的,这种结构称为顺序结构.除了顺序结构之外还有选择结构和循环结构. 1.选择 ...

  6. (python)数据结构---集合

    一.描述 set翻译为集合 set是可变的.无序的.不可重复的 set的元素要求可哈西(不可变的数据类型可哈西,可变的数据类型不可哈希) set是无序的,因此不可以索引,也不可以修改 线型结构的查询时 ...

  7. Win10更新

    Turn: https://m.uczzd.cn/webview/news?app=meizubrw-iflow&aid=11529477703533248224&cid=100&am ...

  8. Python常用的数据类型转换

    在实际开发中.经常要根据需求来转变一些变量的类型. 需要用到以下函数:

  9. 个人对于 Maven 的理解

    个人对于 Maven 的理解 Maven 一直都在使用, 但如果说是不是真的懂 Maven, 很难谈得上. 或许什么时候系统地学习一下, 但在那之前, 打算先记下自己目前对于 Maven 的理解, 之 ...

  10. vim 基础命令大全

         VIM命令大全 光标控制命令 命令                   光标移动h                   向左移一个字符j                   向下移一行k  ...