Hibernate_树状映射

通过Hibernate创建的Region表结构是id、name、parent_id

Region类代码:

@Entity
public class Region {
	private int id;
	private String name;
	private Set<Region> childs=new HashSet<Region>();
	private Region parent;
	
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@OneToMany(mappedBy="parent",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
	public Set<Region> getChilds() {
		return childs;
	}
	public void setChilds(Set<Region> childs) {
		this.childs = childs;
	}
	@ManyToOne
	@JoinColumn(name="parent_id")
	public Region getParent() {
		return parent;
	}
	public void setParent(Region parent) {
		this.parent = parent;
	}
}

 

测试类:

public class Hibernate_ORMappingTest {
 private static SessionFactory sessionFactory;
 
 @BeforeClass
 public static void beforeClass(){
  new SchemaExport(new AnnotationConfiguration().configure()).create(true, true);
  sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory();
  System.out.println("before");
 }
 
 @AfterClass
 public static void afterClass() {
  sessionFactory.close();
 }
 
 @Test
 public  void testTree(){
  System.out.println("1");
 }
 
 @Test
 public void saveRegion(){
  Region r=new Region();
  Region r1=new Region();
  Region r2=new Region(); 
  Region r3=new Region();
  r.setName("福建");
  r1.setName("福州");
  r2.setName("厦门");
  r3.setName("鼓楼区");
  r1.setParent(r);
  r2.setParent(r);
  r3.setParent(r1);
  r.getChilds().add(r1);
  r.getChilds().add(r2);
  r1.getChilds().add(r3);
  
  Session session=sessionFactory.getCurrentSession();
  session.beginTransaction();
  session.save(r);
  session.getTransaction().commit();
 }
 
 @Test
 public void loadRegion(){
  this.saveRegion();
  Session session=sessionFactory.getCurrentSession();
  session.beginTransaction();
  Region r=(Region)session.load(Region.class, 1);
  print(r,0);
  
  
 }
 private void print(Region r,int level){
  
  String preStr="";
  for(int i=0;i<level;i++){
   preStr+="--";
  }
  System.out.println(preStr+r.getName());
  for(Region child:r.getChilds()){
   print(child,level+1);
  }
 }
}


可以将区域对象看成2个对象。一个是父类,一个是子类。

对于父类来说,它与子类的关系是一对多;对于子类来说,它与父类的关系是多对一。由于父类和子类都存在对方的对象引用,因此它们之间的关系是一对多,多对一之间的双向关联。因此需要设置mappedby,以及测试代码中的父类与子类、子类与父类之间的关系都要设置好。

加载树状结构的时候需要用到递归。Region类 fetch=FetchType.EAGER,取父类的时候也会将子类一并取出。这样一般适用于树状结构不复杂的情况。当然也可以默认设置为lazy,当有需要的时候再取出。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我明白了。对于你的问题,我可以给出以下参考答案: 使用 Hibernate 实现树形结构的无限级分类可以采用两种方式:嵌套集合模型和闭包表模型。其中,嵌套集合模型是比较常见的一种方式,它可以通过递归查询的方式来实现对树形结构的操作。 具体实现步骤如下: 1. 创建实体类,包括节点的 id、名称、父节点 id、子节点集合等属性。 2. 使用 Hibernate 的注解方式进行映射,同时在实体类中定义递归查询的方法,实现对树形结构的操作。 3. 在业务逻辑层中,通过调用实体类中的递归查询方法,实现对树形结构的增删改查操作。 示例代码如下: ``` @Entity public class Category { @Id @GeneratedValue private Long id; private String name; @ManyToOne(fetch = FetchType.LAZY) private Category parent; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) private Set<Category> children = new HashSet<>(); // getters and setters public void addChild(Category child) { children.add(child); child.setParent(this); } public void removeChild(Category child) { children.remove(child); child.setParent(null); } public void setParent(Category parent) { this.parent = parent; } public Category getParent() { return parent; } public Set<Category> getChildren() { return children; } public boolean isRoot() { return parent == null; } public boolean isLeaf() { return children.isEmpty(); } public int getLevel() { if (isRoot()) { return 0; } return parent.getLevel() + 1; } public String getTreePath() { if (isRoot()) { return name; } return parent.getTreePath() + " > " + name; } public void addChilds(List<Category> childs) { for (Category child : childs) { addChild(child); } } } public interface CategoryDao extends JpaRepository<Category, Long> { List<Category> findByParentIsNull(); } ``` ``` @Service @Transactional public class CategoryServiceImpl implements CategoryService { @Autowired CategoryDao categoryDao; @Override public void add(Category category) { categoryDao.save(category); } @Override public void delete(Long id) { Category category = categoryDao.findOne(id); if (category != null) { if (category.isRoot()) { categoryDao.delete(category); } else { category.getParent().removeChild(category); } } } @Override public void update(Category category) { categoryDao.save(category); } @Override public Category get(Long id) { return categoryDao.findOne(id); } @Override public List<Category> getAll() { return categoryDao.findAll(); } @Override public List<Category> getRoots() { return categoryDao.findByParentIsNull(); } @Override public List<Category> getChildren(Long id) { Category category = categoryDao.findOne(id); if (category != null) { return new ArrayList<>(category.getChildren()); } return Collections.emptyList(); } @Override public List<Category> getTree() { List<Category> roots = getRoots(); for (Category root : roots) { fetchChildren(root); } return roots; } private void fetchChildren(Category parent) { List<Category> children = getChildren(parent.getId()); parent.addChilds(children); for (Category child : children) { fetchChildren(child); } } } ``` 以上就是使用 Hibernate 实现树形结构无限级分类的基本步骤和示例代码,希望能对你有所帮助。如果你还有其他问题可以继续问我哦。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值