hibernate主键相同的一对一关系

本文介绍如何在Hibernate中实现一对一双主键关联,通过实体类和配置文件的设置,展示了一个客户和其地址实体类之间的一对一关系,省去了外键约束,详细步骤包括创建java工程、导入相关类库、建立实体类、配置映射关系、编写测试代码和运行测试。

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

由于两个实体类是一对一的关系,因此可以设置两个实体类使用相同的主键。相对的,具有相同注解的实体被视为一对一的关系,这样两个表就省略了外键关联。


demo实例

客户地址管理,一个客户对应一个地址,实体间使用相同的主键。


1、建立java工程


2、导入hibernate和MySql相关类库。

  详见之前的博客hibernate单边一对多关系中的配置。


3、建立实体类

Customer为客户的实体类,Address为客户的地址实体类;

两个实体类之间是一对一的属性,两者之间使用相同的主键而没有使用外键约束。

配置时使用OneToOne指定一对一关系,使用@PrimaryKeyJoinColumn指定两个实体类之间使用相同的主键。


客户的实体类Customer.java代码如下:

package com.arvinfei.hibernate.bean;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

@Entity
@Table(name = "tb_customer")
public class Customer {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;

	private String name;

	@OneToOne
	@PrimaryKeyJoinColumn
	private Address address;

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

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

}

地址的实体类Address.java代码如下:

两个实体类使用主键进行一对一关联,这里两个主键为整形,其中客户使用了自增长属性,那么地址就不能在使用自增长属性,否则可能会是两个实体对象的id不一致。hibernate也不会自动保证两个id相同,此时需要手动设置id以保证两个id一致(即将客户自动分配到的id设置给地址)。

package com.arvinfei.hibernate.bean;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

@Entity
@Table(name = "tb_address")
public class Address {

	@Id
	// @GeneratedValue(strategy = GenerationType.IDENTITY)//不使用自动增长
	private Integer id;

	@OneToOne
	@PrimaryKeyJoinColumn
	private Customer customer;

	private String address;

	private String zip;

	private String telephone;

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getTelephone() {
		return telephone;
	}

	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}

	public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}

}

4、在hibernate的配置文件中添加实体类映射关系

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>    
    <property name="dialect">
        org.hibernate.dialect.MySQLDialect
    </property>
    <property name="connection.url">
        jdbc:mysql://localhost:3306/one2onebykey?characterEncoding=UTF-8
    </property>
    <property name="connection.username">root</property>
    <property name="connection.password">admin</property>
    <property name="connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">create</property>    
    <mapping class="com.arvinfei.hibernate.bean.Address" />
    <mapping class="com.arvinfei.hibernate.bean.Customer" />

</session-factory>

</hibernate-configuration>

5、新建测试代码

package com.arvinfei.hibernate.test;

import java.util.List;

import org.hibernate.Session;

import com.arvinfei.hibernate.bean.Address;
import com.arvinfei.hibernate.bean.Customer;
import com.arvinfei.hibernate.util.HibernateSessionFactory;

public class One2OneKey {

	@SuppressWarnings("all")
	public static void main(String[] args) throws Exception {

		Customer customer = new Customer();
		customer.setName("Helloween");

		Address address = new Address();
		address.setAddress("北京市海淀区中关村");
		address.setTelephone("010-77883210");
		address.setZip("100001");

		// address.setCustomer(customer);

		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();

		// 保存 customer,数据库会为 customer 自动分配 ID
		session.persist(customer);

		// 要手工设置 address 的 ID 保证两个ID一致
		address.setId(customer.getId());

		// 保存 address
		session.persist(address);

		session.flush();

		List<Customer> list = session
				.createQuery(" select c from Customer c where c.name = :name ")
				.setParameter("name", "Helloween").list();

		for (Customer c : list) {
			session.refresh(c);
			System.out.println("客户姓名:" + c.getName());
			System.out.println("\t电话:" + c.getAddress().getTelephone());
			System.out.println("\t邮编:" + c.getAddress().getZip());
			System.out.println("\t地址:" + c.getAddress().getAddress());
		}

		session.getTransaction().commit();
		session.close();
	}
}

6、修改HibernateSessionFactory

修改HibernateSessionFactory中的sessionFactory配置方式,默认为xml配置方式,demo中使用注解进行配置,所以需要进行简单修改。

7、运行测试

(1)、打开并连接到mysql数据库;

(2)、在mysql中创建Many2Many数据库;

    create database one2onebykey character set 'utf8';   


(3)、运行本测试工程,查看log输出。


8、源码下载

http://download.youkuaiyun.com/detail/yxtouch/9161295

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值