在一方记住了多方,在多方也记住了一方 ,双向管理,我们这样设计就是双向的关联,在实际开发里面,这种双向的关联是不推荐使用的!而且一对多这种关系最好就不要设计,即不要在一方记住多方,如果你设计了,在找出一方的数据时就要取出多方的数据,如果对方的数据超多的话,很容易导致内存溢出.
虽然在实际开发里面,一对多/多对一双向关联不推荐使用,但是我们还是应该有所了解的。
Department.java
package hibernate.model.o2mDouble;
import java.util.HashSet;
import java.util.Set;
//部门(one)
public class Department {
private Integer id;
private String name;
private Set<Employee> employeeSet = new HashSet<Employee>();
}
Employee.java
package hibernate.model.o2mDouble;
//员工(many)
public class Employee {
private Integer id;
private String name;
private Department department;
}
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="hibernate.model.o2mDouble">
<class name="Department" table="dept">
<id name="id" column="did">
<!-- 设置为native之后,主键会按照本来的顺序进行增长(比如之前11但是删除了,现在就从12开始) -->
<generator class="native"></generator>
</id>
<property name="name" column="dname"></property>
<!-- employees属性,Set集合,表达的是本类与Employee的一对多的关系
class属性:关联的实体类型
key子元素:对方表中的外键列(多方的哪个表)
inverse属性:
默认为false,表示本方维护关联关系。
如果为true,表示本方不维护关联关系。
cascade="all" -->
<set name="employeeSet" lazy="false" inverse="true">
<key column="deptid"></key>
<one-to-many class="Employee" />
</set>
</class>
</hibernate-mapping>
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="hibernate.model.o2mDouble">
<class name="Employee" table="emp">
<id name="id" column="eid">
<!-- 设置成increment之后,会从数据库中查找主键id最大的值,然后+1进行存储 -->
<generator class="increment"></generator>
</id>
<property name="name" column="ename"></property>
<many-to-one name="department" class="Department" column="deptid"></many-to-one>
</class>
</hibernate-mapping>
在hibernate.cfg.xml注册加载
<mapping resource="hibernate/model/o2mDouble/Department.hbm.xml" />
<mapping resource="hibernate/model/o2mDouble/Employee.hbm.xml" />
O2mDouble测试类
package hibernate.model.o2mDouble;
import java.util.Set;
import org.hibernate.Session;
import org.junit.Test;
import xh.util.HibernateUtil;
//单向一对多
public class O2mDouble {
private Session session;
public O2mDouble() {
session = HibernateUtil.getInstance().getSession();
}
// 保存
@Test
public void o2mTest() {
try {
session.beginTransaction();
Department dept = new Department();
dept.setName("财务部");
Employee emp1 = new Employee();
emp1.setName("员工1");
emp1.setDepartment(dept);
Employee emp2 = new Employee();
emp2.setName("员工2");
emp2.setDepartment(dept);
dept.getEmployeeSet().add(emp1);
dept.getEmployeeSet().add(emp2);
session.save(dept);
session.save(emp1);
session.save(emp2);
session.beginTransaction().commit();
session.close();
} catch (Exception e) {
session.beginTransaction().rollback();
}
}
@Test
public void testQuery() {
//多方获取
Employee employee = (Employee) session.get(Employee.class, 1);
String e_name = employee.getName();
String d_name = employee.getDepartment().getName();
System.out.println("员工:"+e_name+",部门:"+d_name);
System.out.println("--------------------");
Department dept = (Department) session.get(Department.class, 1);
String name = dept.getName();
Set<Employee> set = dept.getEmployeeSet();
for (Employee employee2 : set) {
System.out.println("员工:"+employee2.getName()+",部门:"+name);
}
}
}
结论:
- 在映射一对多的双向关联关系时,应该在one方把inverse属性设为true,这可以提高性能
- 当删除双向关联的关系时,也应该修改关联两端的对象的相应属性:
department.getEmployees().clear(); // 清空
employee.setDepartment(null);
3.只有集合标记(set/map/list/array/bag)才有inverse属性。
4.维护关联关系是指设置外键列的值(设置有效值或是null值).
5. 因为是双向操作,所以保存任何一方都能成功,但是推荐保存”一”的一方,并在”一”的一方交出控制权,这样会提高效率
6.
结论是:无论是从哪一方获取数据,都能获取到关联对方的数据。