终于把论文写得差不多了,系统也不急着完成,可以抽出点时间来完成这个系列的博客了。在写本博客之前我是惶恐不安的,高级映射一贯是持久层框架里的重中之重,小到自己开发小系统,大到企业级开发,表的存在从来就不独立的。复杂交错的表之间的联系有时的确让后台开发人员头疼,而作为一个框架,要做的事就是把这种复杂程度降到最低。既然如此,我们就赶快进入正文吧。

先说一对一吧,前几篇博文里用到了User类,今天我们再加上一个Orders订单类

一个订单只能由一个用户创建,所以根据订单查找用户是一对一的查找,所以当我想查出订单关联用户的所有记录怎么查呢?

我们知道这个查询时不用输入参数的,所以在select里面是不用输入parameterType的,由此可知查询关键就在resultType了,的确,但是今天resultType有时会不够用,当然这都是后话了,在一对一查询里面resultType完全是够用的,所以先看看这个怎么用吧

先分析一波,我们之前的所有的输出都有相会映射成相应的类,而我们现在没有一个既包含User属性又包含Orders的类怎么办呢?

没错,就是新建一个满足以上条件的类,在这里有一个小技巧,我们大多时候不需要关联表里的所有属性,比如在这里我们只要user类的用户名和地址两个属性时,可以创建一个Orders类的扩展类,在该扩展类里添加属性username和address,就像下面

解决了映射类,接下来就是xml文件了

先把sql语句贴上来

SELECT orders.*, user.username, user.address
FROMorders,user
WHEREorders.user_id = user.id;

这个sql语句很简单我就不多说了,有了这个mapper.xml就简单了

<select id="findOrderCustom" resultType="com.mybatis.pojo.OrderCustom">SELECT orders.*, user.username, user.addressFROMorders,userWHEREorders.user_id = user.id;</select>

然后就是遵循规范把mapper接口中的方法写了

    //查询Orders关联User使用resultTypepublic List<OrderCustom> findOrderCustom();

最后是测试代码

public class UserMapperTest {private SqlSessionFactory sqlSessionFactory;@Beforepublic void setUp() throws Exception {//得到配置文件流InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");//创建会话会话工厂sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void testFindOrderCustom() throws Exception {//创建会话SqlSession sqlSession = sqlSessionFactory.openSession();//创建mapper代理对象UserMapper userMapper= sqlSession.getMapper(UserMapper.class);List<OrderCustom> list=userMapper.findOrderCustom();//调用代理对象的方法,打印结果
        System.out.println(list.size());sqlSession.close();}
}

大功告成,这个测试代码我已经测试过了没有问题,所以如果有跟初学者想拿着博主的代码运行一遍也是没有问题的。

其实从最开始学到现在,博主一直有一个疑问,为了实现映射一直以来表和类中属性的命名都要保持一致。但是我们的java类规范命名都是用驼峰命名法,而数据库中属性命名大多采用下划线,这样保持一致不得不改变一方的命名规则,有没有什么方法可以两全呢?

答案就是resultMap,跟resultType直接进行类的映射不同,resultMap讲究的是属性的映射。为了举例我再引进一个类,商品类Goods

表结构是这样的

接下来要做的事就是使用resultMap从表中查出所有的数据

在使用resultMap之前要先定义它,怎么定义呢,看代码

<!-- 定义resultMap --><resultMap type="com.mybatis.pojo.Goods" id="goodsResultMap"><id column="id" property="id"/><result column="goods_name" property="goodsName"/><result column="goods_price" property="goodsPrice"/></resultMap>

主键用的是id,普通属性统一使用result。其中column和property分别代表在表和类中的属性名。resultMap的id是为了让下面的select语句引用的,接下来就给出select语句

<!-- 用resultMap查询goods信息 --><select id="findGoodsResultMap" resultMap="goodsResultMap">select * from goods</select>

整个xml的工作就算完成了,老规矩,下面给出mapper接口中的方法和测试代码(注意所有的测试都要加上@before的内容,我这里就懒得再写了)

//查询goods使用resultMappublic List<Goods> findGoodsResultMap();

//测试查询goods使用resultMap
    @Testpublic void testFindGoodsResultMap() throws Exception {//创建会话SqlSession sqlSession = sqlSessionFactory.openSession();//创建mapper代理对象UserMapper userMapper= sqlSession.getMapper(UserMapper.class);List<Goods> list=userMapper.findGoodsResultMap();//调用代理对象的方法,打印结果
        System.out.println(list.size());sqlSession.close();}

