首先是兩個類,在中國是實行一夫一妻,也就是一個husband只能對應一個wife
Wife類,產生的表為t_wife
/** * */package com.maybe.test_1;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;/** * @author MayBe * * function: */@Entity@Table(name="t_wife")public class Wife {private Integer id;private String name;private Husband husband;@Id@GeneratedValuepublic Integer getId() {return id;}public String getName() {return name;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}@OneToOnepublic Husband getHusband() {return husband;}public void setHusband(Husband husband) {this.husband = husband;}}
Husband類,產生的表為t_husband
/** * */package com.maybe.test_1;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;import javax.persistence.Table;/** * @author MayBe * * function: */@Entity@Table(name="t_husband")public class Husband {private Integer id;private String name;private Wife wife;@Id@GeneratedValuepublic Integer getId() {return id;}public String getName() {return name;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}@OneToOnepublic Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}}
因為是一對一雙向關聯,wife類和husband類都包含對方的引用
hibernate.cfg.xml檔案如下:
<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property> <property name="connection.url">jdbc:sqlserver://localhost;DatabaseName=hibernate</property> <property name="connection.username">sa</property> <property name="connection.password">yaphets</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.SQLServerDialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <property name="format_sql">true</property> <!-- <mapping resource="com/maybe/test_1/Player.hbm.xml"/> --> <mapping class="com.maybe.test_1.Husband"/> <mapping class="com.maybe.test_1.Wife"/> </session-factory></hibernate-configuration>
用Junit進行測試,產生的建表語句如下所示
drop table t_wife
create table t_husband (
id int identity not null,
name varchar(255),
wife_id int,
primary key (id)
)
create table t_wife (
id int identity not null,
name varchar(255),
husband_id int,
primary key (id)
)
alter table t_husband
add constraint FK_hxagmw4p5aym8m63pxd6h2wwx
foreign key (wife_id)
references t_wife
alter table t_wife
add constraint FK_fi3kodkmubgryyblf4935y4dk
foreign key (husband_id)
references t_husband
不難看出這種一對一關聯性比較冗餘,這個表的設計明顯有問題,原因是我們在使用註解的時候One-to-one,是由hibernate自動產生的,解決辦法非常簡單,只要在註解上添加一個屬性就可以,比如Husband類:
/** * */package com.maybe.test_1;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;import javax.persistence.Table;/** * @author MayBe * * function: */@Entity@Table(name="t_husband")public class Husband {private Integer id;private String name;private Wife wife;@Id@GeneratedValuepublic Integer getId() {return id;}public String getName() {return name;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}@OneToOne(mappedBy="husband")public Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}}
我們在onetoone中使用了mappedby屬性(在雙向關聯中一般都要用到),指明了mappedBy ,就指明了這個映射關係的承擔方(Wife類中的husband),產生的資料表樹下所示:
create table t_husband (
id int identity not null,
name varchar(255),
primary key (id)
)
create table t_wife (
id int identity not null,
name varchar(255),
husband_id int,
primary key (id)
)
alter table t_wife
add constraint FK_fi3kodkmubgryyblf4935y4dk
foreign key (husband_id)
references t_husband
這次產生的表沒有冗餘,在wife表中有一個外鍵husband_id,正是通過husband_id來維護兩個標的聯絡,所以雙向關係中,要加上mappedBy屬性確保資料庫表的正確性