前言

当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射。对于SSM的Mybatis来说,肯定也是差不多的。既然开了头了,我们就也来简单说一些Mybatis的高级映射。当然说到这些东西的时候,最简单也最常用的就是级联查询,所以我们就以几个简单的级联查询为例,分别说一下Mybatis的一对一、一对多、多对多查询。

一、一对一映射

1、需求:

电商类做买卖,用户提交订单后,某宝根据订单信息和客户的姓名、地址派送,现在查询所有的订单信息,关联查询下但用户信息。

(1)首先确定执行的sql语句为:

  1. <span style="font-size:18px;">SELECT orders.*,user.username,userss.address FROM orders,user WHEREorders.user_id = user.id</span>

resultType方式解决这个问题:

(1)定义po类:

  1. public class OrdersCustom extends Orders {  //OrdersCustom类继承Orders类后OrdersCustom类包括了Orders类的所有字
  1. 段,只需要定义用户的信息字段即可。
  2. private String username;// 用户名称
  3. private String address;// 用户地址
  4. public String getUsername(){
  5. return username;
  6. }
  7. public String setUsername(String username){
  8. this.username=username;
  9. }
  10. ……
  11. }

(2)Mapper映射文件:

  1. <!-- 查询所有订单信息 -->
  2. <select id="findOrdersList" resultType="cn.itcast.mybatis.po.OrdersCustom">
  3. SELECT
  4. orders.*,
  5. user.username,
  6. user.address
  7. FROM
  8. orders,    user
  9. WHERE orders.user_id = user.id
  10. </select>

(3)定义mapper接口:

  1. <span style="font-size:18px;">public List<OrdersCustom> findOrdersList() throws Exception;</span>

(4)测试:

  1. Public void testfindOrdersList()throws Exception{
  2. //获取session
  3. SqlSession session = sqlSessionFactory.openSession();
  4. //获限mapper接口实例
  5. UserMapper userMapper = session.getMapper(UserMapper.class);
  6. //查询订单信息
  7. List<OrdersCustom> list =userMapper.findOrdersList();
  8. System.out.println(list);
  9. //关闭session
  10. session.close();
  11. }

使用resultMap解决问题:

(1)定义resultMap:

  1. <!-- 订单信息resultmap___需要关联查询映射的是用户信息,使用association将用户信息映射到订单对象的用户属性中 -->
  2. <resultMap type="cn.itcast.mybatis.po.Orders"id="userordermap">
  3. <!-- 这里的id,是mybatis在进行一对一查询时将user字段映射为user对象时要使用,必须写 -->
  4. <id property="id" column="id"/>
  5. <resultpropertyresultproperty="user_id" column="user_id"/>
  6. <resultpropertyresultproperty="number" column="number"/>
  7. <associationpropertyassociationproperty="user" javaType="cn.itcast.mybatis.po.User">
  8. <!-- 这里的id为user的id,如果写上表示给user的id属性赋值 -->
  9. <id property="id" column="user_id"/>
  10. <resultpropertyresultproperty="username" column="username"/>
  11. <resultpropertyresultproperty="address" column="address"/>
  12. </association>
  13. </resultMap>

(2)调用resultMap:

  1. <select id="findOrdersListResultMap" resultMap="userordermap">
  2. SELECT
  3. orders.*,
  4. user.username,
  5. user.address
  6. FROM
  7. orders,    user
  8. WHERE orders.user_id = user.id
  9. </select>

(3)定义mapper接口

一对一查询总结:

个人认为啊,这种情况下使用resultType定义输出映射相对简单,因为这样只需要去添加一个po类就行了,按需求添加额外需要的属性,就可以完成映射。而相对于resultType来说,resultMap就显得稍微麻烦一些了,他需要特别定义resultMap来映射相关联表的实体属性。

二、一对多查询:

1、需求:

继上面的需求,查询所有订单信息及订单下的订单明细信息(一个订单信息下面或有很多商品,这个女生买护肤品的时候应该很有感触吧。所以订单信息与订单明细是一对多的关系)

(1)确定在数据库执行的sql语句:

  1. Select  orders.*, user.username, user.address,orderdetail.idorderdetail_id,orderdetail.items_id,
  2. orderdetail.items_num FROM orders,user,orderdetail
  3. WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id
 
执行结果:

(2)定义po类:

  1. public class Orders{
  2. private Integer id;
  3. private Integer userId;
  4. private String number;
  5. private Date createtime;
  6. private String note;
  7. private User user;
  8. private List<OrderDetial> orderDetails;
  9. //getter、setter
  10. }

(3)定义resultMap

  1. <!-- 订单信息resultmap -->
  2. <resultMaptyperesultMaptype="cn.itcast.mybatis.po.Orders"id="userorderdetailmap">
  3. <id property="id"column="id"/>
  4. <result property="user_id" column="user_id"/>
  5. <result property="number" column="number"/>
  6. <association property="user" javaType="cn.itcast.mybatis.po.User">
  7. <id property="id" column="user_id"/>
  8. <result property="username" column="username"/>
  9. <result property="address" column="address"/>
  10. </association>
  11. <collectionpropertycollectionproperty="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
  12. <id property="id" column="orderdetail_id"/>
  13. <result property="items_id" column="items_id"/>
  14. <result property="items_num" column="items_num"/>
  15. </collection>
  16. </resultMap>