写到这里,是不是有人想叫博主用resultMap的方法来写一写之前一对一的查询呢,放心吧,我后面也会讲到的。

首先看需求,如果我想列出所有用户的所有订单,但是用户信息又不能重复该怎么办,这个时候resultType就不够用了,因为需求是用户信息不能重复所以订单类要以list的方式存在

用户类中如下所示

而我们的user表能否直接与上面的类对应呢,显然是不行的,既然不行的话resultMap就要上场了,之前就说过resultMap是细化到属性的对应的,我们完全可以将User类中的list中的对象细化到单独对应orders表,这样问题就解决了啊,那resultMap要怎么定义呢

首先把除去list的属性映射完(懒得麻烦就只写了id,username,address三个属性),写完就是下面这个样子

<resultMap type="com.mybatis.pojo.User" id="userAndOrdersResultMap"><id column="id" property="id"/><result column="username" property="username"/><result column="address" property="address"/></resultMap>

千万要记住我们的主表是user表,所以这里的type是User类

在resultMap里有一个属性collection,这个属性是专门为list准备的,让我们来看看加上这个会是什么样子的

<resultMap type="com.mybatis.pojo.User" id="userAndOrdersResultMap"><id column="id" property="id"/><result column="username" property="username"/><result column="address" property="address"/><collection property="orderList" ofType="com.mybatis.pojo.Orders"><id column="id" property="id"/><result column="user_id" property="user_id"/><result column="number" property="number"/><result column="createtime" property="createtime"/><result column="note" property="note"/></collection></resultMap>

在collection中的property对应类中的属性名,ofType对应类中的list中的对象类型,在这里就是Orders类了,剩下的东西就和之前的配置完全一样了,无非是将orders类中的属性名和表中的属性名对应了。

接下来就是select语句了

<!-- 查询用户关联订单使用resultMap --><select id="findUserAndOrdersResultMap" resultMap="userAndOrdersResultMap">SELECT user.id, user.username, user.address, orders.*FROMorders,userWHEREuser.id = orders.user_id;</select>

是不是sql语句发现和之前写的好像是一样的,啊哈哈,我也是写完才发现的,需求是随便编的。。。

下面是mapper接口中的方法和测试代码(注意所有的测试都要加上@before的内容,我这里就懒得再写了)

//查询User关联Orders使用resultMappublic List<User> findUserAndOrdersResultMap();

//测试查询User关联Orders使用resultMap
    @Testpublic void testFindUserAndOrdersResultMap() throws Exception {//创建会话SqlSession sqlSession = sqlSessionFactory.openSession();//创建mapper代理对象UserMapper userMapper= sqlSession.getMapper(UserMapper.class);List<User> list=userMapper.findUserAndOrdersResultMap();//调用代理对象的方法,打印结果
        System.out.println(list.size());sqlSession.close();}

我的数据库orders表中有三条记录,两条是同一个用户创建的,所以输出结果应该是2,没问题

最后啰嗦一点

如果需求变成订单再关联商品信息该怎么写呢,我们知道订单和商品也是一对一的,即一个订单里面只能有一个该商品的记录(注意,这里的一个指的不是一件,如果用户买了多件该商品最后也会变成一个商品记录,变的只是数量而已),相当于在Orders类中增加一个Goods类作为属性,这个时候该怎么写呢,Mybatis提供了一个叫做association的属性用于关联类,相当于在collection里加上一个association,这个时候,xml文件会变成这样

<resultMap type="com.mybatis.pojo.User" id="userAndOrdersResultMap"><id column="id" property="id"/><result column="username" property="username"/><result column="address" property="address"/><collection property="orderList" ofType="com.mybatis.pojo.Orders"><id column="id" property="id"/><result column="user_id" property="user_id"/><result column="number" property="number"/><result column="createtime" property="createtime"/><result column="note" property="note"/>

<association property="goods" javaType="com.mybatis.pojo.Goods"><id column="id" property="id"/><result column="goods_name" property="goodsName"/><result column="goods_price" property="goodsPrice"/></association>

</collection></resultMap>

这个博主就不去测试了,反正套路都是一样的

有了association,之前那个订单关联用户的查询也就迎刃而解了,只需在Orders类中加一个用户类的属性紧接着配一个association就OK了。

终于写完了,我长舒了一口气,花了大半个下午的时间呢,后面还会写多对多查询,整合spring框架的内容等等。。。

