Hibernate之關聯映射

一.關聯關係  

在軟件開發中,類與類中之間最廣泛的關係就是關聯關係,並且關聯是有方向的。

   以部門(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();

    }
複製代碼
複製代碼
相關文章
相關標籤/搜索