【Mybatis高级映射】一对一映射、一对多映射、多对多映射
前言
当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射。对于SSM的Mybatis来说,肯定也是差不多的。既然开了头了,我们就也来简单说一些Mybatis的高级映射。当然说到这些东西的时候,最简单也最常用的就是级联查询,所以我们就以几个简单的级联查询为例,分别说一下Mybatis的一对一、一对多、多对多查询。
一、一对一映射
1、需求:
电商类做买卖,用户提交订单后,某宝根据订单信息和客户的姓名、地址派送,现在查询所有的订单信息,关联查询下但用户信息。
(1)首先确定执行的sql语句为:
- <span style="font-size:18px;">SELECT orders.*,user.username,userss.address FROM orders,user WHEREorders.user_id = user.id</span>
resultType方式解决这个问题:
(1)定义po类:
- public class OrdersCustom extends Orders { //OrdersCustom类继承Orders类后OrdersCustom类包括了Orders类的所有字
- 段,只需要定义用户的信息字段即可。
- private String username;// 用户名称
- private String address;// 用户地址
- public String getUsername(){
- return username;
- }
- public String setUsername(String username){
- this.username=username;
- }
- ……
- }
(2)Mapper映射文件:
- <!-- 查询所有订单信息 -->
- <select id="findOrdersList" resultType="cn.itcast.mybatis.po.OrdersCustom">
- SELECT
- orders.*,
- user.username,
- user.address
- FROM
- orders, user
- WHERE orders.user_id = user.id
- </select>
(3)定义mapper接口:
- <span style="font-size:18px;">public List<OrdersCustom> findOrdersList() throws Exception;</span>
(4)测试:
- Public void testfindOrdersList()throws Exception{
- //获取session
- SqlSession session = sqlSessionFactory.openSession();
- //获限mapper接口实例
- UserMapper userMapper = session.getMapper(UserMapper.class);
- //查询订单信息
- List<OrdersCustom> list =userMapper.findOrdersList();
- System.out.println(list);
- //关闭session
- session.close();
- }
使用resultMap解决问题:
(1)定义resultMap:
- <!-- 订单信息resultmap___需要关联查询映射的是用户信息,使用association将用户信息映射到订单对象的用户属性中 -->
- <resultMap type="cn.itcast.mybatis.po.Orders"id="userordermap">
- <!-- 这里的id,是mybatis在进行一对一查询时将user字段映射为user对象时要使用,必须写 -->
- <id property="id" column="id"/>
- <resultpropertyresultproperty="user_id" column="user_id"/>
- <resultpropertyresultproperty="number" column="number"/>
- <associationpropertyassociationproperty="user" javaType="cn.itcast.mybatis.po.User">
- <!-- 这里的id为user的id,如果写上表示给user的id属性赋值 -->
- <id property="id" column="user_id"/>
- <resultpropertyresultproperty="username" column="username"/>
- <resultpropertyresultproperty="address" column="address"/>
- </association>
- </resultMap>
(2)调用resultMap:
- <select id="findOrdersListResultMap" resultMap="userordermap">
- SELECT
- orders.*,
- user.username,
- user.address
- FROM
- orders, user
- WHERE orders.user_id = user.id
- </select>
(3)定义mapper接口
一对一查询总结:
个人认为啊,这种情况下使用resultType定义输出映射相对简单,因为这样只需要去添加一个po类就行了,按需求添加额外需要的属性,就可以完成映射。而相对于resultType来说,resultMap就显得稍微麻烦一些了,他需要特别定义resultMap来映射相关联表的实体属性。
二、一对多查询:
1、需求:
继上面的需求,查询所有订单信息及订单下的订单明细信息(一个订单信息下面或有很多商品,这个女生买护肤品的时候应该很有感触吧。所以订单信息与订单明细是一对多的关系)
(1)确定在数据库执行的sql语句:
- Select orders.*, user.username, user.address,orderdetail.idorderdetail_id,orderdetail.items_id,
- orderdetail.items_num FROM orders,user,orderdetail
- WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id
(2)定义po类:
- public class Orders{
- private Integer id;
- private Integer userId;
- private String number;
- private Date createtime;
- private String note;
- private User user;
- private List<OrderDetial> orderDetails;
- //getter、setter
- }
(3)定义resultMap
- <!-- 订单信息resultmap -->
- <resultMaptyperesultMaptype="cn.itcast.mybatis.po.Orders"id="userorderdetailmap">
- <id property="id"column="id"/>
- <result property="user_id" column="user_id"/>
- <result property="number" column="number"/>
- <association property="user" javaType="cn.itcast.mybatis.po.User">
- <id property="id" column="user_id"/>
- <result property="username" column="username"/>
- <result property="address" column="address"/>
- </association>
- <collectionpropertycollectionproperty="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
- <id property="id" column="orderdetail_id"/>
- <result property="items_id" column="items_id"/>
- <result property="items_num" column="items_num"/>
- </collection>
- </resultMap>
大家可以跟上面对比一下,这两个resultMap除了对订单详细的映射定义外,其他的是完全一样的,现在问题来了,我们需要重新定义上面重复的映射信息吗?答案是不用,resultMap具有可继承特性,我们只需要继承上面的resultMap(userordermap),然后只定义别的就可以了,如下:
- <resultMaptyperesultMaptype="cn.itcast.mybatis.po.Orders" id="userorderdetailmap" extends="userordermap">
- <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
- <id property="id" column="orderdetail_id"/>
- <result property="items_id" column="items_id"/>
- <result property="items_num" column="items_num"/>
- </collection>
- </resultMap>
使用extends来继承订单信息resultmap:userordermap
(4)实现调用:
- <selectidselectid="findOrdersDetailList" resultMap="userorderdetailmap">
- SELECT
- orders.*,
- user.username,
- user.address,
- orderdetail.id orderdetail_id,
- orderdetail.items_id,
- orderdetail.items_num
- FROM orders,user,orderdetail
- WHERE orders.user_id = user.id
- AND orders.id =orderdetail.orders_id
- </select>
(5)定义mapper接口:
- publicList<Orders>findOrdersDetailList () throws Exception;
(6)来测试一下:
- Public void testfindOrdersDetailList()throws Exception{
- //获取session
- SqlSession session = sqlSessionFactory.openSession();
- //获限mapper接口实例
- UserMapper userMapper =session.getMapper(UserMapper.class);
- //查询订单信息
- List<Orders> list =userMapper.findOrdersDetailList();
- System.out.println(list);
- //关闭session
- session.close();
- }
这个吧,图没有了,可是可以给大家形容一下,就是返回结果只有四个订单信息,然后每个订单信息里面有两个商品信息list压到这里面。就这样,我们就实现了一对多的查询,为什么这个例子我们不用resultType来执行,其实结果早就给大家了,上面执行sql的结果图,就是返回的信息列表,实际上只有四个订单信息,但是使用resultType会返回8条信息,也就是没有完成去重,还需要我们去手动去重,了然了吗?不是很方便
三、多对多查询
(1)需求:
查询用户购买的商品信息(一个用户可以有N个订单信息,每个订单信息可以有M个商品信息,所以我们需要查询所有的用户信息,关联查询订单及订单明细信息,订单名信息中关联查询商品信息)
(2)确定要执行的sql:
- SELECT
- orders.*,
- USER.username,
- USER.address,
- orderdetail.idorderdetail_id,
- orderdetail.items_id,
- orderdetail.items_num,
- items.nameitems_name,
- items.detailitems_detail
- FROM
- orders,
- USER,
- orderdetail,
- items
- WHERE
- orders.user_id= USER .id
- AND orders.id = orderdetail.orders_id
- ANDorderdetail.items_id = items.id
(3)po类变化:
在User中添加List<Orders>orders 属性;在Orders类中加入List<Orderdetail> orderdetails属性;Items类,不用动
(4)定义resultMap:
- <resultMap type="cn.itcast.mybatis.po.User"id="userOrderListResultMap">
- <id column="user_id"property="id"/>
- <result column="username"property="username"/>
- <collection property="orders"ofType="cn.itcast.mybatis.po.Orders">
- <id column="id"property="id"/>
- <result property="number" column="number"/>
- <collection property="orderdetails"ofType="cn.itcast.mybatis.po.Orderdetail">
- <id column="orderdetail_id" property="id"/>
- <result property="ordersId"column="id"/>
- <result property="itemsId"column="items_id"/>
- <result property="itemsNum"column="items_num"/>
- <association property="items"javaType="cn.itcast.mybatis.po.Items">
- <id column="items_id" property="id"/>
- <result column="items_name" property="name"/>
- <result column="items_detail" property="detail"/>
- </association>
- </collection>
- </collection>
- </resultMap>
(5)调用resultMap:
- <select id="findUserItemResultMap" resultMap="UserItemResultMap" >
- select orders.*,
- user.username,
- user.sex,
- user.address,
- orderdetail.id,
- orderdetail_id,
- orderdetail.items_id,
- orderdetail.items_num,
- orderdetail.orders_id,
- item.id item_id,
- item.name item_name,
- item.detail item_detail,
- item.price item_price
- from orders,user,orderdetail,item
- where orders.user_id=user.id
- and orders.id=orderdetail.orders_id
- and orderdetail.items_id=item.id
- </select>
到这里,相信大家能看出点端倪来了吧,我们一直都是用<collection></collection>和<association></association>分别对集合和实体进行关联映射,而且它们层层嵌套的方式就跟实体之间层层嵌套的方式一样:user中包含orders,orders中包含orderdetail,orderdetail中包含item。
(6)然后定义mapper接口:
- 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高级映射】一对一映射、一对多映射、多对多映射的更多相关文章
- Hibernate之关联映射(一对多和多对一映射,多对多映射)
~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习以下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...
- Hibernate之关联关系映射(一对多和多对一映射,多对多映射)
~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习一下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...
- MyBatis高级查询 一对一映射
drop database if exists simple; create database simple; use simple; drop table if exists sys_user; c ...
- MyBatis的关联关系 一对一 一对多 多对多
一对一示例 一个妻子对应一个丈夫 数据库表设计时 在妻子表中添加一个丈夫主键的作为外键 1 对应的JavaBean代码虽然在数据库里只有一方配置的外键,但是这个一对一是双向的关系. Husband实体 ...
- MyBatis 高级查询环境准备(八)
MyBatis 高级查询 之前在学习 Mapper XML 映射文件时,说到 resultMap 标记是 MyBatis 中最重要最强大也是最复杂的标记,而且还提到后面会详细介绍它的高级用法. 听到高 ...
- Mybatis(四) 高级映射,一对一,一对多,多对多映射
天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种 ...
- Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射
一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...
- java web(六):mybatis之一对一、一对多、多对多映射
前言: 百度百科: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...
- Mybatis 使用 mapper 接口规范的 一对一, 一对多,多对多映射
首先的 是 最原始的 pojo 类来 做简单映射 简单 pojo 映射: <mapper namespace="com.ghc.dao.UserDao"> <se ...
随机推荐
- 最简单的JavaScript模板引擎
在小公司待久了感觉自己的知识面很小,最近逛博客园和一些技术网站看大家在说JavaScript模版引擎的事儿,完全没有概念,网上一搜这是08年开始流行起来的...本来以为这是很高深的知识,后来在网上看到 ...
- python模块(六)
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- Debian 8中dpkg -i自动解决依赖关系
dpkg -i 后#apt-get update &&apt-get -f install
- getCanonicalName和getSimpleName getName的区别与应用
接口: package com.test; public interface Fruit { } 一个实现类: package com.test; public class Apple impleme ...
- 深入理解javascript原型和闭包(4)——隐式原型
注意:本文不是javascript基础教程,如果你没有接触过原型的基本知识,应该先去了解一下,推荐看<javascript高级程序设计(第三版)>第6章:面向对象的程序设计. 上节已经提到 ...
- Asp.Net HttpContext.RemapHandler 用法
最近在看HttpHandler映射过程文章时发现Context对象中有一个RemapHandler方法,它能将当前请求映射到指定的HttpHandler处理,可跳过系统默认的Httphandler.它 ...
- win7挂载VHD文件,模拟多系统并存
挂载vhd是win7 一个很特殊的功能,xp不能支持,一些服务器版的系统 像2008.2008R2这些可能也是支持的,只是没有测试过. 提前的准备: Win7 wim 镜像文件 Imagex.exe ...
- NOIP2012同余方程
描述 求关于 x的同余方程 ax ≡ 1(mod b) 的最小正整数解. 输入格式 输入文件 mod.in输入只有一行,包含两个正整数a,b,用一个空格隔开. 输出格式 输出文件 为 modmod ...
- hzwer模拟赛 虫洞
[题目描述] N个虫洞,M条单向跃迁路径.从一个虫洞沿跃迁路径到另一个虫洞需要消耗一定量的燃料和1单位时间.虫洞有白洞和黑洞之分.设一条跃迁路径两端的虫洞质量差为delta. 1.从白洞跃迁到黑洞,消 ...
- php 301 重定向 转自http://www.icoa.cn/a/475.html
内容简介 有时候我们的有多个域名指向同一个网站,或者我们更换了网站的网址,那么怎么样将原来网站的流量导入到新网址中呢,那么我们可以用301重定向的方式,而且这种方式是对搜索引擎比较友好的方式.如果首页 ...