Hibernate中的一對一關聯


Hibernate提供了兩種一對一映射關聯關系的方式:

1)按照外鍵映射

2)按照主鍵映射

下面以員工賬號表和員工檔案表(員工賬號和檔案表之間是一對一的關系)為例,介紹這兩種映射關系,並使用這兩種 映射方式分別完成以下持久化操作

(1)保存員工檔案的同時分配給員工一個賬號

(2)加載員工檔案的同時加載賬號信息

一:按照外鍵映射

HibernateUtil工具類(用於獲取session和關閉session)

package cn.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();
    }

}

創建實體類Users1和Resume1

Users1:

package cn.entity_fk;



/**
 * 員工類
 * 
 * 
 * 
 */
public class Users1 {
    private Integer userid;//用戶編號
    private String username;//名稱
    private String userpass;//密碼
    private Resume1 resume1;//檔案對象
    
    public Users1() {
    }
    
    public Users1(String username, String userpass) {
    
        this.username = username;
        this.userpass = userpass;
        
    }

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserpass() {
        return userpass;
    }

    public void setUserpass(String userpass) {
        this.userpass = userpass;
    }

    public Resume1 getResume1() {
        return resume1;
    }

    public void setResume1(Resume1 resume1) {
        this.resume1 = resume1;
    }

}

Resume1:

package cn.entity_fk;



/**
 * 檔案類
 * 
 * @time
 * @author Happy
 * 
 */
public class Resume1 {
    private Integer resid; //檔案編號
    private String resname; //檔案名稱
    private String rescardno;//編號
    private Users1 users1;  //隸屬的用戶(員工)
    
    public Resume1() {
    }
    
    public Resume1( String resname, String rescardno) {
        
        this.resname = resname;
        this.rescardno = rescardno;
        
    }

    public Integer getResid() {
        return resid;
    }

    public void setResid(Integer resid) {
        this.resid = resid;
    }

    public String getResname() {
        return resname;
    }

    public void setResname(String resname) {
        this.resname = resname;
    }

    public String getRescardno() {
        return rescardno;
    }

    public void setRescardno(String rescardno) {
        this.rescardno = rescardno;
    }

    public Users1 getUsers1() {
        return users1;
    }

    public void setUsers1(Users1 users1) {
        this.users1 = users1;
    }

}

創建配置文件Users1.hbm.xml和Resume1.hbm.xml

Users1.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.entity_fk">
   <class name="Users1" table="USERS1">
   <!-- 主鍵的配置 -->
     <id name="userid" column="USERID" >
        <!-- 由后台數據庫生成主鍵:默認生成的序列名稱為:Hibernate_Sequence -->
        <generator class="native"></generator>
     </id>
     <property name="username" column="USERNAME" type="string"></property>
     <property name="userpass" column="USERPASS" type="string"></property>
     <!-- 配置一對對,外鍵方式的關聯
        property-ref:通過Resume1 的users1的屬性,建立了從users1到Resume1的對象的關聯!
      -->
     <one-to-one name="resume1" class="Resume1" property-ref="users1"></one-to-one>
   </class>
</hibernate-mapping>

 

Resume1.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.entity_fk">
   <class name="Resume1" table="RESUME1">
     <id name="resid" column="RESID" >
        <generator class="native"></generator>
     </id>
     <property name="resname" column="RESNAME" type="string"></property>
     <property name="rescardno" column="RESCARDNO" type="string"></property>
     <many-to-one name="users1" class="Users1" cascade="all" column="RESUSERID" unique="true"></many-to-one>
   </class>
</hibernate-mapping>

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">***</property>
        <property name="connection.password">***</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/Resume1.hbm.xml" />
        <mapping resource="cn/zhang/entity/Users1.hbm.xml" />
        
    </session-factory>

</hibernate-configuration>

測試類:

/**
     * 一對一關聯測試
     */
public class Tests {
    Session session;
    Transaction tx;
    

    @Before
    public void initDate(){
        session = HibernateUtil.getSession();
         tx= session.beginTransaction();
    }
    
    
    @After
     public void afterTest(){
         tx.commit();
         HibernateUtil.closeSession();
     }
    
    
    /**
     * 一對一關聯測試
     */


    @Test
    public void getTest(){
        Users1 u1=new Users1();
        u1.setUsername("火");
        u1.setUserpass("2");
        
        Resume1 r1=new Resume1();
        r1.setResname("培訓2");
        r1.setRescardno("002");
        
        u1.setResume1(r1);
        r1.setUsers1(u1);
        session.save(r1);
        System.out.println("ok-------");
    }
    
