首页 > 代码库 > Hibernate一对一映射关联

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表:

技术分享

Hibernate一对一映射关联