下面是“java Hibernate 一对多自身关联问题”的完整攻略。
一对多自身关联问题解析
一对多自身关联指的是一个实体类与自身的关联,且一个实体类可以关联多个相同类型的实体类对象。
这种关联关系很常见,例如“部门-员工”,一个部门下可以有多个员工,而一个员工也归属于某个部门。
Hibernate中实现一对多自身关联通常有两种方式:双向关联和单向关联。
双向关联
双向关联指同时在两个实体类之间建立关联关系。
例如我们有一个实体类Employee
,表示员工信息,一个员工可以有多个下属员工,实现代码如下:
public class Employee {
private Long id;
private String name;
// 下属员工
private List<Employee> subordinates = new ArrayList<>();
// 上级员工
private Employee superior;
// 省略getter/setter方法
}
- 在
Employee
类中,我们定义了一个subordinates
属性,表示当前员工的下属员工列表。 - 我们还定义了一个
superior
属性,表示当前员工的直接上级。
这里的关联关系是双向的,即一个员工有多个下属,同时一个下属也有一个直接上级,这个直接上级也是一个员工。
在Employee
类中,我们需要使用Hibernate的注解来实现关联关系的映射,例如:
@Entity
@Table(name = "employee")
public class Employee {
// ...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
// 下属员工
@OneToMany(targetEntity = Employee.class, mappedBy = "superior", cascade = CascadeType.ALL)
private List<Employee> subordinates = new ArrayList<>();
// 上级员工
@ManyToOne(targetEntity = Employee.class)
@JoinColumn(name = "superior_id")
private Employee superior;
// 省略getter/setter方法
}
在这里,我们使用了@OneToMany
注解表示当前员工有多个下属,同时使用了mappedBy
属性来指定关联关系的维护方是Employee
类中的superior
属性,即由下属员工维护关联关系。
同时,我们还使用了@ManyToOne
注解表示当前员工有一个上级员工,使用@JoinColumn
注解指定了关联的外键字段是superior_id
。
这样,我们就完成了实体类之间的关联。
在使用时,我们可以通过给某个员工添加下属来建立关联关系,例如:
Employee ceo = new Employee();
ceo.setName("John");
Employee cto = new Employee();
cto.setName("Mary");
cto.setSuperior(ceo);
Employee developer1 = new Employee();
developer1.setName("Tom");
developer1.setSuperior(cto);
Employee developer2 = new Employee();
developer2.setName("Jack");
developer2.setSuperior(cto);
ceo.getSubordinates().add(cto);
cto.getSubordinates().add(developer1);
cto.getSubordinates().add(developer2);
通过以上代码,我们建立了3个员工的关联关系。cto
和developer1
以及developer2
是cto
的下属,cto
是ceo
的下属。
通过Hibernate的自动级联功能,我们可以使用save
方法将这些员工对象保存到数据库中,例如:
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save(ceo);
session.save(cto);
session.save(developer1);
session.save(developer2);
session.getTransaction().commit();
在这里,我们使用Hibernate的getCurrentSession
方法获得当前线程的Session,然后开启一个事务并保存ceo
、cto
、developer1
、developer2
对象,调用commit
方法提交事务,Hibernate就会将对象保存到数据库中。
单向关联
单向关联指只在一个实体类中建立关联关系。
例如我们有一个实体类Category
,表示商品分类信息,每个分类下可以有多个商品,实现代码如下:
public class Category {
private Long id;
private String name;
// 商品列表
private List<Product> products = new ArrayList<>();
// 省略getter/setter方法
}
- 在
Category
类中,我们定义了一个products
属性,表示当前分类下的商品列表。
这里的关联关系是单向的,即一个分类有多个商品,但是一个商品没有一个明确的所属分类,只有分类保存了关联关系。
在Category
类中,我们同样需要使用Hibernate的注解来实现关联关系的映射,例如:
@Entity
@Table(name = "category")
public class Category {
// ...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
// 商品列表
@OneToMany(targetEntity = Product.class, cascade = CascadeType.ALL)
@JoinColumn(name = "category_id")
private List<Product> products = new ArrayList<>();
// 省略getter/setter方法
}
在这里,我们使用了@OneToMany
注解表示当前分类有多个商品,使用@JoinColumn
注解指定了关联的外键字段是category_id
,由于是单向关联,所以没有使用mappedBy
属性。
在使用时,我们同样是先创建一个Category
对象,然后将多个Product
对象添加到该分类的商品列表中,例如:
Category category = new Category();
category.setName("Fruits");
Product product1 = new Product();
product1.setName("Apple");
product1.setCategory(category);
Product product2 = new Product();
product2.setName("Banana");
product2.setCategory(category);
category.getProducts().add(product1);
category.getProducts().add(product2);
通过以上代码,我们建立了一个分类和两个商品之间的关联关系。两个商品属于同一个分类。
同样,通过Hibernate的自动级联功能,我们可以将这些对象保存到数据库中,例如:
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
session.save(category);
session.save(product1);
session.save(product2);
session.getTransaction().commit();
在这里,我们同样是使用Hibernate的getCurrentSession
方法获取当前线程的Session,然后开启一个事务并将category
、product1
和product2
对象保存到数据库中,最后提交事务。
总结
Java Hibernate可以很方便地实现一对多自身关联问题,常用的实现方式是双向关联和单向关联,开发者可以根据具体的场景选择适合自己的方式,并通过Hibernate的自动级联完成关联对象的持久化。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java Hibernate 一对多自身关联问题 - Python技术站