MyBatis总结六:resultMap详解(包含多表查询)

From: https://www.cnblogs.com/Alex-zqzy/p/9296039.html

简介:  

  MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性,而当我们提供的返回类型是resultMap的时候,将数据库中列数据复制到对象的相应属性上,可以用于复制查询,两者不能同时用。

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

首先来说一下resultType

  使用resultType进行输出映射,只有查询出来的列名和pojo(实体bean)中的属性名一致,该列才可以映射成功。

  简单来说也就是你的数据库字段和JavaBean里的字段名称必须一致才能映射成功。

  所以当我们JavaBean中的字段名和数据库字段名称有不同的时候,或者是多表查询的时候,一般会使用resultMap

 

resultMap

  resultMap是Mybatis最强大的元素,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中。

属性描述
property需要映射到JavaBean 的属性名称。
column数据表的列名或者标签别名。
javaType一个完整的类名,或者是一个类型别名。如果你匹配的是一个JavaBean,那MyBatis 通常会自行检测到。然后,如果你是要映射到一个HashMap,那你需要指定javaType 要达到的目的。
jdbcType数据表支持的类型列表。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果你是直接针对JDBC 编码,且有允许空的列,而你要指定这项。
typeHandler使用这个属性可以覆写类型处理器。这项值可以是一个完整的类名,也可以是一个类型别名。

元素简介:

复制代码

<!--column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象"><id column="表的主键字段,或者可以为查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" /><result column="表的一个字段(可以为任意表的一个字段)" jdbcType="字段类型" property="映射到pojo对象的一个属性(须为type定义的pojo对象中的一个属性)"/><association property="pojo的一个对象属性" javaType="pojo关联的pojo对象"><id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的主席属性"/><result  column="任意表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/></association><!-- 集合中的property须为oftype定义的pojo对象的属性--><collection property="pojo的集合属性" ofType="集合中的pojo对象"><id column="集合中pojo对象对应的表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" /><result column="可以为任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />  </collection>
</resultMap>

复制代码

 

使用具体案例来讲述:

首先我们数据库中的表结构如下:

可以看出我们表字段中有很多字段内有下划线,而我们的JavaBean里面的命名是按照驼峰规则命名的,下面我们贴上JavaBean:

User JavaBean

Order JavaBean

Product JavaBean

Orderitem JavaBean

 

首先我们把配置文件中的驼峰规则关闭

    <settings><setting name="mapUnderscoreToCamelCase" value="false"/></settings>

 

单表查询(查询所有订单信息):

OrderMapper.xml

复制代码

<mapper namespace="com.zy.mapper.OrderMapper"><resultMap id="OrderResultMap" type="com.zy.domain.Order"><id column="oid" property="oid"></id><result column="user_id" property="userId"></result><result column="order_number" property="orderNumber"></result></resultMap><!--查询订单表信息--><select id="getOrderList" resultMap="OrderResultMap">select * from tb_order</select>
</mapper>

复制代码

OrderMapper接口

public interface OrderMapper {public List<Order> getOrderList();
}

测试:

复制代码

public class OrderMapperTest {OrderMapper mapper;@org.junit.Beforepublic void setUp() throws Exception {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession(true);mapper = sqlSession.getMapper(OrderMapper.class);}@org.junit.Testpublic void getOrderList() throws Exception {List<Order> list = mapper.getOrderList();for (Order order : list) {System.out.println(order);}}}

复制代码

运行结果:

 

一对一多表查询(根据订单编号查询订单信息并带出订单所属用户信息):

这里引出了association联合:

  联合元素用来处理“一对一”的关系。需要指定映射的Java实体类的属性,属性的javaType(通常MyBatis 自己会识别)。

OrderMapper.xml

复制代码

<mapper namespace="com.zy.mapper.OrderMapper"><resultMap id="OrderResultMap" type="com.zy.domain.Order"><id column="oid" property="oid"></id><result column="user_id" property="userId"></result><result column="order_number" property="orderNumber"></result></resultMap><!--查询订单表信息--><select id="getOrderList" resultMap="OrderResultMap">select * from tb_order</select><!--extends 表示继承 autoMapping表示自动映射JavaBean中字段和数据表字段一致的字段信息--><resultMap id="OrderWithUserResultMap" type="com.zy.domain.Order" extends="OrderResultMap"><!--由于继承了OrderResultMap 所以这里就不用再写order表的信息了--><!--用户表信息--><association property="user" javaType="com.zy.domain.User" autoMapping="true"><id column="user_id" property="id"></id><result column="user_name" property="userName"></result></association></resultMap><!--根据订单编号查询订单信息并带出订单所属用户信息--><select id="getOrderWithUser" resultMap="OrderWithUserResultMap">select * from tb_order as o left join tb_user as u on o.user_id=u.idwhere o.order_number=#{ordernumber}</select>
</mapper>

