hibernate 一对一主键关联

本文介绍了Hibernate中的一对一双向主键关联,通过创建people和idcard两个表,并详细说明了表的设计,包括外键设置和自增属性。然后展示了如何利用IDEA生成相关类文件和配置文件,最后通过测试文件Manage.java展示了一对一关联的级联操作及对象加载过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此文章部分参看:https://blog.youkuaiyun.com/lzm1340458776/article/details/32155365

hibernate 一对一主键关联有一对一双向主键关联和单向主键关联,本文章仅介绍一对一双向主键关联

step1:建表

建立 people 和 idcard 两个表,如下图:
在这里插入图片描述
people 表中,id属性既为主码也为外码,而外码中设置 on update 和 on delete 为 CASCADE

此外,设置了idcard的id属性为自增,而people的id属性不设自增(仅作记录。对于结果应该没有影响)

利用 idea 自动生成相关类文件和配置文件,经过修改后,各相关文件内容如下:

People.java

package com.wyx.mapping.one_to_one;

import javax.persistence.*;
import java.util.Objects;

@Entity
public class People {
    private int pid;
    private String name;
    private Idcard idcard;

    @Id
    @Column(name = "pid", nullable = false)
    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    @Basic
    @Column(name = "name", nullable = false, length = 45)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        People people = (People) o;
        return pid == people.pid &&
                Objects.equals(name, people.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(pid, name);
    }

    @OneToOne(mappedBy = "people")
    public Idcard getIdcard() {
        return idcard;
    }

    public void setIdcard(Idcard idcard) {
        this.idcard = idcard;
    }
}

Idcard.java

package com.wyx.mapping.one_to_one;

import javax.persistence.*;
import java.util.Objects;

@Entity
public class Idcard {
    private int cid;
    private String number;
    private People people;

    @Id
    @Column(name = "cid", nullable = false)
    public int getCid() {
        return cid;
    }

    public void setCid(int cid) {
        this.cid = cid;
    }

    @Basic
    @Column(name = "number", nullable = false, length = 45)
    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Idcard idcard = (Idcard) o;
        return cid == idcard.cid &&
                Objects.equals(number, idcard.number);
    }

    @Override
    public int hashCode() {
        return Objects.hash(cid, number);
    }

    @OneToOne
    @JoinColumn(name = "cid", referencedColumnName = "pid", nullable = false)
    public People getPeople() {
        return people;
    }

    public void setPeople(People people) {
        this.people = people;
    }
}

people.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.wyx.mapping.one_to_one.People" table="people" schema="hibernate">
        <id name="pid">
            <column name="pid" sql-type="int(11)"/>
            <generator class="foreign">
                <param name="property">idcard</param>
            </generator>
        </id>
        <property name="name">
            <column name="name" sql-type="varchar(45)" length="45"/>
        </property>
        <one-to-one name="idcard" class="com.wyx.mapping.one_to_one.Idcard" constrained="true"/>
    </class>
</hibernate-mapping>

idcard.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.wyx.mapping.one_to_one.Idcard" table="idcard" schema="hibernate">
        <id name="cid">
            <column name="cid" sql-type="int(11)"/>
            <generator class="native"/>
        </id>
        <property name="number">
            <column name="number" sql-type="varchar(45)" length="45"/>
        </property>
        <one-to-one name="people" class="com.wyx.mapping.one_to_one.People"/>
    </class>
</hibernate-mapping>

测试文件
Manage.java

package com.wyx.mapping.one_to_one;

import com.wyx.hibernate.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class Manager {
    public static void main(String[] args){
        Session session = null;
        Transaction transaction = null;

        try {
            session = HibernateUtil.getSession();
            transaction = session.beginTransaction();
            Idcard idcard = new Idcard();
            idcard.setNumber("774562223612223725");
            People people = new People();
            people.setName("et");

            // 可以实现级联保存的,因为Person是维护关系的一端
            people.setIdcard(idcard);
            // 通过IDCard是不能级联保存Person的,因为IDCard是关系的被维护端
            //idcard.setPeople(people);
            session.save(people);
            transaction.commit();
        }catch (Exception e){
            transaction.rollback();
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }

        // 通过Person可以加载IDCard对象,因为是双向关联(发出两条sql语句)
        People people = HibernateUtil.getSession().get(People.class, new Integer("12"));
        System.out.println("people.name: " + people.getName());
        System.out.println("people.idcard.number: " + people.getIdcard().getNumber());

        // 通过IDCard可以加载Person对象,因为是双向关联(只发出一条语句,这涉及到抓取策略)
        Idcard idcard = HibernateUtil.getSession().get(Idcard.class, new Integer("13"));
        System.out.println("idcard.number: " + idcard.getNumber());
        System.out.println("idcard.people.name: " + idcard.getPeople().getName());

    }
}

运行结果:
在这里插入图片描述
如图,前面两个查询语句为级联插入,而接着四行为people加载idcard对象,最后三行为idcard对象加载people对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值