大家可以跟上面对比一下,这两个resultMap除了对订单详细的映射定义外,其他的是完全一样的,现在问题来了,我们需要重新定义上面重复的映射信息吗?答案是不用,resultMap具有可继承特性,我们只需要继承上面的resultMap(userordermap),然后只定义别的就可以了,如下:

  1. <resultMaptyperesultMaptype="cn.itcast.mybatis.po.Orders" id="userorderdetailmap" extends="userordermap">
  2. <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
  3. <id property="id" column="orderdetail_id"/>
  4. <result property="items_id" column="items_id"/>
  5. <result property="items_num" column="items_num"/>
  6. </collection>
  7. </resultMap>

使用extends来继承订单信息resultmap:userordermap

(4)实现调用:

  1. <selectidselectid="findOrdersDetailList" resultMap="userorderdetailmap">
  2. SELECT
  3. orders.*,
  4. user.username,
  5. user.address,
  6. orderdetail.id orderdetail_id,
  7. orderdetail.items_id,
  8. orderdetail.items_num
  9. FROM orders,user,orderdetail
  10. WHERE orders.user_id = user.id
  11. AND orders.id =orderdetail.orders_id
  12. </select>

(5)定义mapper接口:

  1. publicList<Orders>findOrdersDetailList () throws Exception;

(6)来测试一下:

  1. Public void testfindOrdersDetailList()throws Exception{
  2. //获取session
  3. SqlSession session = sqlSessionFactory.openSession();
  4. //获限mapper接口实例
  5. UserMapper userMapper =session.getMapper(UserMapper.class);
  6. //查询订单信息
  7. List<Orders> list =userMapper.findOrdersDetailList();
  8. System.out.println(list);
  9. //关闭session
  10. session.close();
  11. }

这个吧,图没有了,可是可以给大家形容一下,就是返回结果只有四个订单信息,然后每个订单信息里面有两个商品信息list压到这里面。就这样,我们就实现了一对多的查询,为什么这个例子我们不用resultType来执行,其实结果早就给大家了,上面执行sql的结果图,就是返回的信息列表,实际上只有四个订单信息,但是使用resultType会返回8条信息,也就是没有完成去重,还需要我们去手动去重,了然了吗?不是很方便

三、多对多查询

(1)需求:

查询用户购买的商品信息(一个用户可以有N个订单信息,每个订单信息可以有M个商品信息,所以我们需要查询所有的用户信息,关联查询订单及订单明细信息,订单名信息中关联查询商品信息)

(2)确定要执行的sql:

  1. SELECT
  2. orders.*,
  3. USER.username,
  4. USER.address,
  5. orderdetail.idorderdetail_id,
  6. orderdetail.items_id,
  7. orderdetail.items_num,
  8. items.nameitems_name,
  9. items.detailitems_detail
  10. FROM
  11. orders,
  12. USER,
  13. orderdetail,
  14. items
  15. WHERE
  16. orders.user_id= USER .id
  17. AND orders.id = orderdetail.orders_id
  18. ANDorderdetail.items_id = items.id

(3)po类变化:

User中添加List<Orders>orders 属性;在Orders类中加入List<Orderdetail> orderdetails属性;Items类,不用动

(4)定义resultMap:

  1. <resultMap type="cn.itcast.mybatis.po.User"id="userOrderListResultMap">
  2. <id column="user_id"property="id"/>
  3. <result column="username"property="username"/>
  4. <collection property="orders"ofType="cn.itcast.mybatis.po.Orders">
  5. <id  column="id"property="id"/>
  6. <result property="number" column="number"/>
  7. <collection property="orderdetails"ofType="cn.itcast.mybatis.po.Orderdetail">
  8. <id  column="orderdetail_id" property="id"/>
  9. <result property="ordersId"column="id"/>
  10. <result property="itemsId"column="items_id"/>
  11. <result property="itemsNum"column="items_num"/>
  12. <association property="items"javaType="cn.itcast.mybatis.po.Items">
  13. <id column="items_id" property="id"/>
  14. <result column="items_name" property="name"/>
  15. <result column="items_detail" property="detail"/>
  16. </association>
  17. </collection>
  18. </collection>
  19. </resultMap>

(5)调用resultMap:

  1. <select id="findUserItemResultMap" resultMap="UserItemResultMap" >
  2. select orders.*,
  3. user.username,
  4. user.sex,
  5. user.address,
  6. orderdetail.id,
  7. orderdetail_id,
  8. orderdetail.items_id,
  9. orderdetail.items_num,
  10. orderdetail.orders_id,
  11. item.id item_id,
  12. item.name item_name,
  13. item.detail item_detail,
  14. item.price item_price
  15. from orders,user,orderdetail,item
  16. where orders.user_id=user.id
  17. and orders.id=orderdetail.orders_id
  18. and orderdetail.items_id=item.id
  19. </select>