复制代码

OrderMapper接口:

复制代码

public interface OrderMapper {/*** 获取所有订单列表*/public List<Order> getOrderList();/*** 根据订单编号 获取单个订单及所属用户信息*/public Order getOrderWithUser(@Param("ordernumber") String orderNumber);
}

复制代码

测试:

复制代码

public class OrderMapperTest {OrderMapper mapper;@Beforepublic void setUp() throws Exception {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession(true);mapper = sqlSession.getMapper(OrderMapper.class);}@Testpublic void getOrderList() throws Exception {List<Order> list = mapper.getOrderList();for (Order order : list) {System.out.println(order);}}@Testpublic void getOrderWithUser() throws Exception {Order order = mapper.getOrderWithUser("20140921002");System.out.println(order);}}

复制代码

 

一对多多表查询(根据订单号 查询订单,并且查询出所有订单详情(子订单)及所属用户):

由于是一对多,所以这里就引出了collection聚集:

  聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList);列表中对象的类型ofType(Java实体类)。

OrderMapper.xml

复制代码

<mapper namespace="com.zy.mapper.OrderMapper"><resultMap id="OrderResultMap" type="com.zy.domain.Order"><id column="oid" property="oid"></id><result column="user_id" property="userId"></result><result column="order_number" property="orderNumber"></result></resultMap><!--查询订单表信息--><select id="getOrderList" resultMap="OrderResultMap">select * from tb_order</select><!--extends 表示继承--><resultMap id="OrderWithUserResultMap" type="com.zy.domain.Order" extends="OrderResultMap"><!--由于继承了OrderResultMap 所以这里就不用再写order表的信息了--><!--用户表信息--><association property="user" javaType="com.zy.domain.User" autoMapping="true"><id column="user_id" property="id"></id><result column="user_name" property="userName"></result></association></resultMap><!--根据订单编号查询订单信息并带出订单所属用户信息--><select id="getOrderWithUser" resultMap="OrderWithUserResultMap">select * from tb_order as o left join tb_user as u on o.user_id=u.idwhere o.order_number=#{ordernumber}</select><resultMap id="OrderWithItemAndUserResultMap" type="com.zy.domain.Order"extends="OrderWithUserResultMap"><!--javaType为list list代表List类型  ofType为Orderitem--><collection property="orderitemList" javaType="list" ofType="com.zy.domain.Orderitem"autoMapping="true"><id column="item_id" property="itemId"></id><result column="order_id" property="orderId"></result><result column="product_id" property="productId"></result><result column="total_price" property="totalPrice"></result></collection></resultMap><!--根据订单号 查询订单,并且查询出所有订单详情(子订单)及所属用户--><select id="getOrderWithItenAndUser" resultMap="OrderWithItemAndUserResultMap">select * from tb_order oleft join tb_user u on o.user_id=u.idleft join tb_orderitem oi on o.oid=oi.order_idwhere o.order_number=#{ordernumber}</select>
</mapper>

复制代码

OrderMapper接口:

复制代码

public interface OrderMapper {/*** 获取所有订单列表*/public List<Order> getOrderList();/*** 根据订单编号 获取单个订单及所属用户信息*/public Order getOrderWithUser(@Param("ordernumber") String orderNumber);/*** 根据订单号 查询订单,并且查询出所有订单详情(子订单)及所属用户*/public Order getOrderWithItenAndUser(@Param("ordernumber") String orderNumber);
}

复制代码

测试:

复制代码

public class OrderMapperTest {OrderMapper mapper;@Beforepublic void setUp() throws Exception {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession(true);mapper = sqlSession.getMapper(OrderMapper.class);}@Testpublic void getOrderList() throws Exception {List<Order> list = mapper.getOrderList();for (Order order : list) {System.out.println(order);}}@Testpublic void getOrderWithUser() throws Exception {Order order = mapper.getOrderWithUser("20140921002");System.out.println(order);}@Testpublic void getOrderWithItenAndUser() throws Exception {Order order = mapper.getOrderWithItenAndUser("20140921001");System.out.println(order);}}

复制代码

 

多对多 多表查询(根据订单号 查询订单,查询出所属用户,并且查询出订单的详情,及订单详情中的对应的商品信息   订单详情和商品为多对多关系):

这一次我们开启驼峰规则,可以少写一些符合规则的字段:

    <settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>

 

OrderMapper.xml(不继承,从头写的一版):

