表结构
1 2 3 4 5
| Hero Category Hero_Category
id id hero_id name name cate_id superior
|
英雄表和分类表是多对多的关系,分类表里面的 superior
为上级分类 id,superior
和 id
是一对多的关系。
实体对象
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
,表示通过第三张关联表来管理 hero
和 category
,joinColumn
,关联到主表的外键名,主表名+下划线+主表中的主键列名,即 hero_id。关联到从表的外键名,主表中用于关联的属性名+下划线+从表的主键列名,即cate_id。
- 主表就是关系维护端对应的表,从表就是关系被维护端对应的表
superior
和 id
是一对多的关系,@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