问题 ORM映射中,一对多,多对多是非常常见的方式。但是由于场景使用没有这么多,到今天我才发现这个问题。
配置映射关系,使字段与DO
类解耦,方便维护。但是为了方便管理和控制,我就在一个.java
文件中写了两个VO
类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @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了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <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 ="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_
区分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 < select id= "selectHotWordByCategoryId" parameterType= "int" resultMap= "result"> select < ! < ! 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啦。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <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 >