复制代码

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.zy.mapper.OrderMapper"><resultMap id="OrderFullInfoResultMap" type="com.zy.domain.Order" autoMapping="true"><!--order表主键--><id column="oid" property="oid"></id><!--关联用户表--><association property="user" javaType="com.zy.domain.User" autoMapping="true"><!--用户表主键--><id column="user_id" property="id"></id></association><!--关联订单详情表--><collection property="orderitemList" javaType="list" ofType="com.zy.domain.Orderitem"autoMapping="true"><!--订单详情表主键--><id column="item_id" property="itemId"></id><!--关联商品--><association property="product" javaType="com.zy.domain.Product" autoMapping="true"><!--商品表主键--><id column="product_id" property="pid"></id></association></collection></resultMap><!--根据订单号 查询订单,查询出所属用户,并且查询出订单的详情,及订单详情中的对应的商品信息--><select id="getOrderFullInfo" resultMap="OrderFullInfoResultMap">select * from tb_order oleft join tb_user u on o.user_id=u.idleft join tb_orderitem oi on o.oid=oi.order_idleft join tb_product p on oi.product_id=p.pidwhere o.order_number=#{ordernumber}</select>
</mapper>

复制代码

 

OrderMapper接口:

复制代码

public interface OrderMapper {/*** 根据订单号 查询订单,查询出所属用户,并且查询出订单的详情,及订单详情中的对应的商品信息*/public Order getOrderFullInfo(@Param("ordernumber") String orderNumber);
}

复制代码

测试:

复制代码

public class OrderMapperTest {OrderMapper mapper;@Beforepublic void setUp() throws Exception {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession(true);mapper = sqlSession.getMapper(OrderMapper.class);}@Testpublic void getOrderFullInfo() throws Exception{Order order = mapper.getOrderFullInfo("20140921001");System.out.println(order);}}

复制代码

最终测试结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402597.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于beego一键创建RESTFul应用

2019独角兽企业重金招聘Python工程师标准>>> API应用开发入门 Go是非常适合用来开发API应用的&#xff0c;而且我认为也是Go相对于其他动态语言的最大优势应用。beego在开发API应用方面提供了非常强大和快速的工具&#xff0c;方便用户快速的建立API应用原型&#…

MyBatis中in的使用

From: https://www.cnblogs.com/w-bb/articles/6378031.html foreach的主要用在构建in条件中&#xff0c;它可以在SQL语句中进行迭代一个集合。 foreach元素的属性主要有 item&#xff0c;index&#xff0c;collection&#xff0c;open&#xff0c;separator&#xff0c;close…

MyBatis总结五:#{}和${}的用法和区别

From: https://www.cnblogs.com/blazeZzz/p/9295634.html #{}的用法&#xff1a; 我们发现&#xff0c;在Mapper.xml映射文件中&#xff0c;经常使用#{属性名} 来作为SQL语句的占位符&#xff0c;来映射Sql需要的实际参数 如果只有一个参数 <select id"getUserById&…

iOS多视图代码操作

2019独角兽企业重金招聘Python工程师标准>>> 摘抄 http://supershll.blog.163.com/blog/static/370704362012112021115/ 2.1.1 层次结构 基于树的层次结构对iPhone屏幕上的可见内容进行排序。从主窗口开始&#xff0c;视图以特殊的分层方式布置。所有视图都可以有…

(转)Tiny210v2( S5PV210 ) 平台下 FIMD 对应 的 framebuffer 驱动中,关于 video buffer 的理解...

原文:http://www.arm9home.net/read.php?tid-25938.html 管理提醒&#xff1a; 本帖被 xoom 执行加亮操作(2012-12-13)如之前所说&#xff0c;一直想知道显示数据都在哪个地方&#xff0c;通常的数据&#xff0c;比如 framebuffer 中的显示数据&#xff0c;和OpenGL 处理的数据…

C链表反转(时间复杂度O(n))

面试的时候经常会出现的问题,现在都做一遍,回忆一下,练练手. 这个题目需要注意两点: 1.head->next 要先设置为NULL ,否则反转后,它还是指向之前的next节点 2.需要有一个tmp指针,临时保存p->next的地址,这个在改变一个节点的next地址时,经常会用到 示意图 代码实现 #inclu…

mysql中find_in_set()函数的使用及in()用法详解

From: http://www.manongjc.com/article/2710.html MySQL手册中find_in_set函数的语法解释&#xff1a; FIND_IN_SET(str,strlist) str 要查询的字符串 strlist 字段名 参数以”,”分隔 如 (1,2,6,8,10,22) 查询字段(strlist)中包含(str)的结果&#xff0c;返回结果为null…

浅谈SQLiteOpenHelper之onUpgrade例子

当你看到这个博文&#xff0c;首先你要了解onCreate这个创建方法&#xff0c;再来继续下文!&#xff08;可以参考我的上一个博文http://www.cnblogs.com/896240130Master/p/6119616.html&#xff09; 这个onUpgrade类要在onCreate类的基础上建立&#xff01;我们知道onUpgrade是…

