一、单向和双向

    包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部门,一个部门中有多个员工,从部门方看,是一对多关系,而多名员工属于一个部门,是多对一关系,那么如果我们的业务需求只需要通过部门查找到所有的员工,那么我们就只需要进行单向一对多的映射,如果我们需要通过员工来查询出对应的部门,那么我们就需要进行单向多对一的映射,而如果我们这两个业务需求都需要实现,也就是不管从哪一方进行查找,都需要能够找到对方,那么此时就应该编写双向一对多或者双向多对一(双向一对多和双向多对一是一样的意思)。所以,不管是编写哪一种,都是根据业务需求来进行决策的。这就是单向和双向的意思。

    什么是多对多?

       多对多就是不管从哪一方看,都是一对多,那么该关系就是多对多。比如学生跟选修课之间,从学生方看,一个学生能选多门选修课,一对多关系,从选修课之间,一门选修课可以被多个学生选择,也是一对多关系,那么学生跟选修课就是多对多关系。多对多关系之间都会由第三张表来表示这种关系。而不会相互设置外键。

二、测试环境

       

       

三、一对一映射

    有了上面这个关系图,那我们测试就好做多了,就拿orders 和user来测试,从orders方看向user方,就是一对一映射。也就是单向一对一,只需要根据orders能找出user即可。

    两种方案,映射文件中输出映射使用resultType和resultMap。这里只关注映射文件,全局配置文件就不多说了,还是老样子的配置

    3.1、使用resultType

        UserMapper.xml

            

        UserExt.java

          因为需要在查询orders时,将对应的user也查询出来,那么使用resultType的话,就需要创建一个OrdersExt,将user和orders中的属性合并在一起,形成一个新的pojo。这样就能够将查询出来的记录都映射到该pojo上了

            

    3.2、使用resultMap

        usermapper.xml

            

          resultMap

              使用resultMap的话就不需要构造一个新的pojo,只需要将查询出来的记录的值通过resultMap帮我们映射到指定到哪个pojo的哪个属性上即可。

            

 1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="com.wuhao.onetoone.resultMap.UserMapper">
6 <!--
7 resultMap
8 type:返回对象类型。全限定名,如果使用了typeAliases设置别名,则可以使用别名
9 id:唯一标识,供下面使用
10 id标签:唯一标识位,也就是主键。
11 column:从数据库中查询出来的列名。有时候会使用别名,主要看sql语句返回的列名是什么
12 property:对应返回对象中属性名
13 result标签:映射普通属性
14 column和property跟上面一样的功能
15 -->
16 <resultMap type="com.wuhao.onetoone.resultMap.Orders" id="findOrdersAndUserReM">
17 <id column="oid" property="id"/>
18 <result column="number" property="number"/>
19 <result column="user_id" property="userId"/>
20 <result column="createtime" property="createtime"/>
21 <!-- 用户信息,
22 association:一对一映射
23 property:把关联查询的一对一的信息封装到哪个对象属性上
24 javaType:property属性的类型
25 其他的什么id,result标签都跟上面的一样。
26 -->
27 <association property="user" javaType="com.wuhao.onetoone.resultMap.User">
28 <id column="uid" property="id"/>
29 <result column="username" property="username"/>
30 <result column="sex" property="sex"/>
31 </association>
32 </resultMap>
33
34 <!--
35 使用resultMap就能够解决这种麻烦,因为resultMap能进行高级映射,说是高级映射,其实就是可以将查询出来的列表映射到特定
36 的属性上去。
37 使用resultMap之后,就会知道resultType的区别在哪里了
38 resultType:简单一些,是一种平铺式的映射,不用层级式映射用这个比较好。需要什么查什么
39 resultMap:比较繁琐,是一种层级式的映射,在企业中如果没有特殊要求,建议使用resultType来完成一对一映射,
40 -->
41 <select id="findOrdersAndUserByOid" parameterType="int" resultMap="findOrdersAndUserReM">
42 SELECT
43 orders.id oid,
44 orders.number,
45 orders.user_id,
46 orders.createtime,
47 user.id uid,
48 user.username,
49 user.sex
50 FROM orders,user WHERE orders.id = #{id} AND orders.user_id = user.id
51 </select>
52
53
54 </mapper>
 1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="com.wuhao.onetoone.resultMap.UserMapper">
