hibernate 1-1(詳解)

來源:互聯網
上載者:User

標籤:des   c   style   class   blog   code   

領域模型


關係資料模型:

  • 按照外鍵映射:

  • 按照主鍵映射:


基於外鍵映射的 1-1
  • 對於基於外鍵的1-1關聯,其外鍵可以存放在任意一邊,在需要存放外鍵一端,增加many-to-one元素。為many-to-one元素增加unique=“true” 屬性來表示為1-1關聯

  • 另一端需要使用one-to-one元素,該元素使用 property-ref 屬性指定使用被關聯實體主鍵以外的欄位作為關聯欄位

-不使用 property-ref 屬性的 sql

-使用 property-ref 屬性的 sql


為什麼不兩邊都使用外鍵映射的 1-1


這樣就不是一對一關聯性映射了。


基於主鍵映射的 1-1

  • 基於主鍵的映射策略:指一端的主鍵產生器使用 foreign 策略,表明根據”對方”的主鍵來產生自己的主鍵,自己並不能獨立產生主鍵. <param> 子項目指定使用當前持久化類的哪個屬性作為 “對方”

  • 採用foreign主鍵產生器策略的一端增加 one-to-one 元素映射關聯屬性,其one-to-one屬性還應增加 constrained=“true” 屬性;另一端增加one-to-one元素映射關聯屬性。
  • constrained(約束):指定為當前持久化類對應的資料庫表的主鍵添加一個外鍵約束,引用被關聯的對象(“對方”)所對應的資料庫表主鍵



基於外鍵映射的 1-1

執行個體詳解:

Department.java

package com.atguigu.hibernate.one2one.foreign;public class Department {private Integer deptId;private String deptName;private Manager mgr;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;}public Manager getMgr() {return mgr;}public void setMgr(Manager mgr) {this.mgr = mgr;}}


Manager.java
package com.atguigu.hibernate.one2one.foreign;public class Manager {private Integer mgrId;private String mgrName;private Department dept;public Integer getMgrId() {return mgrId;}public void setMgrId(Integer mgrId) {this.mgrId = mgrId;}public String getMgrName() {return mgrName;}public void setMgrName(String mgrName) {this.mgrName = mgrName;}public Department getDept() {return dept;}public void setDept(Department dept) {this.dept = dept;}}


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>    <class name="com.atguigu.hibernate.one2one.foreign.Department" table="DEPARTMENTS">        <id name="deptId" type="java.lang.Integer">            <column name="DEPT_ID" />            <generator class="native" />        </id>                <property name="deptName" type="java.lang.String">            <column name="DEPT_NAME" />        </property><!-- 使用 many-to-one 的方式來映射 1-1 關聯關係 --><many-to-one name="mgr" class="com.atguigu.hibernate.one2one.foreign.Manager" column="MGR_ID" unique="true"></many-to-one>                    </class></hibernate-mapping>


Manager.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>    <class name="com.atguigu.hibernate.one2one.foreign.Manager" table="MANAGERS">                <id name="mgrId" type="java.lang.Integer">            <column name="MGR_ID" />            <generator class="native" />        </id>                <property name="mgrName" type="java.lang.String">            <column name="MGR_NAME" />        </property>                <!-- 映射 1-1 的關聯關係: 在對應的資料表中已經有外鍵了, 當前持久化類使用 one-to-one 進行映射 -->        <!--         沒有外鍵的一端需要使用one-to-one元素,該元素使用 property-ref 屬性指定使用被關聯實體主鍵以外的欄位作為關聯欄位         -->        <one-to-one name="dept"         class="com.atguigu.hibernate.one2one.foreign.Department"        property-ref="mgr"></one-to-one>            </class>    </hibernate-mapping>

