Hibernate中一对一

           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@2e9dca26
11X 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,所以不论是哪一方都无法解除关系

      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值