hibernate一对多关系映射(自身关联)
示例:一个类别(Category)下面有多个子类别,多个子类别属于同一个父类别。
- public class Category {
- private Integer id;
- private String name;
- private Category parentCategory; // 父类别
- private Set<Category> childCategories = new HashSet<Category>(); // 子类别
- // getter and setter
- }
用XML映射
- <hibernate-mapping package="org.monday.hibernate4.domain">
- <class name="Category" table="tbl_category">
- <id name="id">
- <generator class="identity" />
- </id>
- <property name="name" />
- <many-to-one name="parentCategory" class="Category" column="category_id" />
- <set name="childCategories" inverse="true" cascade="all">
- <key column="category_id" />
- <one-to-many class="Category" />
- </set>
- </class>
- </hibernate-mapping>
用@Annotation映射
- @Entity
- @Table(name = "tbl_category")
- public class Category {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Integer id;
- private String name;
- @ManyToOne
- @JoinColumn(name = "category_id")
- private Category parentCategory; // 父类别
- @OneToMany(mappedBy = "parentCategory", targetEntity = Category.class, cascade = CascadeType.ALL)
- private Set<Category> childCategories = new HashSet<Category>(); // 子类别
- //getter and setter
- }
测试代码
- Category foodCategory = new Category("food");
- Category fruitCategory = new Category("fruit");
- Category vegetableCategory = new Category("vegetable");
- Category appleCategory = new Category("apple");
- Category orangeCategory = new Category("orange");
- Category tomatoCategory = new Category("tomato");
- // 建立食品类别和水果类别之间的关联关系
- foodCategory.getChildCategories().add(fruitCategory);
- fruitCategory.setParentCategory(foodCategory);
- // 建立食品类别和蔬菜类别之间的关联关系
- foodCategory.getChildCategories().add(vegetableCategory);
- vegetableCategory.setParentCategory(foodCategory);
- // 建立水果类别和苹果类别之间的关联关系
- fruitCategory.getChildCategories().add(appleCategory);
- appleCategory.setParentCategory(fruitCategory);
- // 建立水果类别和桔子类别之间的关联关系
- fruitCategory.getChildCategories().add(orangeCategory);
- orangeCategory.setParentCategory(fruitCategory);
- // 建立西红柿类别和蔬菜类别之间的关联关系
- tomatoCategory.setParentCategory(vegetableCategory);
- vegetableCategory.getChildCategories().add(tomatoCategory);
- session.save(foodCategory);
SQL schema
- Hibernate:
- create table CATEGORYS (
- id integer not null,
- name varchar(255),
- category_id bigint,
- primary key (id)
- )
- Hibernate:
- alter table CATEGORYS
- add index FK36CF3159B3B4FFA (category_id),
- add constraint FK36CF3159B3B4FFA
- foreign key (category_id)
- references CATEGORYS (id)
-----------------------------改进代码---------------------------
1.改进实体类
- @Entity
- @Table(name = "tbl_category")
- public class Category {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Integer id;
- private String name;
- @ManyToOne
- @JoinColumn(name = "category_id")
- private Category parentCategory; // 父类别
- @OneToMany(mappedBy = "parentCategory", targetEntity = Category.class, cascade = CascadeType.ALL)
- private Set<Category> childCategories = new HashSet<Category>(); // 子类别
- //getter and setter
- /** 添加子类别 */
- public void addChildCategory(Category category) {
- if (category == null) {
- throw new IllegalArgumentException("Can't add a null Category as child.");
- }
- // 删除旧的父类别Category
- if (category.getParentCategory() != null) {
- category.getParentCategory().getChildCategories().remove(category);
- }
- // 设置新的父类别Category
- category.setParentCategory(this);
- // 向当前Category对象中加入子类别
- this.getChildCategories().add(category);
- }
- }
2.测试代码
- // 建立食品类别和水果类别之间的关联关系
- foodCategory.addChildCategory(fruitCategory);
- // 建立食品类别和蔬菜类别之间的关联关系
- foodCategory.addChildCategory(vegetableCategory);
- // 建立水果类别和苹果类别之间的关联关系
- fruitCategory.addChildCategory(appleCategory);
- // 建立水果类别和桔子类别之间的关联关系
- fruitCategory.addChildCategory(orangeCategory);
- // 建立西红柿类别和蔬菜类别之间的关联关系
- vegetableCategory.addChildCategory(tomatoCategory);
- session.save(foodCategory);