package com.atguigu.hibernate.one2one.foreign;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.sql.Blob;import java.sql.Connection;import java.sql.SQLException;import java.util.Date;import org.hibernate.Hibernate;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.jdbc.Work;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class HibernateTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())                            .buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@Testpublic void testGet2(){//在查詢沒有外鍵的實體物件時, 使用的左外串連查詢, 一併查詢出其關聯的對象//並已經進行初始化. Manager mgr = (Manager) session.get(Manager.class, 1);System.out.println(mgr.getMgrName()); System.out.println(mgr.getDept().getDeptName()); }@Testpublic void testGet(){//1. 預設情況下對關聯屬性使用懶載入Department dept = (Department) session.get(Department.class, 1);System.out.println(dept.getDeptName()); //2. 所以會出現懶載入異常的問題. //session.close();//Manager mgr = dept.getMgr();//System.out.println(mgr.getClass()); //System.out.println(mgr.getMgrName()); //3. 查詢 Manager 對象的串連條件應該是 dept.manager_id = mgr.manager_id//而不應該是 dept.dept_id = mgr.manager_idManager mgr = dept.getMgr();System.out.println(mgr.getMgrName()); }@Testpublic void testSave(){Department department = new Department();department.setDeptName("DEPT-BB");Manager manager = new Manager();manager.setMgrName("MGR-BB");//設定關聯關係department.setMgr(manager);manager.setDept(department);//儲存操作//建議先儲存沒有外鍵列的那個對象. 這樣會減少 UPDATE 語句session.save(department);session.save(manager);}}


基於主鍵映射的 1-1

執行個體詳解:

實體類不變和上面相同

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="com.atguigu.hibernate.one2one.primary">    <class name="Department" table="DEPARTMENTS">        <id name="deptId" type="java.lang.Integer">            <column name="DEPT_ID" />            <!-- 使用外鍵的方式來產生當前的主鍵 -->            <generator class="foreign">            <!-- property 屬性指定使用當前持久化類的哪一個屬性的主鍵作為外鍵 -->            <param name="property">mgr</param>            </generator>        </id>                <property name="deptName" type="java.lang.String">            <column name="DEPT_NAME" />        </property><!--  採用 foreign 主鍵產生器策略的一端增加 one-to-one 元素映射關聯屬性,其 one-to-one 節點還應增加 constrained=true 屬性, 以使當前的主鍵上添加外鍵約束--><one-to-one name="mgr" class="Manager" constrained="true"></one-to-one>            </class></hibernate-mapping>


Manager.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>    <class name="com.atguigu.hibernate.one2one.primary.Manager" table="MANAGERS">                <id name="mgrId" type="java.lang.Integer">            <column name="MGR_ID" />            <generator class="native" />        </id>                <property name="mgrName" type="java.lang.String">            <column name="MGR_NAME" />        </property>                <one-to-one name="dept"         class="com.atguigu.hibernate.one2one.primary.Department"></one-to-one>            </class>    </hibernate-mapping>

package com.atguigu.hibernate.one2one.primary;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class HibernateTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())                            .buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@Testpublic void testGet2(){//在查詢沒有外鍵的實體物件時, 使用的左外串連查詢, 一併查詢出其關聯的對象//並已經進行初始化. Manager mgr = (Manager) session.get(Manager.class, 1);System.out.println(mgr.getMgrName()); System.out.println(mgr.getDept().getDeptName()); }@Testpublic void testGet(){//1. 預設情況下對關聯屬性使用懶載入Department dept = (Department) session.get(Department.class, 1);System.out.println(dept.getDeptName()); //2. 所以會出現懶載入異常的問題. Manager mgr = dept.getMgr();System.out.println(mgr.getMgrName()); }@Testpublic void testSave(){Department department = new Department();department.setDeptName("DEPT-DD");Manager manager = new Manager();manager.setMgrName("MGR-DD");//設定關聯關係manager.setDept(department);department.setMgr(manager);//儲存操作//先插入哪一個都不會有多餘的 UPDATEsession.save(department);session.save(manager);}}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.