mybatis一对一查询功能

所属分类: 软件编程 / java 阅读数: 30
收藏 0 赞 0 分享

所谓的一对一查询,就是说我们在查询一个表的数据的时候,需要关联查询其他表的数据。

 需求

    首先说一个使用一对一查询的小需求吧:假设我们在查询某一个订单的信息的时候,需要关联查询出创建这个订单对应的用户信息。表模型如下(

 ResultType

  sql语句的书写

    首先,我们要对我们的需求进行分析。1.我们需要确定这个需求需要涉及到哪两张表,其中哪个是主表,哪个是关联表。具体怎么确定,还是看需求——我们的需求是说,在查询订单的时候,顺带着查出创建这个订单的用户。那么,已经很显然了。我们的主表是订单表(orders)。而我们的关联表则是用户表(user)。

    这个时候,我们就可以写出来如下sql语句了:

select * from orders

    这个时候,我们就应该考虑这个问题了:我们在关联查询的时候应该使用内链接?还是外链接?对于搞不清内链接外链接的区别的同学,我这里先简单的介绍一下,等以后有时间了,再详细写一篇博客说明:内连接是只显示满足条件的。外链接分为左外和右外链接:左连接显示左边全部的再加上右边与左边相同的;右连接显示右边全部的和左边与右边相同的。

  我们的需求是通过订单去关联用户,而由于在orders表中有一个外键(userId)。通过外键的去查关联表user表的数据时,userId是user表的主键。这时,只能查到一条user的信息,而这条记录不会导致我们的主查询结果发生改变。所以,我们选择内链接查询。这时候,我们的sql语句是这样的:

 select * from orders,user where orders.user_id = user.id

    查询完成后,出现结果如下:

    这时,问题来了,我们发现,这个时候出现了两个id,这就会导致我们的数据在输出的时候封装到对象时会出现问题。而且,User_id 这一列和我们的用户id数据是重复的。我们需要改造我们的sql。怎么改造呢?

    因为我们的主表数据是要全部查询的,而用户表我们只需要username,sex,adress这三个信息(这里是假设,没必要纠结需要的是啥信息)。那么我们就需要手动指定我们的sql语句的查询字段了:    

SELECT 
 orders.*,
 USER.username,
 USER.sex,
 USER.address 
FROM
 orders,
 USER 
WHERE orders.user_id = user.id

    前面的这些都是在我们的sql链接工具上进行查询的,当可以显示我们需要的数据库后,我们的sql语句就确定了。这时我们该开始下一步了:

   创建pojo

    我们需要将查询到的结果,通过mybatis框架将数据封装到对应的对象。那么,问题来了,这个查询到的数据由谁来接收?我们如果要将上边sql查询的结果映射到pojo中,pojo中必须包括所有查询列名。但是不管是原来的Orders类还是User类,都没有办法映射全部的字段。这时,我们有一个很简单的解决办法:根据返回的字段,专门写一个类,让它包含所有的查询结果,然后让这个类去接收这个返回的结果集。

    这时有个小技巧,我们的新的pojo中,不需要将所有的字段全部都写上,我们可以让新pojo去继承我们的包含结果集中查询字段较多的一个类,然后将其他需要的数据写到这个子类中即可。

    创建pojo完成后,我们就需要根据规范去创建我们的映射文件和写对应的接口中的方法:

    mapper.xml

    mapper.java中的接口:

 ResultMap

    sql语句上,resultType 和resuleMap实现的方式一样,这里就直接跳过了。

  使用resultMap映射的思路

    我们知道,使用pojo的时候,我们可以将一些数据封装到pojo的对象属性中,他的属性可以是简单类型,也可以是另外一个pojo。这时,我们可以这么做:

    使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。

    Orders类中添加user属性

  mapper.xml

    用resultMap的方法将结果集进行映射的时候,我们需要进行两个操作,一个是定义resultMap,设置每个查到的结果集中的列相对应的对象的属性。这个比较麻烦但是不难。二就是定义我们的statement。

   resultMap

    resultMap实现的基本思路我们刚才已经说了。而且也在orders的pojo类中增加了相应的属性了。接下啦,就是写一个resultMap,将整个查询的结果映射到Orders中在这里面,首先是order订单的映射。就是直接用id 和result标签将两者相互对应即可。然后就是,关联的用户信息的映射,这时候需要用到一个association的标签,将在orders类中的user字段与User类进行映射,然后在其内部还是用id和result标签,将查询的数据和User的属性相映射。

    具体代码如下:   

<!-- 订单查询关联用户的resultMap
 将整个查询的结果映射到cn.mybatis.po.Orders中
  -->
 <resultMap type="cn.mybatis.po.Orders" id="OrdersUserResultMap">
  <!-- 配置映射的订单信息 -->
  <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
   column:订单信息的唯 一标识 列
   property:订单信息的唯 一标识 列所映射到Orders中哪个属性
   -->
  <id column="id" property="id"/>
  <result column="user_id" property="userId"/>
  <result column="number" property="number"/>
  <result column="createtime" property="createtime"/>
  <result column="note" property=note/>
  
  <!-- 配置映射的关联的用户信息 -->
  <!-- association:用于映射关联查询单个对象的信息
  property:要将关联查询的用户信息映射到Orders中哪个属性
   -->
  <association property="user" javaType="cn.mybatis.po.User">
   <!-- id:关联查询用户的唯 一标识
   column:指定唯 一标识用户信息的列
   javaType:映射到user的哪个属性
    -->
   <id column="user_id" property="id"/>
   <result column="username" property="username"/>
   <result column="sex" property="sex"/>
   <result column="address" property="address"/>
  
  </association>
 </resultMap>

   statement

    statement比较简单,就是将返回结果集的映射方式改成resultMap。然后将返回类型只想我们刚完成的resultMap就可以了。

  mapper.java    

 两者的区别

    实现一对一查询的方法说完了,接下来分析下它们的不同之处,和优劣之处。

    首先,都需要对pojo进行修改,一个是增加一个pojo类另外一个则是修改pojo的字段。个人感觉,根据设计模式中的开闭原则。resultType要比resultMap更好一些。

    其次,简易程度上来说,使用resultType实现较为简单。从这点讲,resultType也要比resultMap更好一些。

    不过resultMap可以实现延迟加载,resultType无法实现延迟加载。这方面resultType就不如resultMap更好了。

    所以:建议大家,如果没有查询结果的特殊要求的话使用resultType。

以上所述是小编给大家介绍的mybatis一对一查询功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

更多精彩内容其他人还在看

Java的面向对象编程基本概念学习笔记整理

这篇文章主要介绍了Java的面向对象编程基本概念学习笔记整理,包括类与方法以及多态等支持面向对象语言中的重要特点,需要的朋友可以参考下
收藏 0 赞 0 分享

Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法

这篇文章主要介绍了Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

基于Java实现杨辉三角 LeetCode Pascal's Triangle

这篇文章主要介绍了基于Java实现杨辉三角 LeetCode Pascal's Triangle的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java中Spring获取bean方法小结

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢?下面通过本文给大家介绍Java中Spring获取bean方法小结,对spring获取bean方法相关知识感兴趣的朋友一起学习吧
收藏 0 赞 0 分享

如何计算Java对象占用了多少空间?

在Java中没有sizeof运算符,所以没办法知道一个对象到底占用了多大的空间,但是在分配对象的时候会有一些基本的规则,我们根据这些规则大致能判断出来对象大小,需要的朋友可以参考下
收藏 0 赞 0 分享

剖析Java中的事件处理与异常处理机制

这篇文章主要介绍了Java中的事件处理与异常处理机制,讲解Java是如何对事件或者异常作出响应以及定义异常的一些方法,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Java的Struts2框架的结构及其数据转移方式

这篇文章主要介绍了详解Java的Struts2框架的结构及其数据转移方式,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

Java封装好的mail包发送电子邮件的类

本文给大家分享了2个java封装好的mail包发送电子邮件的类,并附上使用方法,小伙伴们可以根据自己的需求自由选择。
收藏 0 赞 0 分享

在Java的Struts中判断是否调用AJAX及用拦截器对其优化

这篇文章主要介绍了在Java的Struts中判断是否调用AJAX及用拦截器对其优化的方法,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

java多线程Future和Callable类示例分享

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。今天我们就来研究下Future和Callab
收藏 0 赞 0 分享
查看更多