zoukankan      html  css  js  c++  java
  • 009一对一 主键关联映射_单向(one-to-one)

    009一对一  主键关联映射_单向(one-to-one)

    ²  两个对象之间是一对一的关系,如Person-IdCard(人—身份证号)

    ²  有两种策略可以实现一对一的关联映射

    • 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联。
    • 唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系。

    实例场景:人—-> 身份证号(PersonàIdCard),从IdCard看不到Person对象

    对象模型(主键关联映射-单向):

    (站在人的角度看)

    IdCard实体类:

    public class IdCard {
    
        private int id;
    
        private String cardNo;
    
     
    
        public int getId() {
    
            return id;
    
        }
    
        public void setId(int id) {
    
            this.id = id;
    
        }
    
        public String getCardNo() {
    
            return cardNo;
    
        }
    
        public void setCardNo(String cardNo) {
    
            this.cardNo = cardNo;
    
        }
    
    }

    Person实体类:

    public class Person {
    
        private int id;
    
        private String name;   
    
        private IdCard idCard;//持有IdCard对象的引用
    
        public int getId() {
    
            return id;
    
        }
    
        public void setId(int id) {
    
            this.id = id;
    
        }
    
        public String getName() {
    
            return name;
    
        }
    
        public void setName(String name) {
    
            this.name = name;
    
        }
    
        public IdCard getIdCard() {
    
            return idCard;
    
        }
    
        public void setIdCard(IdCard idCard) {
    
            this.idCard = idCard;
    
        }
    
    }

    因为是person引用idcard,所以idcard要求先有值。而person的主键值不是自己生成的。而是参考idcard的值,person即是主键,同时也是外键。

    IdCard实体类的映射文件:

    <hibernate-mapping>
    
        <class name="com.wjt276.hibernate.IdCard" table="t_idcard">
    
            <id name="id" column="id">
    
                <generator class="native"/>
    
            </id>
    
            <property name="cardNo"/>
    
        </class>
    
    </hibernate-mapping>

    Persion实体类的映射文件:

    <hibernate-mapping>
    
        <class name="com.wjt276.hibernate.Person" table="t_person">
    
            <id name="id" column="id">
    
                <!--
    
                    因为主键不是自己生成的,而是作为一个外键(来源于其它值),所以使用foreign生成策略
    
                    foreign:使用另外一个相关联的对象的标识符,通常和<one-to-one>联合起来使用。
    
                    再使用元素<param>的属性值指定相关联对象(这里Person相关联的对象为idCard,则标识符为idCard的id)为了能够在加载person数据同时加载IdCard数据,所以需要使用一个标签<one-to-one>来设置这个功能。
    
                 -->
    
                <generator class="foreign">
    
                    <!-- 元素<param>属性name的值是固定为property -->
    
                    <param name="property">idCard</param>
    
                </generator>
    
            </id>
    
            <property name="name"/>
    
            <!-- <one-to-one>标签
    
            表示如何加载它的引用对象(这里引用对象就指idCard这里的name值是idCard),同时也说是一对一的关系。
    
            默认方式是根据主键加载(把person中的主键取出再到IdCard中来取相关IdCard数据。)
    
     我们也说过此主键也作为一个外键引用 了IdCard,所以需要加一个数据库限制(外键约束)constrained="true"
    
             -->
    
            <one-to-one name="idCard" constrained="true"/> 
    
    </class>
    
    </hibernate-mapping>

    导出至数据库表生成代码如下:

    create table t_idcard (id integer not null auto_increment, cardNo varchar(255), primary key (id))

    create table t_person (id integer not null, name varchar(255), primary key (id))

    alter table t_person add index FK785BED805248EF3 (id), add constraint FK785BED805248EF3 foreign key (id) references t_idcard (id)

    * alter table  ……  意思:person的主键id以外键参照idcard的主键

    ※<one-to-one>标签※

             现在是使用一对一主键关联映射,因为主键不是自己生成的,而是作为一个外键(来源于其它值),所以使用foreign生成策略(使用另外一个相关联的对象的标识符,通常和<one-to-one>联合起来使用)。再使用元素<param>的属性值指定相关联对象(这里Person相关联的对象为idCard,则标识符为idCard的id)为了能够在加载person数据同时加载IdCard数据,所以需要使用一个标签<one-to-one>来设置这个功能。

    <id name="id" column="id">
    
            <generator class="foreign">
    
                <param name="property">idCard</param>
    
            </generator>
    
        </id>
    
    <one-to-one name="idCard" constrained="true"/> 

    一对一 主键关联映射 存储测试

    session = HibernateUtils.getSession();
    
                tx = session.beginTransaction();
    
       
    
                IdCard idCard = new IdCard();
    
                idCard.setCardNo("88888888888888888888888");
    
               
    
                Person person = new Person();
    
                person.setName("菜10");
    
                person.setIdCard(idCard);
    
               
    
                //不会出现TransientObjectException异常
    
                //因为一对一主键关键映射中,默认了cascade属性。
    
                session.save(person);
    
                tx.commit();

    注:不会出现TransientObjectException异常,因为一对一主键关键映射中,默认了cascade属性。

     

    生成SQL语句:

    Hibernate: insert into t_idcard (cardNo) values (?)

    Hibernate: insert into t_person (name, id) values (?, ?)

    一对一 主键关联映射 加载测试

     

    session = HibernateUtils.getSession();
    
                tx = session.beginTransaction();
    
                Person person = (Person)session.load(Person.class, 1);
    
                System.out.println("person.name=" + person.getName());
    
                System.out.println("idCard.cardNo=" + person.getIdCard().getCardNo());
    
                // 提交事务
    
                tx.commit();

    生成SQL语句:

    Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from t_person person0_ where person0_.id=?

    person.name=菜10

    Hibernate: select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idcard idcard0_ where idcard0_.id=?

    idCard.cardNo=88888888888888888888888

    一对一 主键关联映射 总结:

         让两个实体对象的ID保持相同,这样可以避免多余的字段被创建

     

    <id name="id" column="id">
    
         <!—person的主键来源idcard,也就是共享idCard的主键-->
    
                <generator class="foreign">
    
                    <param name="property">idCard</param>
    
                </generator>
    
            </id>
    
            <property name="name"/>
    
    <!—one-to-one标签的含义:指示hibernate怎么加载它的关联对象,默认根据主键加载
    
    constrained="true",表面当前主键上存在一个约束:person的主键作为外键参照了idCard-->
    
            <one-to-one name="idCard" constrained="true"/>
  • 相关阅读:
    Codeforces Round #450 (Div. 2)
    吉哥系列故事——恨7不成妻(数位DP)
    Codeforces Round #546 (Div. 2)
    Balanced Numbers (数位DP)
    XHXJ's LIS(数位DP)
    Balanced Number(数位DP)
    (2016北京集训十三)【xsy1533】mushroom
    (2016北京集训十三)【xsy1532】网络战争
    (2016北京集训十三)【xsy1531】魔法游戏
    (2016北京集训十二)【xsy1542】疯狂求导
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4076949.html
Copyright © 2011-2022 走看看