6 <!--
7 resultMap
8 type:返回对象类型。全限定名,如果使用了typeAliases设置别名,则可以使用别名
9 id:唯一标识,供下面使用
10 id标签:唯一标识位,也就是主键。
11 column:从数据库中查询出来的列名。有时候会使用别名,主要看sql语句返回的列名是什么
12 property:对应返回对象中属性名
13 result标签:映射普通属性
14 column和property跟上面一样的功能
15 -->
16 <resultMap type="com.wuhao.onetoone.resultMap.Orders" id="findOrdersAndUserReM">
17 <id column="oid" property="id"/>
18 <result column="number" property="number"/>
19 <result column="user_id" property="userId"/>
20 <result column="createtime" property="createtime"/>
21 <!-- 用户信息,
22 association:一对一映射
23 property:把关联查询的一对一的信息封装到哪个对象属性上
24 javaType:property属性的类型
25 其他的什么id,result标签都跟上面的一样。
26 -->
27 <association property="user" javaType="com.wuhao.onetoone.resultMap.User">
28 <id column="uid" property="id"/>
29 <result column="username" property="username"/>
30 <result column="sex" property="sex"/>
31 </association>
32 </resultMap>
33
34 <!--
35 使用resultMap就能够解决这种麻烦,因为resultMap能进行高级映射,说是高级映射,其实就是可以将查询出来的列表映射到特定
36 的属性上去。
37 使用resultMap之后,就会知道resultType的区别在哪里了
38 resultType:简单一些,是一种平铺式的映射,不用层级式映射用这个比较好。需要什么查什么
39 resultMap:比较繁琐,是一种层级式的映射,在企业中如果没有特殊要求,建议使用resultType来完成一对一映射,
40 -->
41 <select id="findOrdersAndUserByOid" parameterType="int" resultMap="findOrdersAndUserReM">
42 SELECT
43 orders.id oid,
44 orders.number,
45 orders.user_id,
46 orders.createtime,
47 user.id uid,
48 user.username,
49 user.sex
50 FROM orders,user WHERE orders.id = #{id} AND orders.user_id = user.id
51 </select>
52
53
54 </mapper>

     3.3、小总结

        现在应该认识到了resultMap和resultType的区别,需要知道resultMap中一对一映射时是怎么编写这种映射关系的。 

        上面所侧重的重点在映射文件statement的编写,

四、一对多映射

     查询订单信息,关联查询它的订单明细信息,orders --》 ordersdetail。 单向一对多关系,一个订单有多个订单项。

     4.1、使用resultType

        使用resultType也可以,按照前面的学习,需要构建一个新的pojo,其中包含了订单项属性和orders属性。这个很简单,而且都会做,就不多说了,主要说说使用resultMap的用法。

     4.2、使用resultMap

            

        其中注意resultMap中的extends的用法,继承一个resultMap,就把其中的所有配置都继承过来了,所以这里只需要编写一个collection,映射ordersdetail集合。

        pojo类中应该多了一个这个东西

              

        这里主要是关注,一对多时,resultMap中是如何实现的。使用collection。

五、多对多映射

      查询用户信息,以及它所购买的商品信息  user --》 items

      主表:user  

      从表:orders、orderdetail、items

      也就是通过查询某个user,查找到orders,通过orders查找到orderdetail,通过orderdetail查找到items。

      pojo

        一个用户拥有多个订单

            

        一个订单可以拥有多个订单明细

              

        一个订单明细对应一个商品

            

      usermapper.xml

            

        通过上面pojo和sql语句,可以知道,我们写的resultMap看起来好像需要很复杂,其实不然,一步步一层层进行编写,也不难。

            

        如果是一对多关系,那么就使用collection,如果是一对一,那么就使用association,先写user到orders,然后在写orders中的orderdetail,等等,这样一层层嵌套进去,也很明了。不难懂。

六、总结

      6.1、resultType和resultMap都可以完成高级结果映射

          如果没有特殊要求,使用resultType方便

      6.2、resultType和resultMap 的一个主要区别就是要应用场景不同

          resultType主要是查询明细使用

          resultMap主要是层级查询使用,比如查询用户信息,如何点击查询订单,再去查询订单信息

          resultMap可以实现延迟加载,而resultType没有该功能

      6.3、延迟加载就是我们下一章节要说的东西,这里就需要注意,resultMap菜可以实现延迟加载,那么什么是延迟加载呢?比如上面一对一关系中,通过orders查询到对应的user,当没有使用到user时,那么orders是不会查询出user的,等当使用user时,才会进行查询加载,这就是延迟加载,也称为懒加载,具体下一节讲解。下一节还会讲解一级缓存,二级缓存的问题。

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

  1. 【Mybatis高级映射】一对一映射、一对多映射、多对多映射

    前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...

  2. mybatis 一对一 一对多 多对多

    一对一 一对多 多对多

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

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

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

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

  5. mybatis入门_一对多,多对多映射以及整合spring框架

    一.一对多映射. 1.1 一对多映射之根据多的一方关联查询一的一方 示例:查询出具体的订单信息,同时也查询出来订单的用户信息. 引入的订单表如下所示: 框选出来的为具体的外键. 订单的Pojo类如下所 ...

  6. JPA 一对一 一对多 多对一 多对多配置

    1 JPA概述 1.1 JPA是什么 JPA (Java Persistence API) Java持久化API.是一套Sun公司 Java官方制定的ORM 方案,是规范,是标准 ,sun公司自己并没 ...

  7. day 69-70 一对一 一对多 多对一联表查询

    day 69 orm操作之表关系,多对多,多对一 多对一/一对多, 多对多{类中的定义方法} day69 1. 昨日内容回顾 1. 单表增删改查 2. 单表查询API 返回QuerySet对象的: 1 ...

  8. 使用NHibernate(7)-- 一对一 && 一对多 && 多对多

    1, 一对一. 对于数据量比较大的时候,考虑查询的性能,肯能会把一个对象的属性分到两个表中存放:比如用户和用户资料,经常使用的一般是Id和用户名,用户资料(学校,籍贯等)是不经常被查询的,所以就会分成 ...

  9. mybatis学习之高级映射

    一对一映射查询 1.数据库执行脚本: /* SQLyog Ultimate v12.09 (64 bit) MySQL - 5.7.11-log : Database - db_mybatis *** ...

  10. mybatis 学习四(下) SQL语句映射文件增删改查、参数、缓存

    2.2 select 一个select 元素非常简单.例如: <!-- 查询学生,根据id --> <select id="getStudent" paramet ...

随机推荐

  1. 将n个东西分成n1,n2,n3,n4,....nr 共 r组分给r个人有多少种分法。

    (n!/(n1! *n2! *n3!..nr!) )   * r!/( 同数量组A的数量! 同数量组B的数量!....) 比方20个东西分成2,2,,2,2   3,3,3,3 8组分给8个人有多少种 ...

  2. struct,map,json 互相转换

    1.1 struct to json 准备 很简单,使用encoding包可以互相转换,没什么好说的,但是有几点注意: 1.结构体内需要序列化的字段首字母大写(遵循驼峰式命名),不需要序列化的字段小写 ...

  3. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  4. Codeforces831C Jury Marks

    C. Jury Marks time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  5. 设置MessageBox自动关闭

    通过设置定时器,让定时器的Tick事件模拟往MessageBox发送一个Enter按钮代替用鼠标点击MessageBox上的确定按钮,来实现MessageBox的自动关闭,实现代码如下: System ...

  6. javascript中的replace方法

    1.replace 调用方法str.replace(regexp|substr, newSubStr|function) regexp,正则表达式 substr,需要被替换的字符串 newSubStr ...

  7. UICollectionView添加 HeaderView FooterView

    UICollectionView显示HeaderView FooterView 不如UITableView那么容易,常用会有两种做法: 1.Xib或者Storyboard 在属性一栏中设置一下: 如图 ...

  8. [转]Understand QoS at OpenSwitch

    danny http://dannykim.me/danny/57771 2014.02.11 14:34:58 (*.193.128.184) 592 >>> Purpose Th ...

  9. js实用方法记录-指不定哪天就会用到的js方法

    js实用方法记录-指不定哪天就会用到的js方法 常用或者不常用都有 判断是否在微信浏览器中 测试代码:isWeiXin()==false /** * 是否在微信中 */ function isWeix ...

  10. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    .引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...