到这里,相信大家能看出点端倪来了吧,我们一直都是用<collection></collection>和<association></association>分别对集合和实体进行关联映射,而且它们层层嵌套的方式就跟实体之间层层嵌套的方式一样:user中包含orders,orders中包含orderdetail,orderdetail中包含item。

(6)然后定义mapper接口:

  1. public interface UserMapper {    List<User> findUserItemResultMap() throws Exception;}

结果,就请大家自己去动手实验一下吧!

到此,我们的Mybatis高级映射之一对一,一对多,多对多映射就分享完了,期间自己又有点收获,总结一下:

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

2、resultMap:使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。其中association见关联查询信息映射到一个pojo对象中,collection将关联查询信息映射到一个list集合中然而,使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。那就要看我们自己的判断力了。

【Mybatis高级映射】一对一映射、一对多映射、多对多映射的更多相关文章

  1. Hibernate之关联映射(一对多和多对一映射,多对多映射)

    ~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习以下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...

  2. Hibernate之关联关系映射(一对多和多对一映射,多对多映射)

    ~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习一下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...

  3. MyBatis高级查询 一对一映射

    drop database if exists simple; create database simple; use simple; drop table if exists sys_user; c ...

  4. MyBatis的关联关系 一对一 一对多 多对多

    一对一示例 一个妻子对应一个丈夫 数据库表设计时 在妻子表中添加一个丈夫主键的作为外键 1 对应的JavaBean代码虽然在数据库里只有一方配置的外键,但是这个一对一是双向的关系. Husband实体 ...

  5. MyBatis 高级查询环境准备(八)

    MyBatis 高级查询 之前在学习 Mapper XML 映射文件时,说到 resultMap 标记是 MyBatis 中最重要最强大也是最复杂的标记,而且还提到后面会详细介绍它的高级用法. 听到高 ...

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

    天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种 ...

  7. Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射

    一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...

  8. java web(六):mybatis之一对一、一对多、多对多映射

    前言: 百度百科: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...

  9. Mybatis 使用 mapper 接口规范的 一对一, 一对多,多对多映射

    首先的 是 最原始的 pojo 类来 做简单映射 简单 pojo 映射: <mapper namespace="com.ghc.dao.UserDao"> <se ...

随机推荐

  1. zTree简单实现

    用zTree简单实现从后台传数据生成树 1.在jsp上引入js,jsp的head完整的部分 <%@ page language="java" contentType=&quo ...

  2. VisualStudio配色方案

    最近发现一个很神奇的网站,可以方便的为VisualStudio配色:Studio Styles - Visual Studio color schemes 可以下载一份自己喜欢的配色方案 如果还不满意 ...

  3. Introduction to Neural Machine Translation - part 1

    The Noise Channel Model \(p(e)\): the language Model \(p(f|e)\): the translation model where, \(e\): ...

  4. 看完《Thinking in Java》后,我觉得自己就是一个不懂编程的小孩子,如何快速摆脱这种自卑感

    我虽然不懂java也不懂程序员,但我理解这种心情.当看到自己还算自信的专业领域中一部超越自己水平很多的作品或比自己优秀太多的人,难免会感到震惊,继而进行自我否定.就像我曾经非常喜欢写作,在杂志和校报上 ...

  5. 学习.Net的经典网站

    学习.Net的经典网站 收藏 还不错推荐给大家 原文-- 名称:快速入门 地址:http://chs.gotdotnet.com/quickstart/ 描述:本站点是微软.NET技术的快速入门网站, ...

  6. [Fluent NHibernate]第一个程序

    目录 写在前面 Fluent Nhibernate简介 基本配置 总结 写在前面 在耗时两月,NHibernate系列出炉这篇文章中,很多园友说了Fluent Nhibernate的东东,也激起我的兴 ...

  7. HTML5 离线缓存管理库

    一.HTML5离线缓存技术 支持离线缓存是HTML5中的一个重点,离线缓存就是让用户即使在断网的情况下依然可以正常的运行应用.传统的本地存储数据的方式有 localstorage,sessionsto ...

  8. Java虚拟机 safepoints 初探

    safepoint的定义很不规范,还跟JVM的具体实现有关,我们的讨论主要针对Hotspot VM. 先看看openjdk的官方解释:  http://openjdk.java.net/groups/ ...

  9. URL传递中文字符,特殊危险字符的解决方案(仅供参考)urldecode、base64_encode

    很多时候,我们需要在url中传递中文字符或是其它的html等特殊字符,似乎总会有各种乱,不同的浏览器对他们的编码又不一样, 对于中文,一般的做法是: 把这些文本字符串传给url之前,先进行urlenc ...

  10. 《UNIX网络编程(第3版)》unp.h等源码文件的编译安装

    操作系统:Mac OS X 10.11.5 1.下载书中的源代码:点击下载 2.切换到解压后的目录 unpv13e,先查看下 README,依次执行: ./configure cd lib make ...