最后最后说一点,这些知识我也是在短期内学完的,算是现学现卖,如果哪位大神“随意”看了一眼发现了错误或者有更好的见解还请不吝赐教啊

转载于:https://www.cnblogs.com/scuury/p/8575189.html

Mybatis实现高级映射一对一、一对多查询相关推荐

  1. mybatis高级映射(一对一,一对多,多对多)

    http://www.cnblogs.com/selene/p/4627446.html 阿赫瓦里 生命对于某些人来说,一直都是美丽的,因为这些人的一生都在为某个梦想而奋斗!!! 博客园 首页 新随笔 ...

  2. mysql中建立一对多映射_Mybatis中的高级映射一对一、一对多、多对多

    学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...

  3. MyBatis的高级映射之多对一

    第五节 MyBatis的高级映射之多对一 2016年3月4日 星期五 09:25 使用传统方式的形式 使用MyBatis的方式 这样会产生两条语句 使用ResultMap的方式,对结果进行映射和转换, ...

  4. mybatis入门(六)----高级映射(一对一,一对多,多对多)

    阅读目录 一:订单商品数据模型 二.一对一查询 三.一对多查询 四.多对多查询 回到顶部 一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: View Code 测试数据代码: View C ...

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

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

  6. mybatis入门基础----高级映射(一对一,一对多,多对多)

    一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码:  查看代码 测试数据代码:  查看代码 2.数据模型分析思路 (1).每张表记录的数据内容:分模块对每张表记录的内容进行熟悉,相当于你学习 ...

  7. mybatis入门基础(六)----高级映射(一对一,一对多,多对多)

    阅读目录 一:订单商品数据模型 二.一对一查询 三.一对多查询 四.多对多查询 回到顶部 一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: 1 CREATE TABLE items ( 2 ...

  8. 【转自】mybatis入门基础----高级映射(一对一,一对多,多对多)

    转自:http://www.cnblogs.com/selene/p/4627446.html 可参考https://blog.csdn.net/liu_yanzhao/article/details ...

  9. 【MyBatis框架】高级映射-一对一查询

    一对一查询 根据上面我们分析的订单商品数据模型(链接:12.订单商品数据模型-分析思路.txt),我们来写一下有关一对一的查询,分别使用了resultType和resultMap指定输出参数类型 1. ...

  10. Mybatis中的关系映射(一对一,一对多,多对多)

    在网上寻了很久,大多数讲关系性的文章都是大篇幅的去将表照搬上来,本来就很生硬,此文就不在讲述关系性映射的具体实现,转而从浅层来讲讲其概念性. 1.1 关联关系概述 在关系型数据库中,多表之间存在着三种 ...

最新文章

  1. SCVMM2008R2学习(八),硬件配置文件
  2. MyEclipse设置JSP页面默认编码方式
  3. rust门卡有什么用_Rust能力养成之(10)用Cargo进行项目管理:扩展 调用与优化
  4. C++11:继承构造函数
  5. Python:递归输出斐波那契数列
  6. 191. 位1的个数 golang
  7. 小白用python处理excel文件-python处理excel文件
  8. Q145: 三次曲线对比及其矩阵表示(Bezier, B-Spline, Hermite, Catmull-Rom)
  9. eclipse如何设置成保护眼的背景色
  10. 单片机:Keil的安装教程
  11. 操作系统中的句柄是什么?
  12. HttpGet请求数据乱码的原因
  13. 读计算机视觉综述做的脑图(11.09更新)
  14. C++实现字符串去掉前后的空格
  15. 计算机关机界面卡住,电脑关机时卡在关机界面的解决方法
  16. IE浏览器控制台空白
  17. TDM和STDM复用
  18. 快来帮你三分钟了解物联网
  19. ubuntu 12.04 用后感
  20. 优恩对比分析GDT陶瓷气体放电管与TSS放电管

热门文章

  1. linux查看硬盘分区类型,linux 下查看硬盘分区类型
  2. 文件与i o流java实_JavaFile I/O流
  3. 羞,Spring Bean 初始化/销毁竟然有这么多姿势
  4. linux 创建用户/添加用户/用户组添加修改删除(ubuntu/centos)
  5. Oracle 存储过程、存储函数 与原生 JDBC 调用
  6. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_06-freemarker基础-遍历map数据...
  7. 精通ASP.NET Web程序测试
  8. windowns系统下 通过asmcmd进入asm实例时可能会遇到的一些问题
  9. 洛谷 P3063 [USACO12DEC]牛奶的路由Milk Routing
  10. linux(ubuntu) 搭建java程序运行环境