zoukankan      html  css  js  c++  java
  • 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表:

  • 相关阅读:
    新 DAO 访问接口
    TCP/IP协议中的参数说明
    最近在制作一套ASP.NET控件,已初见雏形
    Creating a Dynamic UI with Knockout.js
    数据库性能优化数据库等待队列
    webpy框架
    .Net Web Http状态异常
    一步一步搭架子(完结篇)
    使用yshow分析前端页面性能
    代码混淆、加密
  • 原文地址:https://www.cnblogs.com/jingpeipei/p/5842869.html
Copyright © 2011-2022 走看看