一对一关系映射

本文介绍了数据库中一对一关系映射的两种方式:主键关联和外键关联。在主键关联中,一个实体的主键被另一个实体引用。在外键关联中,每个实体都有自己的主键,但一个实体通过外键字段引用另一个实体的主键。通过示例展示了如何在映射文件中配置这些关联。

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

主键关联

两个关联的实体在表中具有相同的主键值,这个主键可只由其中一个表生成,在另外一个表中通过映射文件中使用主键的foreign生成机制引用已经生成的主键值。

Student类

package Mapping2;

public class Student {
	
	private Long id;
	private long studentNo;
	private String studentName;
	private int sage;
	private String major;
	
	/*	进行一对一关联,双方互添引用对方对象的属性及方法 */
	private Card card;
	
	public Card getCard() {
		return card;
	}
	
	public void setCard(Card card) {
		this.card = card;
	}
	
	
	public Student() {}
	public Student(long studentNo, String studentName, int sage, String major) {
		super();
		this.studentNo = studentNo;
		this.studentName = studentName;
		this.sage = sage;
		this.major = major;
	}
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public long getStudentNo() {
		return studentNo;
	}
	public void setStudentNo(long studentNo) {
		this.studentNo = studentNo;
	}
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
	public int getSage() {
		return sage;
	}
	public void setSage(int sage) {
		this.sage = sage;
	}
	public String getMajor() {
		return major;
	}
	public void setMajor(String major) {
		this.major = major;
	}
}


Student.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 package="Mapping2">
	<class name="Student" table="student" >
		<id name="id" column="id">
			<generator class="identity"/>
		</id>
		<property name="studentNo" type="long" column="student_no"/>
		<property name="studentName" type="string" column="student_name"/>
		<property name="sage" type="integer" column="sage"/>
		<property name="major" type="string" column="major"/>
	
		<one-to-one name="card" class="Mapping2.Card" cascade="all" fetch="join" />
		
	</class>
</hibernate-mapping>


Card类

package Mapping2;

public class Card {

	private Long id;
	private String cardNo;
	private String major;
	private double balance;
	
	/*	一对一关联,双方互添引用对方对象的属性及方法 	*/
	private Student student;
	
	public Student getStudent() {
		return student;
	}

	public void setStudent(Student student) {
		this.student = student;
	}


	public Card() {
		// TODO Auto-generated constructor stub
	}
	
	public Card(String cardNo, String major, double balance) {
		
		this.cardNo = cardNo;
		this.major = major;
		this.balance = balance;
	}

	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	
	public String getCardNo() {
		return cardNo;
	}
	public void setCardNo(String cardNo) {
		this.cardNo = cardNo;
	}

	public String getMajor() {
		return major;
	}
	public void setMajor(String major) {
		this.major = major;
	}

	public double getBalance() {
		return balance;
	}
	public void setBalance(double balance) {
		this.balance = balance;
	}

}

Card.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 package="Mapping2">
	<class name="Card" table="card" lazy="true" >
		<id name="id" column="id">
			<generator class="foreign">	<!-- 一对一关系映射,主键关联class是 foreign,外键关联是identity -->
				<param name="property">student</param>
			</generator>
		</id>
		<property name="CardNo" type="string" column="CardNo"/>
		<property name="major" type="string" column="major"/>
		<property name="balance" type="double" column="balance"/>
		
		<!-- 一对一主键关联  -->
		<one-to-one name="student" class="Mapping2.Student" constrained="true"  />

	</class>
</hibernate-mapping>

测试
package Mapping2;

import org.hibernate.Transaction;
import org.hibernate.Session;

import util.HibernateUtil;

public class OneToOnePrimaryKeyAssociation {

	public static void main(String[] args) {
		
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		Student student = new Student(20120101,"Akbar Housein",20,"电子商务");
		Card card = new Card("110101","电子商务",1500.00);
		student.setCard(card);
		card.setStudent(student);
		session.save(student);
		tx.commit();
	}
}

结果




外键关联

一对一的外键关联是指两个实体各自有自己的主键,但其中一个实体用外键引用另外一个实体。例如,Student实体和Card实体各自对应表的主键都是id,设在card表中还有一个studentId属性,它引用student表的id列,在card表中studentId就是外键。

若仍建立双向关联,则Student.hbm.xml无须修改,修改后的Card.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 package="Mapping2">
	<class name="Card" table="card" lazy="true" >
		<id name="id" column="id">
			<generator class="identity">	<!-- 一对一关系映射,主键关联class是 foreign,外键关联是identity -->
				<param name="property">student</param>
			</generator>
		</id>
		<property name="CardNo" type="string" column="CardNo"/>
		<property name="major" type="string" column="major"/>
		<property name="balance" type="double" column="balance"/>
		
		<!-- 一对一主键关联  
		<one-to-one name="student" class="Mapping2.Student" constrained="true"  />-->
		
		 
		<!-- 一对一外键关联 -->
		<many-to-one name="student" class="Mapping2.Student"
			 column="studentId" unique="true" />	
		<!-- 一对一关联实际是多对一关联的特例,当将<many-to-one>元素的unique属性值指定为true时,
			多对一的关联实际上变成了一对一的关联 -->
	</class>
</hibernate-mapping>

上面Card类的基础上再加入studentId属性及setter、getter方法和新构造函数

	/*一对一外键关联	*/
	private Student studentId;
	
	public Student getStudentId() {
		return studentId;
	}

	public void setStudentId(Student studentId) {
		this.studentId = studentId;
	}
	
	public Card(String cardNo, String major, double balance,
			Student studentId) {
		
		this.cardNo = cardNo;
		this.major = major;
		this.balance = balance;
		this.studentId = studentId;
	}

将上面测试类中
Card card = new Card("110101","电子商务",1500.00);

改为

Card card = new Card("110101","电子商务",1500.00,student);

运行结果




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值