hibernate中的一對多與多對一的詳細配置解析
阿新 • • 發佈:2019-02-15
1.Employee
package cn.itcast.b_one2Many; public class Employee { private int empId; private String empName; private double salary; //員工與部門(多對一) private Dept dept; public int getEmpId() { return empId; } public void setEmpId(int empId) { this.empId = empId; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } }
2.Dept
package cn.itcast.b_one2Many; import java.util.HashSet; import java.util.Set; public class Dept { private int deptId; private String deptName; //部門對應的多個員工(一對多) private Set<Employee> emps=new HashSet<Employee>(); public int getDeptId() { return deptId; } public void setDeptId(int deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public Set<Employee> getEmps() { return emps; } public void setEmps(Set<Employee> emps) { this.emps = emps; } }
3.Employee.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- This mapping demonstrates content-based discrimination for the table-per-hierarchy mapping strategy, using a formula discriminator. --> <!--對映檔案:對映一個實體類物件,描述一個物件最終可以直接儲存物件資料到資料庫中 --> <!-- package:要對映的物件所在的包(可選,如果不指定,此檔案下所有的類都要指定全路徑) auto-import 預設為true,在寫HQL的時候自動匯入包名 如果指定為false,在寫HQL的時候必須要寫上類的全名--> <hibernate-mapping package="cn.itcast.b_one2Many"> <class name="Employee" table="t_employee"> <id name="empId"> <generator class="native"></generator> </id> <property name="empName" length="20"></property> <property name="salary" type="double"></property> <!--多對一的對映 Employee對映關鍵點: 1.對映的部門屬性:dept 2.對映的部門物件:對應的外來鍵欄位:dept_id 3.部門的型別--> <many-to-one name="dept" column="dept_Id" class="Dept"></many-to-one> </class> </hibernate-mapping>
4.Dept.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
This mapping demonstrates content-based discrimination for the
table-per-hierarchy mapping strategy, using a formula
discriminator.
-->
<!--對映檔案:對映一個實體類物件,描述一個物件最終可以直接儲存物件資料到資料庫中 -->
<!-- package:要對映的物件所在的包(可選,如果不指定,此檔案下所有的類都要指定全路徑)
auto-import 預設為true,在寫HQL的時候自動匯入包名
如果指定為false,在寫HQL的時候必須要寫上類的全名-->
<hibernate-mapping package="cn.itcast.b_one2Many">
<class name="Dept" table="t_dept">
<id name="deptId">
<generator class="native"></generator>
</id>
<property name="deptName" length="20"></property>
<!-- 一對多關聯對映配置(通過部門管理到員工)
Dept對映關鍵點:
1.指定對映的集合屬性:emps
2.集合屬性對應的集合表:t_employee
3.集合表的外來鍵欄位:t_employee.dept_id
4.集合元素的型別-->
<set name="emps" table="t_employee">
<key column="dept_Id"></key>
<one-to-many class="Employee"></one-to-many>
</set>
</class>
</hibernate-mapping>
5.測試類
package cn.itcast.b_one2Many;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;
public class App_save {
private static SessionFactory sf;
static{
sf=new Configuration()
.configure()
.addClass(Dept.class)
.addClass(Employee.class) //測試的時候使用
.buildSessionFactory();
}
//儲存,通過部門方儲存資料(一對多操作儲存資料)
@Test
public void Save() {
Session session=sf.openSession();
session.beginTransaction();
//部門物件
Dept dept=new Dept();
dept.setDeptName("應用開發部");
//員工物件
Employee emp_zs=new Employee();
emp_zs.setEmpName("張三");
Employee emp_ls=new Employee();
emp_ls.setEmpName("李四");
//處理關係
dept.getEmps().add(emp_zs);
dept.getEmps().add(emp_ls);
//儲存資料
session.save(emp_zs);
session.save(emp_ls);
session.save(dept);
session.getTransaction().commit();
session.close();
/* Hibernate: insert into t_employee (empName, salary, dept_Id) values (?, ?, ?)
Hibernate: insert into t_employee (empName, salary, dept_Id) values (?, ?, ?)
Hibernate: insert into t_dept (deptName) values (?)
Hibernate: update t_employee set dept_Id=? where empId=? //維護員工部門引用的id
Hibernate: update t_employee set dept_Id=? where empId=?
*/
}
//推薦:用多的一方來儲存資料,減少資料庫維護的次數
//儲存資料,通過員工方儲存資料(多對一操作資料)
@Test
public void Save2() {
Session session=sf.openSession();
session.beginTransaction();
//部門物件
Dept dept=new Dept();
dept.setDeptName("人事部");
//員工物件
Employee emp_zs=new Employee();
emp_zs.setEmpName("張三");
Employee emp_ls=new Employee();
emp_ls.setEmpName("李四");
//處理關係
emp_zs.setDept(dept);
emp_ls.setDept(dept);
//儲存資料
//先儲存一的一方,再儲存多的一方,這樣關係會自動維護(配置對映一定要正確)
session.save(dept);//儲存部門下的所有員工
session.save(emp_zs);
session.save(emp_ls);
session.getTransaction().commit();
session.close();
/* Hibernate: insert into t_dept (deptName) values (?)
Hibernate: insert into t_employee (empName, salary, dept_Id) values (?, ?, ?)
Hibernate: insert into t_employee (empName, salary, dept_Id) values (?, ?, ?)
少生成2條update的sql
*/
}
}
6.hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一個session-factory節點代表一個數據庫 -->
<session-factory>
<!-- 1.資料庫連線配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hib-demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!--資料庫方法配置,hibernate在執行的時候,會根據不同的方言生成符合當前資料庫語法的sql -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2.其他相關配置 -->
<!--2.1顯示hibernate在執行的時候執行的sql語句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2格式化sql
<property name="hibernate.format_sql">true</property>-->
<!-- 2.3自動建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 3.載入所有對映
<mapping resource="cn/itcast/a_hello/Employee.hbm.xml"/>-->
</session-factory>
</hibernate-configuration>