表结构

1
2
3
4
5
Hero      Category      Hero_Category
------- ------- -------------
id id hero_id
name name cate_id
superior

英雄表和分类表是多对多的关系,分类表里面的 superior为上级分类 id,superiorid 是一对多的关系。

实体对象

1
2
3
4
5
6
7
public class Hero {
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "orm_hero_cate",
joinColumns = @JoinColumn(name = "hero_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "cate_id", referencedColumnName = "id"))
private List<Category> categories;
}
1
2
3
4
5
6
7
8
9
10
11
public class Category {
@ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.REMOVE}, optional = true)
@JoinColumn(name = "superior", referencedColumnName = "id")
private Category superior;

@ManyToMany(mappedBy = "categories")
private List<Hero> heroes;

@OneToMany(mappedBy="superior")
private List<Category> children;
}

相关说明:

  • @JoinTable,表示通过第三张关联表来管理 herocategoryjoinColumn,关联到主表的外键名,主表名+下划线+主表中的主键列名,即 hero_id。关联到从表的外键名,主表中用于关联的属性名+下划线+从表的主键列名,即cate_id。
  • 主表就是关系维护端对应的表,从表就是关系被维护端对应的表
  • superiorid 是一对多的关系,@ManyToOne来表示
  • mapperBy表示关联的属性字段

测试代码

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
@Test
public void testSave(){
List<Category> categoryList = categoryDao.findByLevel(0);
if (categoryList.size() == 0){
Category testCate = Category.builder().name("testCate").level(1).createTime(new DateTime()).lastUpdateTime(new DateTime()).build();
Category testCate_1 = Category.builder().name("testCate_1").level(2).superior(testCate).createTime(new DateTime()).lastUpdateTime(new DateTime()).build();
Category testCate_2 = Category.builder().name("testCate_2").level(2).superior(testCate).createTime(new DateTime()).lastUpdateTime(new DateTime()).build();
Category testCate_1_1 = Category.builder().name("testCate_1_1").level(3).superior(testCate_1).createTime(new DateTime()).lastUpdateTime(new DateTime()).build();
categoryList.add(testCate);
categoryList.add(testCate_1);
categoryList.add(testCate_2);
categoryList.add(testCate_1_1);

categoryDao.saveAll(categoryList);
List<Category> categories = categoryDao.findAll();
log.debug("【分类】={}", JSONArray.toJSONString(categories));
}

heroDao.findById(1).ifPresent(hero -> {
hero.setCategories(categoryList);
hero.setName("添加分类");
heroDao.save(hero);
});

log.debug("【英雄分类】={}", JSONUtil.toJsonStr(heroDao.findById(1).get().getCategories()));
}

参考

https://stackoverflow.com/questions/5478328/jpa-jointable-annotation

https://github.com/xkcoding/spring-boot-demo/tree/master/spring-boot-demo-orm-jpa