標籤: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);}}