Hibernate单向1-1关联
对于单向的1-1关联,需要在实体类中增加相对应关联实体的属性(关联实体对象)
基于外键的单向1-1关联
Annotation方式
无连接表的单向1-1关联
首先使用@OneToOne注解代表关联实体的属性,再使用@JoinColumn映射外键即可
例:Husband类中设置了对应的Wife类对象,并为之增加@OneToOne和@JoinColumn注解,其中unique=true保证了wife_id字段的唯一性
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
@OneToOne
@JoinColumn(name="wife_id", unique=true)
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
由于是单向1-1,所有Wife类中没有设置Husband对象
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Wife {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
测试类:
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;
/**
* @author msidolphin
* @time 2017年6月3日
*/
public class DomainJunit {
@Test
public void schemaExport_() {
new SchemaExport(new Configuration().configure()).create(false, true);
}
}
控制台日志输出的SQL语句
有连接表的单向1-1关联
有连接表的单向1-1关联需要使用@JoinTable注解映射连接表,由于是1-1关联,因此需要为@JoinTable注解中的joinColumns属性映射的外键字段设置unique=true属性,以此保证严格的1-1关联
Husband类:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
@OneToOne
@JoinColumn(name="wife_id", unique=true)
@JoinTable(
name="husband_wife", //表名
joinColumns=@JoinColumn(
name="husband_id",
unique=true,
referencedColumnName="id"
),
inverseJoinColumns=@JoinColumn(
name="wife_id",
unique=true,
referencedColumnName="id"
)
)
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife类无需改动,同上
控制台输出的sql语句:
XML方式
使用<many-to-one>标签设置关联实体属性,由于是1-1,所以unique属性要设置为true
husband.hbm.xml文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="pers.msidolphin.hibernate.one2one">
<class name="Husband" table="husband">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name" length="50"/>
<many-to-one name="wife" column="wife_id" unique="true"></many-to-one>
</class>
</hibernate-mapping>
wife.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="pers.msidolphin.hibernate.one2one">
<class name="Wife" table="wife">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name" length="50"></property>
</class>
</hibernate-mapping>
Hibernate双向1-1关联
双向1-1关联需要在两个实体类中都增加引用关联实体的属性
基于外键的双向1-1关联
Annotation方式
无连接表的双向1-1关联
两端都需要为关联实体属性增加@OneToOne注解,对于基于外键的双向1-1关联,外键可以存放在任意一端,存放外键的一端,需要增加@JoinColumn注解映射外键字段,当选择一方增加外键后,该表即变为从表,而另一张表则为主表,主表对应的实体使用@OneToOne注解时,应增加mappedBy属性,表示该表作为主表使用,不增加对应从表的外键(这么做是为了防止修改从表时需要更新对应的主表字段,导致生成额外的update语句,引起性能下降)
例:
Husband类:husband表作为主表
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
@OneToOne(mappedBy="husband")
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife类:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Wife {
private int id;
private String name;
private Husband husband;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
@OneToOne
@JoinColumn(
name="husband_id",
unique=true
)
public Husband getHusband() {
return husband;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
}
结果:
有连接表的双向1-1关联
有连接表的双向1-1关联需要在两端都使用@JoinTable映射连接表,在映射连接表时,两端指定的连接表的表名应当相同,字段名当然也要一致
Husband类:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
@OneToOne
@JoinTable(
name="husband_wife", //表名
joinColumns=@JoinColumn(
name="husband_id",
unique=true,
referencedColumnName="id"
),
inverseJoinColumns=@JoinColumn(
name="wife_id",
unique=true,
referencedColumnName="id"
)
)
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife类:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Wife {
private int id;
private String name;
private Husband husband;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
@OneToOne
@JoinTable(
name="husband_wife", //表名
joinColumns=@JoinColumn(
name="wife_id",
unique=true,
referencedColumnName="id"
),
inverseJoinColumns=@JoinColumn(
name="husband_id",
unique=true,
referencedColumnName="id"
)
)
public Husband getHusband() {
return husband;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
}
结果:
XML方式
husband.hbm.xml文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="pers.msidolphin.hibernate.one2one">
<class name="Husband" table="husband">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name" length="50"/>
<many-to-one name="wife" column="wife_id" unique="true"></many-to-one>
</class>
</hibernate-mapping>
wife.hbm.xml文件
注:这里使用的是<one-to-one>标签,如果使用<many-to-one>标签,则在两张表中都会生成外键字段
<?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="pers.msidolphin.hibernate.one2one">
<class name="Wife" table="wife">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name" length="50"></property>
<one-to-one name="husband"></one-to-one>
</class>
</hibernate-mapping>
Hibernate联合主键关联
Annotation方式
Wife类:id和name字段作为联合主键
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Wife implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String name;
@Id
public int getId() {
return id;
}
@Id
@Column(length = 50)
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(obj instanceof Wife) {
Wife pk = (Wife) obj;
if(this.id == pk.getId() && this.name.equals(pk.getName())) {
return true;
}
return false;
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
Husband类:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.OneToOne;
/**
* @author msidolphin
* @time 2017年6月3日
*/
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
@Column(length = 50)
public String getName() {
return name;
}
@OneToOne
@JoinColumns({
@JoinColumn(name="wife_id", referencedColumnName="id", unique=true),
@JoinColumn(name="wife_name", referencedColumnName="name", unique=true)
})
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
控制台打印的SQL建表语句:
XML方式
主键类: Wife表的id和name字段作为联合主键
import java.io.Serializable;
/**
* @author msidolphin
* @time 2017年6月3日
*/
public class WifePk implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String name;
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(obj instanceof WifePk) {
WifePk pk = (WifePk) obj;
if(this.id == pk.getId() && this.name.equals(pk.getName())) {
return true;
}
return false;
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
Wife类:
/**
* @author msidolphin
* @time 2017年6月3日
*/
public class Wife {
private WifePk pk;
public WifePk getPk() {
return pk;
}
public void setPk(WifePk pk) {
this.pk = pk;
}
}
Husband类:
/**
* @author msidolphin
* @time 2017年6月3日
*/
public class Husband {
private int id;
private String name;
private Wife wife;
public int getId() {
return id;
}
public String getName() {
return name;
}
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
wife.hbm.xml文件,由于使用了联合主键,所以应该使用<composite-id>标签
<?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="pers.msidolphin.hibernate.one2one">
<class name="Wife" table="wife">
<composite-id name="pk" class="pers.msidolphin.hibernate.one2one.WifePk">
<key-property name="id"></key-property>
<key-property name="name" length="50"></key-property>
</composite-id>
</class>
</hibernate-mapping>
husband.hbm.xml文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="pers.msidolphin.hibernate.one2one">
<class name="Husband" table="husband">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name" length="50"/>
<many-to-one name="wife">
<!-- 要格外注意顺序 -->
<column name="wife_id" unique="true"></column>
<column name="wife_name" unique="true"></column>
</many-to-one>
</class>
</hibernate-mapping>
控制台打印的SQL建表语句: