问题
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>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于