    /**
     * 查詢
     */

    @Test
    public void selectTest(){
         Users1 u1=(Users1)session.load(Users1.class, 2);
          System.out.println(u1.getResume1().getResname());
        
    }

結果:

數據庫:

數據庫:

Users1表:

Resume1表:

二:按照主鍵映射

Users2表的userid字段是主鍵,同時作為外鍵參照Resume2表的主鍵,即Users2表與Resume2表共享主鍵(Users2中的主鍵值是根據Resume2生成的主鍵值取值的)

Resume2:

package cn.entity_pk;



/**
 * 檔案類
 * 
 * @time
 * @author Happy
 * 
 */
public class Resume2 {
    private Integer resid;
    private String resname;
    private String rescardno;
    private Users2 users2;
    
    public Users2 getUsers2() {
        return users2;
    }

    public void setUsers2(Users2 users2) {
        this.users2 = users2;
    }

    public Resume2() {
    }
    
    public Resume2( String resname, String rescardno) {
        
        this.resname = resname;
        this.rescardno = rescardno;
        
    }

    public Integer getResid() {
        return resid;
    }

    public void setResid(Integer resid) {
        this.resid = resid;
    }

    public String getResname() {
        return resname;
    }

    public void setResname(String resname) {
        this.resname = resname;
    }

    public String getRescardno() {
        return rescardno;
    }

    public void setRescardno(String rescardno) {
        this.rescardno = rescardno;
    }

    

}

 

 Users2:

package cn.entity_pk;



/**
 * 員工類
 * 
 * @author Happy
 * 
 */
public class Users2 {
    private Integer userid;
    private String username;
    private String userpass;
    private Resume2 resume2;
    
    public Resume2 getResume2() {
        return resume2;
    }

    public void setResume2(Resume2 resume2) {
        this.resume2 = resume2;
    }

    public Users2() {
    }
    
    public Users2(String username, String userpass) {
    
        this.username = username;
        this.userpass = userpass;
        
    }

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserpass() {
        return userpass;
    }

    public void setUserpass(String userpass) {
        this.userpass = userpass;
    }

    

}

Resume2.hbm.xml映射文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.entity_pk">
 <class name="Resume2" table="RESUME2">
  <id column="RESID" name="resid">
     <generator class="sequence">
       <param name="sequence">SEQ_NUM</param>
     </generator>
  </id>
  <property column="RESNAME" name="resname" type="string"/>
  <property column="RESCARDNO" name="rescardno" type="string"/>
  <!--主的一方  -->
  <one-to-one  name="users2" cascade="all" class="Users2" />
 </class>
</hibernate-mapping>

Users2.hbm.xml映射文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.entity_pk">
   <class name="Users2" table="USERS2">
     <id name="userid" column="USERID" >
         <generator class="foreign">
            <param name="property">resume2</param>
         </generator>
     </id>
     <property name="username" column="USERNAME" type="string"></property>
     <property name="userpass" column="USERPASS" type="string"></property>
     <!-- constrained:用來約束 在底層USERS2數據表中,植入外鍵-->
     <one-to-one name="resume2" class="Resume2" constrained="true"></one-to-one>
   </class>
</hibernate-mapping>

測試類:

public class Test_pk {
    Session session;
    Transaction tx;
    

    @Before
    public void initDate(){
        session = HibernateUtil.getSession();
         tx= session.beginTransaction();
    }
    
    
    @After
     public void afterTest(){
         tx.commit();
         HibernateUtil.closeSession();
     }
    
    
    /**
     * 一對一關聯測試:按照主鍵映射
     */
    @Test
    public void getTest(){
        Users2 u1=new Users2();
        u1.setUsername("呵呵");
        u1.setUserpass("1");
        
        Resume2 r1=new Resume2();
        r1.setResname("哈哈");
        r1.setRescardno("001");
        
        u1.setResume2(r1);
        r1.setUsers2(u1);
        session.save(r1);
        System.out.println("ok-------");
        
    }
    
    /**
     * 查詢
     */
    @Test
    public void selectTest(){
        Users2 u1=(Users2)session.load(Users2.class, 2);
        System.out.println(u1.getResume2().getResname());
        
    }

結果:

數據庫:

Resume2表:

Users2表:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM