Mybatis(四) 高级映射,一对一,一对多,多对多映射

      天气甚好,怎能不学习?

 

一、单向和双向

    包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在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,1)">45             orders.user_id,1)">46             orders.createtime,1)">47             user.id uid,1)">48             user.username,1)">49             user.sex
50          FROM orders,user WHERE orders.id = #{id} AND orders.user_id = user.id    
51     </select>
52     
53     
54 </mapper>
View Code

     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时,才会进行查询加载,这就是延迟加载,也称为懒加载,具体下一节讲解。下一节还会讲解一级缓存,二级缓存的问题。

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1.pom.xml引入依赖 &lt;dependency&gt; &lt;groupId&gt;com.github.pagehelper&lt;/groupId&gt; &lt;artifactId&gt;pagehelper&lt;/artifactId&gt; &lt;version&gt;5
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt; &lt;!DOCTYPE configuration PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot; &qu
准备工作 ① 创建数据库&amp;数据表 ## 创建数据库 CREATE DATABASE `dbtest1`; ## 创建数据表 CREATE TABLE `t_user` ( `id` INT NOT NULL AUTO_INCREMENT, `username` VARCHAR(20) DEF
MyBatis逆向工程是指根据数据库表结构自动生成对应的实体类、Mapper接口以及SQL映射文件的过程。这个过程可以通过MyBatis提供的逆向工程工具来完成,极大地方便了开发人员,避免了重复的代码编写,提高了开发效率。 创建逆向工程的步骤 1、添加依赖&amp;插件 &lt;!-- 控制Mave
MyBatis获取参数值的两种方式:${}和#{} ${}的本质就是字符串拼接,#{}的本质就是占位符赋值。 ${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自
resultMap作用是处理数据表中字段与java实体类中属性的映射关系。 准备工作 ① 创建数据库&amp;数据表 CREATE DATABASE `dbtest1`; CREATE TABLE `t_emp` ( `emp_id` int NOT NULL AUTO_INCREMENT, `em
EHCache缓存针对于MyBatis的二级缓存。 MyBatis默认二级缓存是SqlSessionFactory级别的。 添加依赖 &lt;!-- MyBatis-EHCache整合包 --&gt; &lt;dependency&gt; &lt;groupId&gt;org.mybatis.cac
MyBatis 提供了一级缓存和二级缓存的支持,用于提高数据库查询的性能,减少不必要的数据库访问。 一级缓存(SqlSession 级别的缓存) 一级缓存是 MyBatis 中最细粒度的缓存,也称为本地缓存。它存在于每个 SqlSession 的生命周期中,当 SqlSession 被关闭或清空时,
动态SQL是 MyBatis 中非常强大且灵活的功能,允许你根据不同的条件构建SQL查询。 这主要通过 &lt;if&gt;、&lt;choose&gt;、&lt;when&gt;、&lt;otherwise&gt;、&lt;foreach&gt;等标签实现。 查询场景 /** * 根据条件查询员工
本教程操作系统:windows10系统、DELL G3电脑。 MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。在 MyBatis 中,配置数据库连接是非常重要的第一步。下面将详细介绍如何配置 MyBatis 的
今天小编给大家分享的是MyBatis批量查询、插入、更新、删除如何实现,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。
今天小编给大家分享的是Mybatis操作多数据源实现的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获...
本篇文章和大家了解一下mybatis集成到spring的方式有哪些。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1 前言1.1 集成spring前使用mybat...
今天小编给大家分享的是mybatis-plus分页查询的3种方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获...
本篇内容主要讲解“mybatis之BaseTypeHandler怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mybatis...
这篇文章主要介绍了mybatisforeach怎么传两个参数的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mybatisforeach怎...
这篇“MyBatis映射文件中parameterType与resultType怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的...
这篇文章主要介绍“MyBatis怎么获取自动生成的键值”,在日常操作中,相信很多人在MyBatis怎么获取自动生成的键值问题上存在疑惑,小编查阅了各式资料,整理出
这篇文章主要讲解了“怎么去掉IntelliJIDEA中mybatis对应的xml文件警告”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入...
这篇文章主要介绍“MybatisPlus使用@TableId主键id自增长无效如何解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这...