http://blog.csdn.net/yerenyuan_pku/article/details/71894172

在实际开发中我们不可能只是对单表进行操作,必然要操作多表,本文就来讲解多表操作中的一对一关联映射和一对多(或多对一)关联映射,至于多对多关联映射实质上也是两个一对多(或多对一)关联映射,所以在这里我并不打算讲解。先从一对一关联映射讲起。本文案例代码的编写是建立在前文MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql案例基础之上的!

一对一关联映射

我以商品订单数据模型为例来讲解一对一关联映射,如下: 

一对一查询

有这样一个需求:查询所有订单信息,关联查询下单用户信息。 
注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询(值得注意的一点是这儿我将订单与用户的关系理解为一对多的关系,但实质上从订单角度出发,多个订单可属于一个用户,故订单与用户的关系应该是多对一的关系)。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。 
解决该需求,可有两种方法,先讲第一种方法。

方法一

使用resultType,定义订单信息po类,此po类中包括了订单信息和用户信息。在cn.itheima.mybatis.po包下新建一个OrderUser类:

public class OrderUser extends Orders { private String username; private String address; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }

OrderUser类继承Orders类后,OrderUser类包括了Orders类的所有字段,只需要定义用户的信息字段即可。 
接着按照需求编写sql语句,在OrderMapper.xml映射文件中添加如下select元素:

<select id="getOrderUserList" resultType="orderuser">SELECTo.id,o.user_id userId,o.number, o.createtime, o.note, u.username, u.address FROM orders o LEFT JOIN `user` u ON o.user_id = u.id </select>

紧接着在OrderMapper接口中编写如下方法:

List<OrderUser> getOrderUserList();
  • 1
  • 1

最后在OrderMapperTest单元测试类中编写如下测试方法:

@Test
public void testGetOrderUserList() {SqlSession sqlSession = sqlSessionFactory.openSession();OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<OrderUser> orderList = orderMapper.getOrderUserList(); for (OrderUser orderUser : orderList) { System.out.println(orderUser); } sqlSession.close(); }

在testGetOrderUserList方法中的以下代码处打一个断点:

for (OrderUser orderUser : orderList) {
  • 1
  • 1

然后以Debug模式运行该方法,大概就能看到你想要的结果了。 
小结:定义专门的po类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较为简单,企业中使用普遍

方法二

使用resultMap,定义专门的resultMap用于映射一对一查询结果。首先在Orders类中加入user属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。这样Orders类的代码为:

public class Orders {private Integer id;private Integer userId;private String number; private Date createtime; private String note; private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } 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(); } }

然后在OrderMapper.xml映射文件中添加如下select元素:

<select id="getOrderUserResultMap" resultMap="order_user_resultmap">SELECTo.id,o.user_id,o.number, o.createtime, o.note, u.username, u.address FROM orders o LEFT JOIN `user` u ON o.user_id = u.id </select>
  • 1

上面id为order_user_resultmap的resultMap也须定义,如下:

<resultMap type="orders" id="order_user_resultmap"> <id property="id" column="id"/> <result property="userId" column="user_id" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> <!-- 配置一对一关联映射 --> <association property="user" javaType="cn.itheima.mybatis.po.User"> <id property="id" column="user_id"/> <result property="username" column="username"/> <result property="address" column="address"/> </association> </resultMap>
  • 1

这里resultMap指定order_user_resultmap。

  • association:表示进行关联查询单条记录。
  • property:表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中。即property对应Orders类里面一对一关联映射的那个属性,即user属性。
  • javaType:表示关联查询的结果类型。即user属性的数据类型,可使用别名。
  • <id property="id" column="user_id"/>:查询结果的user_id列对应关联对象的id属性,这里是<id />表示user_id是关联查询对象的唯一标识。
  • <result property="username" column="username"/>:查询结果的username列对应关联对象的username属性。

OrderMapper.xml映射文件配置之后,在OrderMapper接口中编写如下方法:

List<Orders> getOrderUserResultMap();
  • 1
  • 1

最后在OrderMapperTest单元测试类中编写如下测试方法:

@Test
public void testGetOrderUserResultMap() {SqlSession sqlSession = sqlSessionFactory.openSession();OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<Orders> orderList = orderMapper.getOrderUserResultMap(); for (Orders orders : orderList) { System.out.println(orders); } sqlSession.close(); }

在testGetOrderUserResultMap方法中的以下代码处打一个断点:

