mybatis主从表关联查询,返回对象带有集合属性解析
作者:瘦_猴 发布时间:2023-06-15 16:10:59
标签:mybatis,关联查询,返回对象,集合
主从表关联查询,返回对象带有集合属性
昨天有同事让我帮着看一个问题,mybatis主从表联合查询,返回的对象封装集合属性。我先将出现的问题记录一下,然后再讲处理方法也简单说明一下:
VersionResult为接收返回数据对象
get\set方法我这里就省略了。
public class VersionResult extends BaseResult implements Serializable{
private Integer id;
private String code;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
private Date createTimes;
//记录内容表的集合对象
private List<UpdateRecordEntity> UpdateRecordEntityList;
}
UpdateRecordEntity为从表数据
同样get\set方法我这里就省略了。
@Table(name = "z_update_record")
public class UpdateRecordEntity extends BaseEntity {
@Id
private Integer id;
@Column(name = "version_id")
private Integer versionId;
@Column(name = "module_name")
private String moduleName;
@Column(name = "update_content")
private String updateContent;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
@Column(name = "create_time")
private Date createTime;
@Column(name = "is_delete")
private Integer isDelete;
}
mapper.xml写法,这个是关键
<!--跟新记录表封装的对象-->
<resultMap id="BaseResultMap" type="com.wangtiansoft.wisdomedu.persistence.result.server.VersionResult">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="code" property="code" />
<result column="create_time" property="createTimes" />
<collection property="UpdateRecordEntityList" ofType="com.wangtiansoft.wisdomedu.persistence.entity.UpdateRecordEntity">
<id property="id" column="id"/>
<result property="versionId" column="version_id"/>
<result property="moduleName" column="module_name"/>
<result property="updateContent" column="update_content"/>
<result property="createTime" column="create_time"/>
<result property="isDelete" column="is_delete"/>
<result property="tenantId" column="tenant_id"/>
</collection>
</resultMap>
sql查询语句
<select id="selectVersionList" parameterType="map" resultMap="BaseResultMap">
SELECT
z.`code`,
z.create_time createTimes,
zur.module_name moduleName,
zur.update_content updateContent,
zur.create_time createTime
FROM
z_version z
LEFT JOIN z_update_record zur ON z.id = zur.version_id
WHERE
z.tenant_id = #{tenantId}
AND z.is_delete = 0
AND z.is_disabled = 0
AND zur.tenant_id = #{tenantId}
AND zur.is_delete = 0
AND YEAR(z.create_time)=YEAR(#{date})
ORDER by z.create_time desc
</select>
执行sql返回的数据
页面调取接口
下面我将接口数据粘贴下来:
{
"code": "0",
"msg": "",
"data": [{
"id": null,
"code": "1419",
"createTimes": null,
"updateRecordEntityList": []
}, {
"id": null,
"code": "开发修改1111",
"createTimes": null,
"updateRecordEntityList": []
}, {
"id": null,
"code": "开发修改1111",
"createTimes": null,
"updateRecordEntityList": []
}, {
"id": null,
"code": "开发修改1111",
"createTimes": null,
"updateRecordEntityList": []
}, {
"id": null,
"code": "开发修改1111",
"createTimes": null,
"updateRecordEntityList": []
}]
}
观察code、createTimes、updateRecordEntityList三个属性,会发现只有code字段有值其余的全部为null。分析这个是为啥呢?找点资料粘贴如下:
发现是sql数据和VersionResult的mapper.xml中映射关系有点问题,没有对应起来。resultMap中必须将别名和上面resultMap对的上就行,很明显sql返回数据的列明没有和resultMap一一对应起来,因此有了以下对xml文件的修改:
<resultMap id="BaseResultMap" type="com.wangtiansoft.wisdomedu.persistence.result.server.VersionResult">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="code" property="code" />
<result column="createTimes" property="createTimes" />
<collection property="UpdateRecordEntityList" ofType="com.wangtiansoft.wisdomedu.persistence.entity.UpdateRecordEntity">
<id property="id" column="id"/>
<result property="moduleName" column="moduleName"/>
<result property="updateContent" column="updateContent"/>
<result property="createTime" column="createTime"/>
</collection>
</resultMap>
数据显示正常:
{
"code": "0",
"msg": "",
"data": [{
"code": "1419",
"createTimes": "2019-09-02 00:00",
"updateRecordEntityList": [{
"moduleName": "安达市大所",
"updateContent": "1321321",
"createTime": "2019-09-02 10:17"
}]
}, {
"code": "开发修改1111",
"createTimes": "2019-05-07 00:00",
"updateRecordEntityList": [{
"moduleName": "平台111111",
"updateContent": "平台版本第一次更新1",
"createTime": "2019-08-15 15:07"
}]
}, {
"code": "开发修改1111",
"createTimes": "2019-05-07 00:00",
"updateRecordEntityList": [{
"moduleName": "111",
"updateContent": "111",
"createTime": "2019-08-16 11:16"
}]
}, {
"code": "开发修改1111",
"createTimes": "2019-05-07 00:00",
"updateRecordEntityList": [{
"moduleName": "515",
"updateContent": "5155",
"createTime": "2019-08-21 17:29"
}]
}, {
"code": "开发修改1111",
"createTimes": "2019-05-07 00:00",
"updateRecordEntityList": [{
"moduleName": "2222",
"updateContent": "第二次更新",
"createTime": "2019-08-22 14:23"
}]
}]
}
mybatis关联查询(对象嵌套对象)
Mybatis 查询对象中嵌套其他对象的解决方法有两种,
一种是用关联另一个resultMap的形式
如下:
<association property="office" javaType="Office" resultMap="officeMap"/>
<mapper namespace="com.dixn.oa.modules.sys.dao.RoleDao">
<resultMap type="Office" id="officeMap">
<id property="id" column="id" />
<result property="name" column="office.name" />
<result property="code" column="office.code" />
</resultMap>
<resultMap id="roleResult" type="Role">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="enname" column="enname" />
<result property="roleType" column="roleType" />
<result property="dataScope" column="dataScope" />
<result property="remarks" column="remarks" />
<result property="useable" column="useable" />
<association property="office" javaType="Office" resultMap="officeMap"/>
<collection property="menuList" ofType="Menu">
<id property="id" column="menuList.id" />
</collection>
<collection property="officeList" ofType="Office">
<id property="id" column="officeList.id" />
</collection>
</resultMap>
<sql id="roleColumns">
a.id,
a.office_id AS "office.id",
a.name,
a.enname,
a.role_type AS roleType,
a.data_scope AS dataScope,
a.remarks,
a.create_by AS "createBy.id",
a.create_date,
a.update_by AS "updateBy.id",
a.update_date,
a.del_flag,
o.name AS "office.name",
o.code AS "office.code",
a.useable AS useable,
a.is_sys AS sysData
</sql>
<select id="get" resultMap="roleResult">
SELECT
<include refid="roleColumns"/>
rm.menu_id AS "menuList.id",
ro.office_id AS "officeList.id"
FROM sys_role a
JOIN sys_office o ON o.id = a.office_id
LEFT JOIN sys_role_menu rm ON rm.role_id = a.id
LEFT JOIN sys_role_office ro ON ro.role_id = a.id
WHERE a.id = #{id}
</select>
一种联合查询 (一对一)的实现
但是这种方式有“N+1”的问题,不建议使用
<resultMap id="roleResult" type="Role">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="enname" column="enname" />
<result property="roleType" column="roleType" />
<result property="dataScope" column="dataScope" />
<result property="remarks" column="remarks" />
<result property="useable" column="useable" />
<association property="office" javaType="Office" column="id" select="getOfficeById"/>
<collection property="menuList" ofType="Menu">
<id property="id" column="menuList.id" />
</collection>
<collection property="officeList" ofType="Office">
<id property="id" column="officeList.id" />
</collection>
</resultMap>
<select id="getOfficeById" resultType="Office">
select o.name AS "office.name",o.code AS "office.code" from sys_office o where o.id = #{id}
</select>
来源:https://blog.csdn.net/weixin_43839457/article/details/100513385
0
投稿
猜你喜欢
- 下面是一个AOP实现的简单例子:首先定义一些业务方法:/** * Created with IntelliJ IDEA. 
- 实践过程效果代码public partial class Form1 : Form {
- API参数:/**fileName: 临时文件的名字, 生成后的文件名字将会是【fileName + 随机数】suffix: 文件后缀,例如
- VisualVM是JDK自带的一款全能型性能监控和故障分析工具,包括对CPU使用、JVM堆内存消耗、线程、类加载的实时监控,内存dump文件
- 自定义注解+springAop参数非空校验自定义注解,来对对应的方法进行入参校验,为空返回参数错误新建注解类@interface Param
- 介绍使用mybatis时可以使用二级缓存提高查询速度,进而改善用户体验。使用redis做mybatis的二级缓存可是内存可控<如将单独
- 前言本文主要给大家介绍了关于Spring Boot应用极速部署脚本的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧
- 一:算术运算符1.算术运算符有哪些①基本四则运算符:+ - * / %②增量赋值运算符:+= -= *= /= %=③自增/自减运算符++
- Spring提供的工具类,主要用于框架内部使用,这个类提供了一些简单的方法,并且提供了易于使用的方法在分割字符串,如CSV字符串,以及集合和
- 一、项目创建创建一个控制台应用程序,项目右键->管理 NuGet 程序包->Topshelft及Topshelf.Log4Net
- Jetty和tomcat的比较Tomcat和Jetty都是一种Servlet引擎,他们都支持标准的servlet规范和JavaEE的规范。架
- 最近有一个项目要用到年份周期,用于数据统计图表展示使用,当中用到年份周期,以及年份周期所在的日期范围。当初设想通过已知数据来换算年份周期,经
- 这篇文章主要介绍了Java集合使用 Iterator 删除元素,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 本文实例为大家分享了Java打印指定年月日历的具体代码,供大家参考,具体内容如下日历如下:程序如下://打印指定年月的日历public cl
- 在使用Mybatis时,有的时候我们可以不用定义resultMap,而是直接在<select>语句上指定resultType。这
- 第一种就是 最常见的 用Try..Catch..再try中强转你要确认的string 类型成功就是int catch 就不是&n
- 通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作。注:如果对Java8新特性
- 上帝之火本系列讲述的是开源实时监控告警解决方案Prometheus,这个单词很牛逼。每次我都能联想到带来上帝之火的希腊之神,普罗米修斯。而这
- 本文实例讲述了Java设计模式之工厂模式。分享给大家供大家参考,具体如下:一、 简单工厂先来思考一个问题。我们平时写程序时,会有这种情况,A
- 一、概述无论是什么语言,在多线程编程中,常常会遇到多个线同时操作程某个变量(读/写),如果读/写不同步,则会造成不符合预期的结果。例如:线程