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

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

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

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

    实例场景:人<—-> 身份证号(Person<->IdCard)双向:互相持有对方的引用

    IdCard实体类:

    public class IdCard {
    
        private int id;
    
        private String cardNo; 
    
        private Person person; //持有Person对象的引用
    
        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;
    
        }
    
        public Person getPerson() {
    
            return person;
    
        }
    
        public void setPerson(Person person) {
    
            this.person = person;
    
        }
    
    }

    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;
    
        }
    
    }

    IdCard实体类映射文件:

    <hibernate-mapping>
    
        <class name="com.wjt276.hibernate.IdCard" table="t_idcard">
    
            <id name="id" column="id">
    
                <generator class="native"/>
    
            </id>
    
            <property name="cardNo"/>
    
    <!—
    
    one-to-one标签的含义:指示hibernate怎么加载它的关联对象(这里的关联对象为person),默认根据主键加载
    
    -->
    
            <one-to-one name="person"/>
    
        </class>
    
    </hibernate-mapping>

    Person实体类映射文件不变:

    <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>

    导出至数据库表生成SQL语句:

    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)

    注意:此双向的SQL语句,与单向的SQL语句没有任何变化,也就是说数据库中的表单向双向没有任何区别。<one-to-one>的单向、双向对数据库表没有影响,只是告诉Hibernate如何加载数据对象。

    一对一 主键关联映射加载数据测试—双向:

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

    加载数据时,输出SQL语句:

    Hibernate: select idcard0_.id as id1_1_, idcard0_.cardNo as cardNo1_1_, person1_.id as id0_0_, person1_.name as name0_0_ from t_idcard idcard0_ left outer join t_person person1_ on idcard0_.id=person1_.id where idcard0_.id=?

    总结:

    需要在idcard映射文件中加入<one-to-one>标签指向hibernate,指示hibernate如何加载person(默认根据主键加载。)

  • 相关阅读:
    java基础循环、条件语句、switch case
    java基础抽象类、接口、枚举、包
    java基础基本数据类型、变量类型、修饰符、运算符
    Mac权限问题,operation not permitted
    【比赛游记】NOIP2021 游记
    【比赛题解】NOIP2021 题解
    把LeetCode上的Sql题刷完了会有什么收获
    分析函数之Lead()、Lag()
    QT相关(c++)
    grpc
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4077920.html
Copyright © 2011-2022 走看看