此文章部分参看: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对象。