• 十、一对一


    四、一对一

     

    一对一分为,基于主键的一对一,和基于外键的一对一。

    基于主键的一对一,指的是,idCard表的主键就是外键,它的值参考person表的id,而不需要重新生成一个字段来记录到底这个idCard是指向哪个person的。

    而基于外键的一对一,指的是,personid我们自定,idCardid我们也自定。我们要根据用户的代码idCard.setPerson(),在idCard表中新增成一个字段person,来记录到底这个idCard是属于哪个person的。

     

    1.基于主键的一对一

     

     

    基于主键的一对一:

    person表中,person_id是主键,在IdCard表中,card_id不仅是主键,也是外键--它的值是复制Person_id的。

     

    ①创建domain

     

     

     

    ②创建(domain).hbm.xml

    <hibernate-mapping package="com.myz.domain">
    
    <class name="Person" table="person">
    
    <id name="id" type="java.lang.Integer">
    
    <!-- 手动分配id号 -->
    
    <generator class="assigned"></generator>
    
    </id>
    
    <property name="name" type="java.lang.String">
    
    <column name="name" length="64"></column>
    
    </property>
    
     
    
    <!-- 配置person和idCard属性是一对一的关系 -->
    
    <one-to-one name="idCard"></one-to-one>
    
    </class>
    
    </hibernate-mapping>

     

    <hibernate-mapping package="com.myz.domain">
    
    <class name="IdCard" table="idCard">
    
    <id name="id" type="java.lang.Integer">
    
    <!-- 因为我们这里是基于主键的一对一,说明Idcard的主键是依赖于Person的id的,所以这个主键既是主键,又是外键 -->
    
    <generator class="foreign">
    
    <!-- 这里的person指的是跟哪个属性一对一 -->
    
    <param name="property">person</param>
    
    </generator>
    
    </id>
    
    <property name="cardtime" type="java.util.Date">
    
    <column name="cardtime" length="64"></column>
    
    </property>
    
     
    
    <!-- 配置IdCard和person属性是一对一的关系 -->
    
    <one-to-one name="person"></one-to-one>
    
    </class>
    
    </hibernate-mapping>

     

    ③关系详解

     

    ④创建hibernate.hbm.xml,并让hibernate帮我们创建数据库

    <session-factory>
    
    <property name="dialect">
    
    org.hibernate.dialect.MySQLDialect
    
    </property>
    
    <property name="connection.url">
    
    jdbc:mysql://localhost:3306/test1
    
    </property>
    
    <property name="connection.username">root</property>
    
    <property name="connection.password">123456</property>
    
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    
    <property name="myeclipse.connection.profile">mysql</property>
    
    <property name="show_sql">true</property>
    
    <property name="hbm2ddl.auto">update</property>
    
     
    
    <mapping resource="com/myz/domain/Person.hbm.xml" />
    
    <mapping resource="com/myz/domain/IdCard.hbm.xml" />
    
     
    
    </session-factory>

    ⑤测试

    session=HibernateUtil.getCurrentSession();
    
    ts=session.beginTransaction();
    
     
    
    Person p1=new Person();
    
    p1.setId(1);
    
    p1.setName("孙悟空");
    
    IdCard idCard=new IdCard();
    
    idCard.setCardtime(new Date());
    
     
    
    //表示这个idCard这个对象是属于p1这个对象的
    
    //因为先有person再有idCard,后有的对象设置属性值为先有的对象
    
    idCard.setPerson(p1);
    
     
    
    //先有人再有idcard,保存也是先保存先有的对象
    
    session.save(p1);
    
    session.save(idCard);
    
     
    
    ts.commit();

    这时数据库虽然有person表和idCard表,而且idCard表主键确实也根据person主键确定,但是idCard表却没有外键,idCardid应该既是主键又是外键才对,这是因为我们没有让hibernate帮我们自动生成外键,在Idcard.hbm.xml处修改:

    <one-to-one name="person" constrained="true"></one-to-one>

    constrained默认为false,表示不生成外键

    此时再执行操作,发现idcard表生成了外键。跟person表的主键相对应。

    总结:

    配置domain.hbm.xml的时候 ,一个属性一个属性往下配,如果是主键就写到<id>里去,如果是普通属性就写到<property>里去,如果是对象属性就写到一对一里去。哪个值需要参考别的表的值,生成策略就是foreign。哪个表需要生成外键,就在一对一里写上constrained="true"

     

    2.基于外键的一对一

     

    与基于主键的一对一不同的是,虽然domain结构一样,我们想自己给idCard指定id,而让它给我们自动生成一个实实在在的外键person,指向personid

    ①创建domain对象

    ②创建Person.hbm.xml

    ③创建idCard.hbm.xml

    <class name="IDCard" table="sqlIDCard">
    
    <id name="cardId" type="java.lang.Integer">
    
    <column name="sqlCardId"></column>
    
    <generator class="assigned">
    
    </generator>
    
    </id>
    
     
    
    <property name="cardTime" type="java.util.Date">
    
    <column name="sqlCardTime"></column>
    
    </property>
    
    //由于多个外键可以指向同一个主键,所以是many-to-one
    
    //由于一张身份证只能归一人持有,所以需要添加unique,防止多个外键指向同一个主键
    
    //所以即使这个是一对一的关系,我们还是使用many-to-one
    
    <many-to-one name="person" unique="true"></many-to-one>
    
    </class>

    ④测试

    public static void main(String[] args) {
    
    // TODO Auto-generated method stub
    
    Session session=null;
    
    Transaction ts=null;
    
    try {
    
    session=HibernateUtil.getCurrentSession();
    
    ts=session.beginTransaction();
    
     
    
    Person p1=new Person();
    
    p1.setPersonId(8);
    
    p1.setPersonName("jack");
    
    IDCard idCard=new IDCard();
    
    idCard.setCardId(101);
    
    idCard.setCardTime(new Date());
    
    idCard.setPerson(p1);
    
     
    
    session.save(idCard);
    
    session.save(p1);
    
     
    
     
    
    ts.commit();
    
    } catch (Exception e) {
    
    // TODO: handle exception
    
    e.printStackTrace();
    
    ts.rollback();
    
    }finally{
    
    if(ts.isActive()) ts=null;
    
    if(session.isOpen()) session.close();
    
    }
    
    }

    ⑤查看mysql

    IdCard表总共有三个字段,idnameperson。系统自动生成了一个字段,person。是外键,它指向person表的id

  • 相关阅读:
    2015 年最受 Linux 爱好者欢迎的软硬件大盘点
    Java 9终于要包含Jigsaw项目了
    Linux 容器技术史话:从 chroot 到未来
    开发者最常用的 8 款 Sublime Text 3 插件
    60,000毫秒内对Linux的性能诊断效的方法
    bzoj 2595 [Wc2008]游览计划(斯坦纳树)
    bzoj 3997 [TJOI2015]组合数学(DP)
    bzoj 1014 [JSOI2008]火星人prefix(splay+hash)
    bzoj 1090 [SCOI2003]字符串折叠(区间DP)
    bzoj 1537 [POI2005]Aut- The Bus(DP+BIT)
  • 原文地址:https://www.cnblogs.com/myz666/p/8425080.html
Copyright © 2020-2023  润新知