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"/>
  • 相关阅读:
    Python 安装Twisted 提示python version 2.7 required,which was not found in the registry
    Openfire Strophe开发中文乱码问题
    css div 垂直居中
    How to create custom methods for use in spring security expression language annotations
    How to check “hasRole” in Java Code with Spring Security?
    Android 显示/隐藏 应用图标
    Android 当媒体变更后,通知其他应用重新扫描
    文件上传那些事儿
    专题:点滴Javascript
    主流动画实现方式总结
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4076949.html
Copyright © 2011-2022 走看看