新闻  |   论坛  |   博客  |   在线研讨会
扣丁学堂Java培训之Mybatis中是如何实现这种多表关系的
扣丁客 | 2020-12-09 14:31:25    阅读:1051   发布文章

在现实的项目中进行数据库建模时,我们要遵循数据库设计范式的要求,会对现实中的业务模型进行拆分,封装在不同的数据表中,表与表之间存在着一对多或是多对多的对应关系。进而,我们对数据库的增删改查操作的主体,也就从单表变成了多表。那么Mybatis中是如何实现这种多表关系的映射呢?

查询结果集ResultMap

resultMap元素是MyBatis中最重要最强大的元素。它就是让你远离90%的需要从结果集中取出数据的JDBC代码的那个东西,而且在一些情形下允许你做一些JDBC不支持的事情。事实上,编写相似于对复杂语句联合映射这些等同的代码,也许可以跨过上千行的代码。

有朋友会问,之前的示例中我们没有用到结果集,不是也可以正确地将数据表中的数据映射到Java对象的属性中吗?是的。这正是resultMap元素设计的初衷,就是简单语句不需要明确的结果映射,而很多复杂语句确实需要描述它们的关系。

resultMap元素中,允许有以下直接子元素:

constructor-类在实例化时,用来注入结果到构造方法中(本文中暂不讲解)

id-作用与result相同,同时可以标识出用这个字段值可以区分其他对象实例。可以理解为数据表中的主键,可以定位数据表中唯一一笔记录

result-将数据表中的字段注入到Java对象属性中

association-关联,简单的讲,就是“有一个”关系,如“用户”有一个“帐号”

collection-集合,顾名思议,就是“有很多”关系,如“客户”有很多“订单”

discriminator-使用结果集决定使用哪个个结果映射(暂不涉及)

1、嵌套查询映射

嵌套查询映射:通过执行另外一个SQL映射语句来返回预期的复杂类型。

想查询出订单的时候去给我关联查询出该订单所属于的用户信息。(查询一张表)

users表和orders表两张表如下:

  
  CREATETABLE`users`(
  `uid`bigint(20)NOTNULLAUTO_INCREMENT,
  `uname_uu`varchar(255)DEFAULTNULL,
  `upwd`varchar(255)DEFAULTNULL,
  `sex`varchar(255)DEFAULTNULL,
  `birthday`dateDEFAULTNULL,
  PRIMARYKEY(`uid`)
  )ENGINE=InnoDBAUTO_INCREMENT=20DEFAULTCHARSET=utf8;
  CREATETABLE`orders`(
  `oid`bigint(255)NOTNULLAUTO_INCREMENT,
  `oprice`doubleDEFAULTNULL,
  `createtime`datetimeDEFAULTNULL,
  `flag`varchar(255)DEFAULTNULLCOMMENT'订单的状态',
  `uid`bigint(20)DEFAULTNULLCOMMENT'外键',
  PRIMARYKEY(`oid`),
  KEY`uid`(`uid`),
  CONSTRAINT`orders_ibfk_1`FOREIGNKEY(`uid`)REFERENCES`users`(`uid`)
  )ENGINE=InnoDBAUTO_INCREMENT=4DEFAULTCHARSET=utf8;
  UserMapper配置文件如下:
  <!--关联查询出一方-->
  <!--查询订单的时候去关联查询用户-->
  <!--a.嵌套查询映射只查询一个表-->
  <selectid="queryOrderWithUser"resultMap="OrderAndUserMap">
  select*fromorders
  </select>
  <!--定义一个resultMap-->
  <!--type:pojo类id:resultMap的唯一标志-->
  <resultMaptype="order"id="OrderAndUserMap">
  <!--如果column和pojo属性名(property)一致可以不写-->
  <idcolumn="oid"property="oid"/>
  <!--关联查询出一方
  column:外键字段
  property:关联对象的属性名
  javaType:写pojo类的类型
  select:写statement对象的id值
  -->
  <associationcolumn="uid"property="user"javaType="user"select="queryUserByUid">
  <!--<resultcolumn="uname_uu"property="uname"/>-->
  </association>
  </resultMap>
  <selectid="queryUserByUid"parameterType="long"resultMap="myUserMap1">
  select*fromuserswhereuid=#{uid}
  </select>
  <!--配置resultMap-->
  <!--需要配置需要的所有属性不管列明和属性名是否一致-->
  <resultMaptype="order"id="OrderAndUserMap2">
  <idcolumn="oid"property="oid"/>
  <resultcolumn="oprice"property="oprice"/>
  <resultcolumn="flag"property="flag"/>
  <resultcolumn="createtime"property="createtime"/>
  <!--
  property:属性名
  javaType:pojo的类型也可以通过resulteMap指定返回的结果集
  -->
  <associationproperty="user"resultMap="myUserMap1"/>
  </resultMap>
  UserMapper.java接口方法如下:
  //查询订单去关联查询用户
  List<Order>queryOrderWithUser();
  测试代码:
  ////14.查询订单去关联查询用户嵌套查询映射
  @Test
  publicvoidrun14()throwsIOException{
  UserMappermapper=sqlSession.getMapper(UserMapper.class);
  List<Order>c=mapper.queryOrderWithUser();
  System.out.println(c);
  }


2、嵌套结映射

嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。

  UserMapper.xml
  <selectid="queryUserWithOrder2"resultMap="OrderAndUserMap2">
  <!--sql左外连接查询-->
  select*fromordersasoleftouterjoinusersasuono.uid=u.uid;
  </select>
  <!--配置resultMap-->
  <!--需要配置需要的所有属性不管列明和属性名是否一致-->
  <resultMaptype="order"id="OrderAndUserMap2">
  <idcolumn="oid"property="oid"/>
  <resultcolumn="oprice"property="oprice"/>
  <resultcolumn="flag"property="flag"/>
  <resultcolumn="createtime"property="createtime"/>
  <!--
  property:属性名
  javaType:pojo的类型也可以通过resulteMap指定返回的结果集
  -->
  <associationproperty="user"resultMap="myUserMap1"/>
  </resultMap>
  <resultMaptype="user"id="myUserMap1">
  <!--配置主键映射
  column:表的字段
  property:pojo的属性
  -->
  <idcolumn="uid"property="uid"/>
  <!--配置普通属性-->
  <resultcolumn="uname_uu"property="uname"/>
  <resultcolumn="sex"property="sex"/>
  <resultcolumn="birthday"property="birthday"/>
  </resultMap>
  UserMapper.java接口方法如下:
  //查询订单去关联查询用户
  List<Order>queryOrderWithUser2();
  测试代码:
  ////14.查询订单去关联查询用户嵌套查询映射
  @Test
  publicvoidrun14()throwsIOException{
  UserMappermapper=sqlSession.getMapper(UserMapper.class);
  List<Order>c=mapper.queryOrderWithUser2();
  System.out.println(c);
  }


3、查询2个表

自己整一个pojo类把需要用到的user表的字段和order表的字段全都写进去直接用resultType


  <selectid="queryUserWithOrder2"resultType="UserOrder">
  <!--sql左外连接查询-->
  select*fromordersasoleftouterjoinusersasuono.uid=u.uid;
  </select>


最后想要了解更多Java信息的同学可以前往扣丁学堂官网咨询,扣丁学堂Java培训深受学员的喜爱。扣丁学堂不仅有专业的老师和与时俱进的课程体系,还有大量的Java视频教程供学员观看学习哦。扣丁学堂java技术交流群:487098661。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客