Mybatis 多对多映射的小问题

本贴最后更新于 2033 天前,其中的信息可能已经时异事殊

问题

ORM 映射中,一对多,多对多是非常常见的方式。但是由于场景使用没有这么多,到今天我才发现这个问题。

配置映射关系,使字段与 DO 类解耦,方便维护。但是为了方便管理和控制,我就在一个 .java 文件中写了两个 VO 类。

@ToString @Setter(value = AccessLevel.PUBLIC) @Getter(value = AccessLevel.PUBLIC) @NoArgsConstructor @AllArgsConstructor @JsonInclude(value = JsonInclude.Include.NON_NULL) public class CategoryVO { private Long cid; private Long pid; private Integer level; private Integer sortNo; private String cname; private java.sql.Timestamp created; private java.sql.Timestamp updated; private List<Word> words; } @ToString @Setter(value = AccessLevel.PUBLIC) @Getter(value = AccessLevel.PUBLIC) @NoArgsConstructor @AllArgsConstructor @JsonInclude(value = JsonInclude.Include.NON_NULL) class Word { private Long id; private Long hotWordId; private Long categoryId; private String keyword; private Integer source; private Integer sortNo; private Integer isDeleted; private java.sql.Timestamp created; private java.sql.Timestamp updated; }

它们的关系也非常简单,可以直接看出,一个类目(分类)对应多组 HotWord(热词)。所以在 resultMap 中为了图快我就直接把属性一个个映射数据库的 column 了。

<resultMap id="result" type="{hape}.common.orm.model.vo.CategoryVO"> <!-- 相同的列名id --> <id column="id" jdbcType="INTEGER" property="cid"/> <result column="parent_id" jdbcType="INTEGER" property="pid"/> <result column="name" jdbcType="VARCHAR" property="cname"/> <result column="level" jdbcType="INTEGER" property="level"/> <result column="sort_no" jdbcType="INTEGER" property="sortNo"/> <collection property="words" ofType="{hape}.common.orm.model.vo.Word"> <!-- 相同的列名id --> <id column="id" jdbcType="INTEGER" property="id"/> <result column="hotword_id" jdbcType="INTEGER" property="hotWordId"/> <result column="category_id" jdbcType="INTEGER" property="categoryId"/> <result column="keyword" jdbcType="VARCHAR" property="keyword"/> <result column="source" jdbcType="TINYINT" property="source"/> <result column="sort_no" jdbcType="INTEGER" property="sortNo"/> <result column="is_deleted" jdbcType="TINYINT" property="isDeleted"/> <result column="created" jdbcType="TIMESTAMP" property="created"/> <result column="updated" jdbcType="TIMESTAMP" property="updated"/> </collection> </resultMap>

但是实际结果却并不是一个包含了多个子结构的对象,而是只有一个 words 对象,究其原因,原来是因为 colum 列名有重复,都存在一个相同的 id。

解决办法

你可以选择干掉其中一个 id,或者在使用 SQL 语句中加入别名加以区分,当字段较多的时候就会比较麻烦。我这里把字段都加上了 w_ 区分。

<select id="selectHotWordByCategoryId" parameterType="int" resultMap="result"> select <!-- 为什么要as "w_"呢?因为两张表的colum有相同的名称会出现问题,不然就只能查出子表的一条而不是多条了 --> t1.*, t2.id as w_id, t2.hotword_id as w_hotword_id, t2.keyword as w_keyword, t2.source as w_source, t2.sort_no as w_sort_no, t2.created as w_created, t2.updated as w_updated from xunfei_category t1 left join xunfei_hotword t2 on t1.id = t2.category_id where t1.id = #{id} and t2.is_deleted = 0 order by t2.sort_no, t2.updated desc </select>

然后在 resultMap 中修改成改后的别名就 OK 啦。

<resultMap id="result" type="{hape}.common.orm.model.vo.CategoryVO"> <id column="id" jdbcType="INTEGER" property="cid"/> <result column="parent_id" jdbcType="INTEGER" property="pid"/> <result column="name" jdbcType="VARCHAR" property="cname"/> <result column="level" jdbcType="INTEGER" property="level"/> <result column="sort_no" jdbcType="INTEGER" property="sortNo"/> <collection property="words" ofType="{hape}.common.orm.model.vo.Word"> <id column="w_id" jdbcType="INTEGER" property="id"/> <result column="w_hotword_id" jdbcType="INTEGER" property="hotWordId"/> <result column="w_category_id" jdbcType="INTEGER" property="categoryId"/> <result column="w_keyword" jdbcType="VARCHAR" property="keyword"/> <result column="w_source" jdbcType="TINYINT" property="source"/> <result column="w_sort_no" jdbcType="INTEGER" property="sortNo"/> <result column="w_is_deleted" jdbcType="TINYINT" property="isDeleted"/> <result column="w_created" jdbcType="TIMESTAMP" property="created"/> <result column="w_updated" jdbcType="TIMESTAMP" property="updated"/> </collection> </resultMap>
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 357 关注
  • 映射
    2 引用
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    346 引用 • 760 回帖
  • 多对多
    1 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    225 引用 • 1588 回帖
  • V2Ray
    1 引用 • 15 回帖 • 4 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 50 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    188 引用 • 319 回帖 • 237 关注
  • Access
    1 引用 • 3 回帖 • 3 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 165 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    326 引用 • 1395 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 635 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 4 关注
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    26694 引用 • 111172 回帖
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 685 关注
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    2 引用 • 32 回帖
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 5 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 651 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    415 引用 • 3601 回帖
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 117 关注
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    498 引用 • 934 回帖
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    29 引用 • 202 回帖 • 35 关注
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    84 引用 • 414 回帖
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1444 引用 • 10083 回帖 • 500 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    108 引用 • 295 回帖
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 773 关注
  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    29 引用 • 230 回帖 • 125 关注
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