for (Orders orders : orderList) {
  • 1
  • 1

然后以Debug模式运行该方法,大概就能看到你想要的结果了。 
小结:使用association完成关联查询,将关联查询信息映射到pojo对象中

一对多关联映射

现有这样一个需求:查询所有用户信息及用户关联的订单信息。这儿,用户信息和订单信息为一对多关系。在此,我使用resultMap来实现。 
为了解决该需求,在User类中加入List<Orders> orders属性,这样User类的代码就为:

public class User {private Integer id; // int类型的id是不可能为null的!private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String address;// 地址 private List<Orders> orders; public List<Orders> getOrders() { return orders; } public void setOrders(List<Orders> orders) { this.orders = orders; } 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 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; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address + "]"; } }

然后在OrderMapper.xml映射文件中添加如下select元素:

<select id="getUserWithOrders" resultMap="user_order_resultmap">SELECTu.id,u.username,u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN orders o ON u.id = o.user_id </select>
  • 1

上面id为user_order_resultmap的resultMap也须定义,如下:

<!-- 一对多关联映射 -->
<resultMap type="user" id="user_order_resultmap"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="birthday" column="birthday"/> <result property="sex" column="sex"/> <result property="address" column="address"/> <!-- 配置一对多关联映射 --> <collection property="orders" ofType="orders"> <!-- id对应Orders类的主键属性 --> <id property="id" column="oid"/> <result property="number" column="number"/> <result property="createtime" column="createtime"/> <result property="note" column="note"/> </collection> </resultMap>

这里resultMap指定user_order_resultmap。

  • collection部分定义了用户关联的订单信息。表示关联查询结果集。
  • property=”orders”:关联查询的结果集存储在User对象的哪个属性上。即property对应User对象中的集合属性。
  • ofType=”orders”:指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。
  • <id /><result/>的意义同一对一查询。

OrderMapper.xml映射文件配置之后,在OrderMapper接口中编写如下方法:

List<User> getUserWithOrders();
  • 1
  • 1

最后在OrderMapperTest单元测试类中编写如下测试方法:

@Test
public void testGetUserWithOrders() {SqlSession sqlSession = sqlSessionFactory.openSession();OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<User> userList = orderMapper.getUserWithOrders(); for (User user : userList) { System.out.println(user); } sqlSession.close(); }

在testGetUserWithOrders方法中的以下代码处打一个断点:

for (User user : userList) {

然后以Debug模式运行该方法,大概就能看到你想要的结果了。 
至此,一对一关联映射和一对多关联映射 
我就已总结完了,觉得总结得蛮走心的。读者如需查看源码,可参考MyBatis框架的学习(五)——一对一关联映射和一对多关联映射

转载于:https://www.cnblogs.com/telwanggs/p/6911825.html

(转)MyBatis框架的学习(五)——一对一关联映射和一对多关联映射相关推荐

  1. (转)MyBatis框架的学习(六)——MyBatis整合Spring

    http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...

  2. (转)MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql

    http://blog.csdn.net/yerenyuan_pku/article/details/71893689 前面对MyBatis框架的学习中,我们对Mapper.xml映射文件多少有些了解 ...

  3. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图:  下面作简要概述: ...

  4. (转)MyBatis框架的学习(七)——MyBatis逆向工程自动生成代码

    http://blog.csdn.net/yerenyuan_pku/article/details/71909325 什么是逆向工程 MyBatis的一个主要的特点就是需要程序员自己编写sql,那么 ...

  5. (转)MyBatis框架的学习(三)——Dao层开发方法

    http://blog.csdn.net/yerenyuan_pku/article/details/71700957 使用MyBatis开发Dao层,通常有两个方法,即原始Dao开发方法和Mappe ...

  6. 1、MyBatis框架入门学习CRUD

    文章目录 框架前言 名词辨析 JavaWeb阶段回顾 框架介绍 ORM框架 MyBatis简介 MyBatis入门案例 1.环境准备 2.新建普通Maven项目,导入依赖 3.MyBatis核心配置文 ...

  7. (转)MyBatis框架的学习(一)——MyBatis介绍

    http://blog.csdn.net/yerenyuan_pku/article/details/71699343 MyBatis介绍 MyBatis本是apache的一个开源项目iBatis,2 ...

  8. 【Mybatis】 mapper XML 文件中使用 collection实现一对多关联

    前言 Mybatis 一对一,使用 association 标签 Mybatis 一对多,使用 collection 标签 本文主要说明 collection 实现一对多关联.使用 associati ...

  9. Mybatis多表关联查询(一对多关联查询)

    1.Mybatis一级缓存与二级缓存 目的:提高查询效率,降低数据库查询压力,提升系统整体性能. 一级缓存:默认开启,Session级别,同一个会话内生效. 命中缓存的情况:statementid.S ...

最新文章

  1. javascript(js)的小数点乘法除法问题
  2. golang 面向对象编程
  3. go语言之行--基础部分
  4. 小明分享:SSD201/202系统烧录篇,多种烧录方式,小明都做了分享,有需要的小伙伴拿走不谢哈!更多资料需求可以关注我,我是启明云端的小明MM!
  5. 移动端下拉刷新原理和实例
  6. php变量原格式输出,PHP格式化输出打印变量
  7. 老男孩教育学员参观机房实践活动
  8. java考前复习之数组
  9. linux文件名快速键入,linux修改文件名【使用模式】
  10. 问个globle的问题,如何定时更新论坛的数据啊?
  11. 修改win10 ntp服务器地址,修改win10 ntp服务器地址
  12. 微信小程序----地理围栏实现员工防作弊地图打卡功能
  13. win10重装系统打开分区或者磁盘提示无法访问解决办法
  14. 阻容感基础06:电容器分类(1)-陶瓷电容
  15. Quartz 使用(2.x版本)
  16. 上海计算机考试分值,上海高考科目及分值
  17. Cryptarithmetic Problem ‘ODD+ODD == EVEN’;map()函数,reduce()
  18. win10 系统连接 wifi 的小地球图标还在但 wifi 选项没有了的解决办法
  19. 脉冲神经网络(SNN)论文阅读(三)-----高精度低时延的ANN转换SNN方法
  20. 期末大作业 | ToDoList网页设计 日记本界面设计记录

热门文章

  1. 计算机安装最新的安全补丁,Win10不要装!微软发布4月安全补丁合集
  2. python批量更改文件后缀名
  3. 不使用总线矩阵的CortexM3最小系统搭建(AHB外设有ITCM,DTCM,DEFAULT_SLAVE和AHB_APB桥,APB外设只有一个UART)附整个工程
  4. html 动物特效,分享9款用HTML5/CSS3制作的动物人物动画,
  5. 思科模拟器企业网站服务器配置,思科模拟器服务器配置
  6. 获取json配置_ASP.NET Core集成Nacos配置中心之适配多格式配置
  7. 【LeetCode】【HOT】104. 二叉树的最大深度(BFS+队列/递归)
  8. 发现kafka丢消息后的排查
  9. 一次性计划任务at与周期性计划任务crontab
  10. 使用Jedis操作redis