Hibernate(六)實現一對多、多對一對映關聯關係
阿新 • • 發佈:2019-02-20
一對多、多對一這種關係在現實生活中很多,例如部門與員工的關係,學校裡班級與學生的關係...
那麼在具體的系統實現中如果i實現這種關聯關係呢?這裡以部門和員工的關係為例。
部門實體類
員工實體類package test.hibernate.hbmOneToMany; import java.util.HashSet; import java.util.Set; public class Department { private Integer id; private String name; private Set<Employee> employees = new HashSet<Employee>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Employee> getEmployees() { return employees; } public void setEmployees(Set<Employee> employees) { this.employees = employees; } @Override public String toString() { // TODO Auto-generated method stub return "[employee:id=" + id + ",name=" + name + "]"; } }
部門對映Department.hbm.xmlpackage test.hibernate.hbmOneToMany; public class Employee { private Integer id; private String name; private Department department=new Department(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="test.hibernate.hbmOneToMany"> <class name="Department" table="department"> <id name="id" type="integer" column="id"> <generator class="native" /> </id> <property name="name" /> <!-- inverse屬性:預設為false,表示本方維護關聯關係; 如果設為true,表示本方不維護關聯關係 只是影響是否能設定外來鍵列的值(設成有效值或是null值),對獲取資訊沒有影響 --> <set name="employees" inverse="false"> <key column="departmentId"></key> <one-to-many class="Employee" /> </set> </class> </hibernate-mapping>
inverse=false
inverse=true
員工對映檔案Employee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.hibernate.hbmOneToMany">
<class name="Employee" table="employee">
<id name="id" type="integer" column="id">
<generator class="native" />
</id>
<property name="name"/>
<many-to-one name="department" class="Department" column="departmentId"></many-to-one>
</class>
</hibernate-mapping>
測試類App
package test.hibernate.hbmOneToMany;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App {
private static SessionFactory sessionFactory = new Configuration()//
.configure()//
.addClass(Department.class)// 新增Hibernate實體類(載入對應的對映檔案)
.addClass(Employee.class)//
.buildSessionFactory();
@Test
public void testSave() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 構建物件
Department department = new Department();
department.setName("開發部");
Employee employee = new Employee();
employee.setName("張三");
Employee employee2 = new Employee();
employee2.setName("李瑟");
// 關聯起來
employee.setDepartment(department);
employee2.setDepartment(department);
department.getEmployees().add(employee);
department.getEmployees().add(employee2);
// 儲存
session.save(department);
session.save(employee);
session.save(employee2);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 獲取到部門關聯的員工
@Test
public void testGet() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// 獲取資料
Department department = (Department) session.get(Department.class, 1);
System.out.println(department.getId());
System.out.println(department.getName());
System.out.println(department.getEmployees());
session.getTransaction().commit();
session.close();
}
// 解除關聯關係
@Test
public void testRemoveRelation() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 從員工解除與部門的關聯,也就是員工不再屬於任何部門
// Employee employee=(Employee) session.get(Employee.class, 8);
// employee.setDepartment(null);
// 從部門解除員工關係
Department department = (Department) session.get(Department.class, 1);
// 要使這句有效,需將對映檔案裡的inverse設為false,即部門恢復維護關係
department.getEmployees().clear();
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 刪除部門及對員工的影響
@Test
public void testDelete() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 刪除員工,對部門沒有影響
// Employee employee=(Employee) session.get(Employee.class, 9);
// session.delete(employee);
/*
* 如果沒有關聯的員工,能刪除
* 如果有關聯的員工且inverse=true,由於不能維護關聯關係,會直接執行刪除且報異常
* 如果有關聯的員工且inverse=false,由於可以維護關聯關係,會將員工的外來鍵設為null,再刪除自己
*/
Department department = (Department) session.get(Department.class, 8);
session.delete(department);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
}
級聯是指操作主物件時,對關聯的物件也做相同的操作。 預設為none,代表不級聯。可設為:delete、save-update、all、none... 一般在多對一或一對多的時候使用級聯,多對多的時候不使用級聯。
修改後的測試程式碼:
Department.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.hibernate.hbmOneToMany">
<class name="Department" table="department">
<id name="id" type="integer" column="id">
<generator class="native" />
</id>
<property name="name" />
<!-- inverse屬性:預設為false,表示本方維護關聯關係;
如果設為true,表示本方不維護關聯關係
只是影響是否能設定外來鍵列的值(設成有效值或是null值),對獲取資訊沒有影響
cascade級聯屬性:
即刪掉一個Department,會同時刪掉department下的所有employees
-->
<set name="employees" inverse="false" cascade="save-update">
<key column="departmentId"></key>
<one-to-many class="Employee" />
</set>
</class>
</hibernate-mapping>
package test.hibernate.hbmOneToMany;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App {
private static SessionFactory sessionFactory = new Configuration()//
.configure()//
.addClass(Department.class)// 新增Hibernate實體類(載入對應的對映檔案)
.addClass(Employee.class)//
.buildSessionFactory();
@Test
public void testSave() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 構建物件
Department department = new Department();
department.setName("開發部");
Employee employee = new Employee();
employee.setName("張三");
Employee employee2 = new Employee();
employee2.setName("李瑟");
// 關聯起來
employee.setDepartment(department);
employee2.setDepartment(department);
department.getEmployees().add(employee);
department.getEmployees().add(employee2);
// 儲存
// session.save(department);
// session.save(employee);
// session.save(employee2);
//級聯儲存,將cascade設為save-update
session.save(department);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 獲取到部門關聯的員工
@Test
public void testGet() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// 獲取資料
Department department = (Department) session.get(Department.class, 1);
System.out.println(department.getId());
System.out.println(department.getName());
System.out.println(department.getEmployees());
session.getTransaction().commit();
session.close();
}
// 解除關聯關係
@Test
public void testRemoveRelation() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 從員工解除與部門的關聯,也就是員工不再屬於任何部門
// Employee employee=(Employee) session.get(Employee.class, 8);
// employee.setDepartment(null);
// 從部門解除員工關係
Department department = (Department) session.get(Department.class, 1);
// 要使這句有效,需將對映檔案裡的inverse設為false,即部門恢復維護關係
department.getEmployees().clear();
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 刪除部門及對員工的影響
@Test
public void testDelete() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 刪除員工,對部門沒有影響
// Employee employee=(Employee) session.get(Employee.class, 9);
// session.delete(employee);
/*
* 如果沒有關聯的員工,能刪除
* 如果有關聯的員工且inverse=true,由於不能維護關聯關係,會直接執行刪除且報異常
* 如果有關聯的員工且inverse=false,由於可以維護關聯關係,會將員工的外來鍵設為null,再刪除自己
*/
Department department = (Department) session.get(Department.class, 10);
session.delete(department);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
}