zoukankan      html  css  js  c++  java
  • Hibernate中的一对一关系详解(1)

    A:先讲讲一对一的关系(欲知其他关系,请看下篇)

        a:主键关联的一对一关系

               一对一关系一般用主键关联,也就是说用主键值来维护两者的关系,一个表的主键存放另一个表的主键值。例如在员工与帐号中,我们取员工表的主键值作为帐号的主键值。

      我们一员工表和账号表为例:(员工表是主表,账号表是从表)

           对持久化的对象的封装和get,set方法已省略,值得注意的是:vo中必须相互写上对方的对象:如在employee中要定义private AccountVo account,在account中也要写上对应的employee,   我们只对映射文件与测试编写

       主表的mapping配置:使用了one-to-one

    <?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="com.ysq.vo">
             <class name="EmployeeVo" table="employee">
           <id name="oid">
              <generator class="sequence">
                <param name="sequence">dept_seq</param>  <!-- 使用的Oracle数据库,主键增长方式是sequence-->
              </generator>
           </id>
           <property name="deptid">
             <column name="deptid"/>
           </property>
           <property name="empName">
             <column name="empName" length="20"/>
           </property>
           <property name="sex">
             <column name="sex" length="2"/>
           </property>
           <property name="birthday">
             <column name="birthday" length="30"/>
           </property>
           <property name="school">
             <column name="school" length="20"/>
           </property>
           <property name="major">
             <column name="major" length="10"/>
           </property>
           <property name="degree">
             <column name="degree"/>
           </property>
           <property name="phone">
             <column name="phone" length="12"/>
           </property>
    
    <one-to-one name="account" class="AccountVo" cascade="all"></one-to-one>
         </class>   
    </hibernate-mapping>

    从表的mapping配置:

     <?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="com.ysq.vo">
          <class name="AccountVo" table="account">
            <id name="oid" type="java.lang.Integer">
                <column name="oid" />
                <generator class="foreign" ><!-- 采用外键方式生成主键值 -->
                     <param name="property">employee</param><!-- 表示取员工的主键值作为帐号的主键值,这里的employee要跟下面的<one-to-one>的name属性值一致 -->
                </generator>
            </id>
            <property name="username" type="java.lang.String">
                <column name="username" length="20" />
            </property>
            <property name="password" type="java.lang.String">
                <column name="password" length="20" />
            </property>
            <property name="email" type="java.lang.String">
                <column name="email" length="100" />
            </property>
            <property name="inactive" type="java.lang.String">
                <column name="inactive" length="1" />
            </property>
            <one-to-one name="employee" class= "EmployeeVo" constrained="true"></one-to-one>
       </class>  
    </hibernate-mapping>

     对应的测试类:

     //添加员工信息,同时也添加了对应的账号
    @Test
    public void addEmployee(){ EmployeeVo employee = new EmployeeVo(); AccountVo account = new AccountVo(); account.setUsername("zhangsan21"); account.setEmail("csw-java@163.com"); account.setPassword("123"); employee.setBirthday("2003-09-09"); employee.setEmpName("lizi21"); employee.setPhone("1232132"); Session session = SessionFactoryUtils.getSession(); Transaction tr = session.beginTransaction(); try { tr.begin(); /* //保存员工 session.save(employee); //保存帐号 account.setEmployee(employee); session.save(account);*/ //也可以进行双向关联,对主表进行save() account.setEmployee(employee); employee.setAccount(account); session.save(employee);//保存员工时,级联保存了账号 tr.commit(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ session.close(); } }
    @Test    //修改和删除
        public void updateEmp(){
            .......
              try {
                tr.begin();
                 //设置了双向关联,当对员工修改时,对account也进行了修改
                    employee.setAccount(account);
                    account.setEmployee(employee);
                   session.update(employee);
                   tr.commit();
            } catch (HibernateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                session.close();
            }
    
        }
        @Test
        public void deleteEmp(){
             ........
              Session session = SessionFactoryUtils.getSession();
              Transaction tr = session.beginTransaction();
              try {
                tr.begin();
                    //设置双向关联
                    employee.setAccount(account);
                    account.setEmployee(employee);
     
     
    
                   session.delete(employee);
                   tr.commit();
            } catch (HibernateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                session.close();
            }
        }
    @Test   //查询信息
        public void findEmployeeById(){
            Session session = SessionFactoryUtils.getSession();
            //一对一默认的延迟加载    get(class clazz,id)只针对通过id查询
            EmployeeVo employee = (EmployeeVo)session.get(EmployeeVo.class, 6);
            
            session.close();
            
            System.out.println(employee);
            System.out.println(employee.getAccount().getUsername());//注意:我这里的打印是引用了vo中的toString()方法,但只能在一个封装类中写toString()方法,同时写两个会报错的
        }
        
        @SuppressWarnings("unchecked")
        @Test
        public void findEmployee(){
            Session session = SessionFactoryUtils.getSession();
            //一对一默认的延迟加载[HQL]
            List<EmployeeVo> emps = session.createQuery("from EmployeeVo").list();
            
            session.close();
            for (EmployeeVo employee2 : emps) {
                 System.out.println(employee2);
                 System.out.println(employee2.getAccount().getUsername());
                 System.out.println();
            }
        }

       b:使用外键关联一对一的关系

         只需要包对应的mapping文件中修改一些就可以了

       如:employee中的:<one-to-one name="account" class="AccountVo" cascade="all"></one-to-one>需要修改如下:

          <!--因为现在员工对帐号是采用外键关联,所以在这里得加一个属性property-ref="employee"指定对方many-to-one 的name属性值-->
         <one-to-one name="account" class="AccountVo" property-ref="employee" cascade="all"></one-to-one>

          account中的:<one-to-one name="employee" class= "EmployeeVo" constrained="true"></one-to-one>  需要修改如下:

            <many-to-one name="employee" class="EmployeeVo" column="empid" unique="true"></many-to-one><!--在这边不再配置one-to-one了,而是用many-to-one,并且在many-to-one中加了unique="true"属性,表示唯一的多对一,也就成了一对一了,这里还得注意必须得指定外键column="empid" -->

    生活赋予我们一种巨大的和无限高贵的礼品,这就是青春:充满着力量,充满着期待志愿,充满着求知和斗争的志向,充满着希望信心和青春。
  • 相关阅读:
    cf B. Sonya and Exhibition
    cf B. Sonya and Exhibition
    1000C
    1000C
    AOE网打印所有的关键路径
    AOE网打印所有的关键路径
    拓扑排序判断有向图是否成环
    拓扑排序判断有向图是否成环
    迭代器
    Dictionary Aizu
  • 原文地址:https://www.cnblogs.com/ysq0908/p/4749805.html
Copyright © 2011-2022 走看看