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