一.關聯關係 在軟件開發中,類與類中之間最廣泛的關係就是關聯關係,並且關聯是有方向的。 以部門(Dept)和員工(Emp)爲例: 一個部門下能夠有多個員工,而一個員工只能屬於一個部門。因此從Emp到Dept的關聯是一對多的關聯關係,這就意味着每一個Emp對象只會引用一個Dept對象。 從Dept到Emp是一對多的關聯關係,這意味着Dept對象會引用一組Emp對象,所以在Dept類中應該定義一個集合類型的屬性,來引用所關聯的Emp對象。 若是僅有從Emp到Dept對象的關聯,或者僅有從Dept到Emp的關聯,就稱爲單向關聯。若是同時包含兩種關聯,就稱爲雙向關聯。 二.配置單向多對一關聯 在Emp類中定義一個Dept屬性,而在Dept類中無須定義用於存放Emp對象的集合屬性 01.Dept.java 複製代碼 複製代碼 package cn.zhang.entity; //部門實體類 public class Dept { private Integer deptid;//編號 private String deptname;//名稱 public Integer getDeptid() { return deptid; } public void setDeptid(Integer deptid) { this.deptid = deptid; } public String getDeptname() { return deptname; } public void setDeptname(String deptname) { this.deptname = deptname; } } 複製代碼 複製代碼 02.Emp.java 複製代碼 複製代碼 package cn.zhang.entity; //員工實體類 public class Emp { private Integer empno;//編號 private String empname;//姓名 private Dept dept;//所屬部門 public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEmpname() { return empname; } public void setEmpname(String empname) { this.empname = empname; } } 複製代碼 複製代碼 03.Dept.hbm.xml 複製代碼 複製代碼 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.zhang.entity"> <class name="Dept" table="DEPT"> <!--主鍵生成策略--> <id name="deptid" column="DEPTID"> <generator class="sequence"> <param name="sequence">SQ_Num</param> </generator> </id> <property name="deptname" type="string" column="deptname"/> </class> </hibernate-mapping> 複製代碼 複製代碼 04.Emp.hbm.xml 複製代碼 複製代碼 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.zhang.entity"> <class name="Emp" table="EMP"> <!-- 主鍵生成策略 --> <id name="empno" column="empno"> <generator class="sequence"> <param name="sequence">SQ_Num</param> </generator> </id> <property name="empname" type="string" column="empname"/> <!-- 多對一(員工對部門) --> <many-to-one name="dept" column="deptid" class="Dept"></many-to-one> </class> </hibernate-mapping> 複製代碼 複製代碼 05.hibernate.cfg.xml 配置文件 複製代碼 複製代碼 <?xml version='1.0' encoding='utf-8'?> <!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> <!-- Database connection settings --> <property name="connection.driver_class">oracle.jdbc.OracleDriver</property> <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property> <property name="connection.username">zhangzong</property> <property name="connection.password">123</property> <!-- SQL dialect (SQL 方言)--> <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> <!-- Echo all executed SQL to stdout 在控制檯打印後臺的SQL語句--> <property name="show_sql">true</property> <!-- 格式化顯示SQL --> <property name="format_sql">true</property> <!-- JDBC connection pool (use the built-in) --> <!-- <property name="connection.pool_size">1</property> --> <!-- Enable Hibernate's automatic session context management 指定當前session範圍和上下文--> <!-- <property name="current_session_context_class">thread</property> --> <!-- Disable the second-level cache --> <!-- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>--> <mapping resource="cn/zhang/entity/Dept.hbm.xml" /> <mapping resource="cn/zhang/entity/Emp.hbm.xml" /> </session-factory> </hibernate-configuration> 複製代碼 複製代碼 06.用於得到session對象和關閉session對象的工具類HibernateUtil 複製代碼 複製代碼 package cn.zhang.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { //初始化一個ThreadLocal對象,有get和set方法 private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>(); private static Configuration configuration; private final static SessionFactory sessionFactory; static{ configuration=new Configuration().configure(); sessionFactory=configuration.buildSessionFactory(); } //得到session對象 public static Session currentSession() { //sessionTL的get方法根據當前線程返回其對應的線程內部變量,即Session對象,多線程狀況下共享數據庫鏈接是不安全的。 //ThreadLocal保證了每一個線程都有本身的session對象 Session session=(Session)sessionTL.get(); if (session==null) { session=sessionFactory.openSession(); sessionTL.set(session); } return session; } //關閉session對象 public static void closeSession() { Session session=(Session)sessionTL.get(); sessionTL.set(null); session.close(); } } 複製代碼 複製代碼 07.測試類 複製代碼 複製代碼 @Test //多對一的單向關聯關係 public void TestOne(){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Dept dept=new Dept(); dept.setDeptname("開發部"); Emp emp=new Emp(); emp.setDept(dept); emp.setEmpname("張總"); session.save(dept); session.save(emp); tx.commit(); HibernateUtil.closeSession(); } 複製代碼 複製代碼 三.配置雙向的一對多關聯 在上一個例子中,已經創建Emp類到Dept類的多對一關聯,下面再增長Dept到Emp類的一對多關聯, 在Dept類中增長一個集合類型的emps屬性: 複製代碼 複製代碼 private Set<Emp> emps=new HashSet<Emp>();//員工集合 public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } 複製代碼 複製代碼 在Dept.hbm.xml中也會改變爲: 複製代碼 複製代碼 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.zhang.entity"> <class name="Dept" table="DEPT"> <id name="deptid" column="DEPTID"> <generator class="sequence"> <param name="sequence">SQ_Num</param> </generator> </id> <property name="deptname" type="string" column="deptname"/> <!-- 映射集合類型的emps屬性 --> <!-- name屬性:設定持久化類的屬性名。此處爲Dept類的emps --> <set name="emps" cascade="save-update" inverse="true"> <!-- column屬性設定與所關聯的持久化類對應的表的外鍵,此處爲EMP表的deptid字段 --> <key column="deptid"></key> <!-- class屬性設定與所關聯的持久化類,此處爲Emp類 --> <one-to-many class="Emp"></one-to-many> </set> </class> </hibernate-mapping> 複製代碼 複製代碼 補充:cascade屬性和inverse屬性(會新寫一篇博客) 01."cascade"屬性 "cascade"-直譯過來就是"級聯、串聯"的意思,書面化的解釋爲"該屬性會使咱們在操做主對象時,同時Hibernate幫助咱們完成從屬對象 相應的操做(好比,有Customer和Order這兩張表,關係爲一對多,只使用JDBC刪除Customer表中的一行記錄時,咱們還須要手動的將 Order表中與之關聯的記錄全都刪除,使用Hibernate的'cascade'屬性後,當咱們刪除一條Customer記錄時,Hibernate 會幫助咱們完成相應Order表記錄的刪除工做,方便了咱們的工做)"。 02."inverse"屬性 "inverse" -直譯過來就是"反轉,使顛倒"的意思,書面化的解釋爲"是否將關係維護的權力交給對方"(這個解釋真夠蛋疼的-_-!!,就是理解不了)。 Hibernate中的"inverse"屬性只有兩個值"true"和"false"。"true"表示將關係維護的權力交給對方,"false"表示不交出維護權力(默認值)。 推薦博客:http://www.cnblogs.com/o-andy-o/archive/2012/03/26/2418235.html 測試: 複製代碼 複製代碼 @Test public void TestThree(){ //得到session對象 Session session = HibernateUtil.currentSession(); //開啓事務 Transaction tx = session.beginTransaction(); //創建一個Dept對象和Emp對象 Dept dept=new Dept(); dept.setDeptname("就業部"); Emp emp=new Emp(); emp.setEmpname("坤坤"); //創建Dept和Emp對象的一對多雙向關聯關係 emp.setDept(dept); dept.getEmps().add(emp); //保存Dept對象 session.save(dept); //提交事務 tx.commit(); //關閉session鏈接 HibernateUtil.closeSession(); } 複製代碼 複製代碼