Hibernate中一对一

来源:互联网 发布:java课程内容 编辑:程序博客网 时间:2024/05/28 16:25

           1) 数据库表的设计

                1> 基于外键方式

                    即在其中一方增加一个外键,指向另一张表的主键,并添加unique约束(否则不加就是一对多了)

                   

                2> 基于主键方式

                    即另一张表的主键就是外键,指向另一张表的主键

                    

                3> 比较

                     基于外键方式的记录可以单独存在,基于主键的方式由于引用的是其他表的主键,所以如果其他表中相关记录不存在,本表中记录也不会存在。

             2) 基于外键的方式

                1> pojo设计

         public class IdCard {           private int id;           private String num;           private Person person;        }
        public class Person {           private int id;           private String name;           private IdCard idCard;        }
                2>  映射文件

 <class name="cn.com.cpf.pojo.IdCard"   table="t_idCard" >  <id name="id" column="id">        <generator class="native"/>  </id>  <property name="num"/>  <many-to-one name="person" class="cn.com.cpf.pojo.Person" unique="true" column="personId" /> </class>
         因为在一对一中和多对一只不过就是在外键多了一个唯一性约束,所以标签用的还是多对一的
 <class name="cn.com.cpf.pojo.Person"   table="t_person" >  <id name="id" column="id">       <generator class="native"/>  </id>  <property name="name"/>  <one-to-one name="idCard" class="cn.com.cpf.pojo.IdCard" property-ref="person" ></one-to-one> </class>
    在本方使用property-ref属性来指定关联的外键对应的pojo属性
               3> 生成的数据库表结构

           维护关系的表:

           

          

        

        另一张表:

        
           4>保存

        factory = new Configuration().configure().buildSessionFactory();        session = factory.openSession();        Transaction tx = session.beginTransaction();        Person person = new Person();        person.setName("xny");        IdCard idCard = new IdCard();        idCard.setNum("22X");        idCard.setPerson(person);        person.setIdCard(idCard);        session.save(person);        session.save(idCard);
         结果:

Hibernate: insert into t_person (name) values (?)Hibernate: insert into t_idCard (num, personId) values (?, ?)
          5> 查询

        factory = new Configuration().configure().buildSessionFactory();        session = factory.openSession();         Person person = (Person) session.get(Person.class, 1);        System.out.println(person.getName()+" "+person.getIdCard());        IdCard idCard = (IdCard) session.get(IdCard.class, 1);        System.out.println(idCard.getNum()+" "+idCard.getPerson());
            结果为:

Hibernate: select person0_.id as id1_6_0_, person0_.name as name2_6_0_, idcard1_.id as id1_5_1_, idcard1_.num as num2_5_1_, idcard1_.personId as personId3_5_1_ from t_person person0_ left outer join t_idCard idcard1_ on person0_.id=idcard1_.personId where person0_.id=?zq cn.com.cpf.pojo.IdCard@2e9dca2611X cn.com.cpf.pojo.Person@32b3a5a0
          6> 解除关系

         从有外键的一方解除:          

        factory = new Configuration().configure().buildSessionFactory();        session = factory.openSession();        Transaction tx = session.beginTransaction();        IdCard idCard = (IdCard) session.get(IdCard.class, 1);        idCard.setPerson(null);        tx.commit();
          结果为:

Hibernate: select idcard0_.id as id1_5_0_, idcard0_.num as num2_5_0_, idcard0_.personId as personId3_5_0_ from t_idCard idcard0_ where idcard0_.id=?Hibernate: update t_idCard set num=?, personId=? where id=?
        从无外键的一方解除

        factory = new Configuration().configure().buildSessionFactory();        session = factory.openSession();        Transaction tx = session.beginTransaction();        Person person = (Person) session.get(Person.class, 2);        person.setIdCard(null);        tx.commit();
            结果为:

Hibernate: select person0_.id as id1_6_0_, person0_.name as name2_6_0_, idcard1_.id as id1_5_1_, idcard1_.num as num2_5_1_, idcard1_.personId as personId3_5_1_ from t_person person0_ left outer join t_idCard idcard1_ on person0_.id=idcard1_.personId where person0_.id=?
           无update语句,说明并没有解除关系

        7> 删除

        从无外键的一方删除

      factory = new Configuration().configure().buildSessionFactory();      session = factory.openSession();      Transaction tx = session.beginTransaction();      Person person = (Person) session.get(Person.class, 2);      session.delete(person);      tx.commit();
        结果为:

 com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t_idcard`, CONSTRAINT `FK_k76g8cd5pddkq5qesjleu60ts` FOREIGN KEY (`personId`) REFERENCES `t_person` (`id`))
        从有外键的一方删除

      factory = new Configuration().configure().buildSessionFactory();      session = factory.openSession();      Transaction tx = session.beginTransaction();      IdCard idCard = (IdCard) session.get(IdCard.class, 2);      session.delete(idCard);      tx.commit();
        结果为:

Hibernate: select idcard0_.id as id1_5_0_, idcard0_.num as num2_5_0_, idcard0_.personId as personId3_5_0_ from t_idCard idcard0_ where idcard0_.id=?Hibernate: delete from t_idCard where id=?
        成功删除

        7> 因为在一对一关系中只有一方维护关系,所以只能从维护外键的一方执行解除关系和删除操作

        3) 基于主键的方式

             1>  pojo

                 和基于外键的完全相同

             2>  映射文件

               无外键一方:

<class name="cn.com.cpf.pojo.Person"   table="t_person2" >  <id name="id" column="id">       <generator class="native"/>  </id>  <property name="name"/>  <one-to-one name="idCard" class="cn.com.cpf.pojo.IdCard"/> </class>
               有外键一方:

 <class name="cn.com.cpf.pojo.IdCard"   table="t_idCard2" >  <id name="id" column="id">        <generator class="foreign">            <param name="property">person</param>        </generator>  </id>  <property name="num"/>  <one-to-one name="person" class="cn.com.cpf.pojo.Person" constrained="true"/> </class>
              1.主键的生成方式为foreign,其中需要配property参数,值为依赖的其id的那个对象

              2.在one-to-one标签中,需要设置constrained为true

            3> 生成的数据库表

            维护外键的表:

           

          

          不维护外键的表:
           

          4> 解除关联关系

              由于是基于主键的关联,且因为不能设置主键为null,所以不论是哪一方都无法解除关系

      

0 0
原创粉丝点击