MySQL 字符串分割 SUBSTRING_INDEX函数

From: MySQL 字符串分割 SUBSTRING_INDEX函数 Sql代码 SUBSTRING_INDEX(str,delim,count) 用delim 分割str&#xff0c;取第count个子串 url http://www.medhelp.org/forums/Acne/show/56 Java代码 substring_index(url,"/",1) 结果是http: Java代码 substri…

XEN--转载自鸟哥的linux私房菜

初探 XenXen 的效能為什麼能夠這麼好&#xff1f; Xen 在使用上面有什麼樣的限制&#xff1f;我的一部主機最多可以支援幾個 Xen 的模擬環境&#xff1f; Xen 的模擬環境有幾種類型&#xff1f; 這些疑問我們都得要先知道一下才好&#xff01; 當然&#xff0c;最好能夠有個簡單…

[Mojava 10.14.4] Clover隐藏多余分区, 原来可以这么简单

好不容易把黑苹果装完了, 搞定驱动和引导, 剩下的也没啥了, 但还有一事: 隐藏clover中多余的启动项! 直接上最关键的部分: 1. 打开Clover Configurator, 挂载对应的EFI分区 2. 打开分区,加载对应的config.plist文件 3. 切换到Clover Configurator的Gui界面, 添加需要隐藏的项…

Mybatis高级-resultMap之collection聚集

From: https://aodeng.cc/archives/mybatisgaoji 简介 聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性&#xff0c;属性的javaType&#xff08;一般为ArrayList&#xff09;&#xff1b;列表中对象的类型ofType&#xff08;Java实体类&#xff09;&#…

电脑公司 Ghost XP SP3 国庆特别版 v2011.10

电脑公司 Ghost XP SP3 国庆特别版 v2011.10 文件名称:DNGS_GhostXpSp3_v2011.10.iso文件大小:686.59MB &#xff08;719,945,728字节&#xff09;系统格式:NTFSCRC32:DDEBC170MD5:FA264E6241154EE7F80EFED3CFF1C6A2SHA1:FFEB1C13854AA954D9EE384153815FAF52E0747B电脑城系统 …

TCP中间件_Delphi_client

1、界面 1.1、formMain.pas 1.1.1、 object frmMain: TfrmMainLeft 191Top 103Width 542Height 466Caption frmMainColor clBtnFaceFont.Charset DEFAULT_CHARSETFont.Color clWindowTextFont.Height -11Font.Name MS Sans SerifFont.Style []OldCreateOrder False…

Java、Mysql、MyBatis 中枚举 enum 的使用

From: https://yulaiz.com/java-mysql-enum/ Java 和 MySql 中都有枚举的概念&#xff0c;合理的使用枚举&#xff0c;可以让代码阅读和数据库数据查询更加直观、高效。那么我们怎么使用呢&#xff0c;什么时候使用&#xff0c;两者之间怎么进行数据关联呢&#xff1f;&#x…

ny12 喷水装置(二)

喷水装置&#xff08;二&#xff09; 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;4描述有一块草坪&#xff0c;横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<10000)个点状的喷水装置&#xff0c;每个喷水装置i喷水的效果是让…

wordpress插件制作视频教程【资料分享】

2019独角兽企业重金招聘Python工程师标准>>> 一共5集&#xff0c;每一集15分钟左右&#xff0c;适合入门用哦~ 资料地址&#xff1a; http://wordpresshy.com/create-plugin 分集介绍&#xff1a; 1 【教学大纲】 1.介绍什么是插件&#xff1b; 2.插件的文件结…

博主故事:博客提升了我在口腔行业的影响力

自从我上次谈了谈个人开设博客的目的一文后&#xff0c;今天就有一位博友发来了感谢留言&#xff0c;他说他的博客让他在国内做牙齿矫正行业的有了一定影响力&#xff0c;下月被请到上海讲课&#xff0c;也有不少民营机构前来挖他&#xff0c;还被邀请参加中国口腔医学界最盛大…

RabbitMQ入门教程——发布/订阅

什么是发布订阅 发布订阅是一种设计模式定义了一对多的依赖关系&#xff0c;让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时&#xff0c;会通知所有的订阅者对象&#xff0c;使他们能够自动更新自己的状态。 为了描述这种模式&#xff0c;我们将会构建…

linux C 学习---函数指针

我们经常会听到这样的说法&#xff0c;不懂得函数指针就不是真正的C语言高手。我们不管这句话对与否&#xff0c;但是它都从侧面反应出了函数指针的重要性&#xff0c;所以我们还是有必要掌握对函数指针的使用。先来看看函数指针的定义吧。 函数是由执行语句组成的指令序列或者…