解决mybatis三表连接查询数据重复的问题
作者:周向源 发布时间:2023-09-13 15:24:25
此问题的产生,主要是数据库的字段名一样导致
三张表 DOCTOR JOB OBJECT
有问题的查询语句和查询结果是:
SELECT d.*,j.*,o.* from
(select d.*,rownum r from DOCTOR d where rownum<=6) d
join job j on d.job_id=j.id join object o on o.id=d.object_id
where r>0
<img src="https://img-blog.csdn.net/20161020110037608?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
注意 :查询结果中有6列是一样的id,name
修改为别名
SELECT d.*,j.name jobn,j.id jid,j.oid joid,o.id objid,o.name objn from
(select d.*,rownum r from DOCTOR d where rownum<=6) d
join job j on d.job_id=j.id join object o on o.id=d.object_id
where r>0
<span style="color:#3366ff;">新的查询结果是: 注意看列名</span>
<span style="color:#3366ff;">
</span>
<span style="color:#3366ff;"><img src="https://img-blog.csdn.net/20161020110703515?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
</span>
此时依然不能解决数据重复问题,还需要修改resultMap的column属性名为别名
至此问题全部解决!
补充:Mybatis连3表查询数据resultMap结果映射
一、前言
MyBatis是基于“数据库结构不可控”的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与现实间转换的手段了,而resultMap就是结果集映射的配置标签了。
二、从SQL查询结果到领域模型实体
在深入ResultMap标签前,我们需要了解从SQL查询结果集到JavaBean或POJO实体的过程。
1. 通过JDBC查询得到ResultSet对象
2. 遍历ResultSet对象并将每行数据暂存到HashMap实例中,以结果集的字段名或字段别名为键,以字段值为值
3. 根据ResultMap标签的type属性通过反射实例化领域模型
4. 根据ResultMap标签的type属性和id、result等标签信息将HashMap中的键值对,填充到领域模型实例中并返回
三、ResultMap标签
1. 属性说明
id属性 ,resultMap标签的标识。
type属性 ,返回值的全限定类名,或类型别名。
autoMapping属性 ,值范围true(默认值)|false, 设置是否启动自动映射功能,自动映射功能就是自动查找与字段名小写同名的属性名,并调用setter方法。而设置为false后,则需要在`resultMap`内明确注明映射关系才会调用对应的setter方法。
2. 基本作用:建立SQL查询结果字段与实体属性的映射关系信息
示例1:通过setter构造领域模型
public class EStudent{
private long id;
private String name;
private int age;
// getter,setter方法
/**
* 必须提供一个无参数的构造函数
*/
public EStudent(){}
}
<select id="getStudent" resultMap="getStudentRM">
SELECT ID, Name, Age
FROM TStudent
</select>
<resultMap id="getStudentRM" type="EStudnet">
<id property="id" column="ID"/>
<result property="studentName" column="Name"/>
<result property="studentAge" column="Age"/>
</resultMap>
子元素说明:
id元素 ,用于设置主键字段与领域模型属性的映射关系
result元素 ,用于设置普通字段与领域模型属性的映射关系
示例2:通过构造函数构造领域模型
public class EStudent{
private long id;
private String name;
private int age;
// getter方法
public EStudent(long id, String name, int age){
this.id = id;
this.name = name;
this.age = age;
}
}
<select id="getStudent" resultMap="getStudentRM">
SELECT ID, Name, Age
FROM TStudent
</select>
<resultMap id="getStudentRM" type="EStudnet">
<constructor>
<idArg column="ID" javaType="_long"/>
<arg column="Name" javaType="String"/>
<arg column="Age" javaType="_int"/>
</constructor>
</resultMap>
子元素说明:
constructor元素 ,指定使用指定参数列表的构造函数来实例化领域模型。注意:其子元素顺序必须与参数列表顺序对应
idArg子元素 ,标记该入参为主键
arg子元素 ,标记该入参为普通字段(主键使用该子元素设置也是可以的)
3. 一对一关系、一对多关系查询这里不多说
注意:在采用嵌套结果的方式查询一对一、一对多关系时,必须要通过resultMap下的id或result标签来显式设置属性/字段映射关系,否则在查询多条记录时会仅仅返回最后一条记录的情况。
4. 动态映射关系信息
通过 discriminator子元素 (鉴别器)可以实现动态映射关系信息的设置。具体示例如下:
public class EStudent{
private long id;
private String name;
private String juniorHighSchool;
private String seniorHighSchool;
private int during; // 在本校就读时间
// getter,setter方法
/**
* 必须提供一个无参数的构造函数
*/
public EStudent(){}
}
情景:查询学生信息的seniorHighSchool信息,若就读时间during字段值为4、5、6时,则以juniorHighSchool字段作所为seniorHighSchool信息。
<select id="getStundent" resultMap="rm">
SELECT ID, Name, JuniorHighSchool, SeniorHighSchool, during
FROM TStudent
</select>
<resultMap id="rm" type="EStudent">
// 若不加这句,则当将juniorHighSchool赋予给seniorHighSchool属性时,juniorHighSchool属性将为null
<result column="juniorHighSchool" property="juniorHighSchool"/>
<discriminator column="during" javaType="_int">
// 形式1:通过resultType设置动态映射信息
<case value="4" resultType="EStudent">
<result column="juniorHighSchool" property="seniorHighSchool"/>
</case>
// 形式2: 通过resultMap设置动态映射信息
<case value="5" resultMap="dynamicRM"/>
<case value="6" resultMap="dynamicRM"/>
</discriminator>
</resultMap>
<resultMap id="dynamicRM" type="EStudent">
<result column="juniorHighSchool" property="seniorHighSchool"/>
</resultMap>
注意:上面关于 discriminator子元素 的 case元素 的 resultType属性 和 resultMap元素 的 type属性 ,均不是直指返回的领域模型类型,而是指定根据判断条件后得到映射关系,可通过 id子元素 和 result子元素 重写映射关系。
5. id元素,result元素,idArg元素,arg元素,discriminator元素的共同属性
javaType属性 :Java类的全限定名,或别名
jdbcType属性 :JDBC类型, JDBC类型为CUD操作时列可能为空时进行处理
typeHandler属性 :指定类型处理器的全限定类名或类型别名
column属性 :指定SQL查询结果的字段名或字段别名。将用于JDBC的 resultSet.getString(columnName)
四、总结
掌握上述内容,那么在写一对一关系、一对多关系查询时就更有把握了哦!
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/SVDJASFHIAU/article/details/52870104
猜你喜欢
- 本文实例讲述了C#中list用法。分享给大家供大家参考,具体如下:protected void Page_Load(object sende
- 最近的项目中,想做到一种能够吸引眼球的一种角色选择浏览效果Demo源码:点击打开链接最终实现了下按如下图这么一种浏览效果:效果图一效果图二可
- 什么是TKMybatisTKMybatis 是基于Mybatis 框架开发的一个工具,内部实现了对单表的基本数据操作,只需要简单继承 TKM
- 功能介绍功能:群聊+私发+上线提醒+下线提醒+查询在线用户文件Utils需要用maven导入下面两个包 <dependency>
- 一、实现MyBatis ID构建接口@Slf4j@Componentpublic class CustomIdGenerator imple
- 和之前一样首先看一下WPF钟表效果图 是不是很炫酷,上面的那个花都是带有动画效果的图片 。接下来就是代码了。首先看一下整个场景的布局搭建&l
- 一次性全部绘制出来实现代码import java.awt.*;public class AlgoVisualizer {private st
- 对于QQ截图,肯定是早就有认识了,只是一直没有去认真观察这个操作的具体实现步骤。所以这里将自己的记忆中的步骤简单的写一下:习惯性用QQ或者T
- 一、线程的优先级别线程优先级别的使用范例:package cn.galc.test;public class TestThread6 { p
- 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义。通过
- 一、概念从本质上来说,它就是一个匿名函数,可以用来直接实现接口中的方法,从而简化代码。但是Lambda有一个限制,不能实现接口中的所有方法,
- @Param注解导致分页失效—分页 * 问题描述在使用mybatis分页时,使用@Param注解传入了两个对象,分页失效,查询出的总是全部的
- SpringCloud是分布式微服务架构的一站式解决方案,十多种微服务架构落地技术的集合体,俗称微服务全家桶SpringCloud和Spri
- Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excut
- 1.Spring IOC容器可以管理bean的生命周期,Spring允许在bean生命周期内特定的时间点执行指定的任务。2.Spring I
- 本文主要给大家介绍的是关于Android实现微信雷达扫描效果的相关内容,分享出来供大家参考学习,下面来看看详细的介绍:废话不多说 先上图(用
- 前言随着使用 Spring 进行开发的个人和企业越来越多,Spring 也慢慢从一个单一简洁的小框架变成一个大而全的开源软件,Spring
- 作为代码质量检查的流行工具,比如Sonarqube能够检查代码的“ * ”,跟代码结合起来能够更好地提高代码的质量,这篇文章将会介绍如何结合
- Java基础将Bean属性值放入Map中的实例利用发射将Java对象的属性值以属性名称为键,存储到Map中的简单实现。包括自身属性及从父类继
- 一、前导知识串行口是计算机的标准接口,现在的PC机(个人电脑)一般至少有两个串行口COM1和COM2。串行口应用广泛,在数据通信、计算机网络