Hibernate映射数据 - 一对一映射
Hierbnate中生成一对一映射关系的策略有主键映射以及外键映射两种。
主键映射: 通过将两个相关联的表生成共享主键,完成一对一的数据库表结构。
外键映射: 会在一个表中生成用于链接另一个表的外键,再通过unique属性实现一对一的数据库表结构。
例子:生成一个地址表(tb_address)用于存储学生的唯一的位置信息。
主键映射(双向)
1. student.java
package com.java1234.hibernate.model;
public class Student {
private int id;
private String name;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2. address.java
package com.java1234.hibernate.model;
public class Address {
private int id;
private String zipCode;
private String address;
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
3. stduent.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>
<class name="com.java1234.hibernate.model.Student" table="tb_student">
<id name="id" column="stuId">
<generator class="native"/>
</id>
<property name="name" column="stuName"/>
<!-- 添加一对一映射,当查询学生对应的地址信息时,通过以下属性完成映射 -->
<one-to-one name="address" class="com.java1234.hibernate.model.Address"/>
</class>
</hibernate-mapping>
4. address.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>
<class name="com.java1234.hibernate.model.Address" table="tb_address">
<id name="id" column="addId">
<!-- 定义主键生成策略为foreign,通过property绑定Address中的对象,
使得Address与Stduent的对象拥有统一主键 -->
<generator class="foregin">
<param name="property">student</param>
</generator>
</id>
<property name="zipCode" column="zipcode"/>
<property name="address" column="address"/>
<!-- 添加一对一映射,当查询地址对应的学生信息时,通过以下属性完成映射,
并用 constrained完成共享主键约束 -->
<one-to-one name="student" class="com.java1234.hibernate.model.Student" constrained="true"/>
</class>
</hibernate-mapping>
5. 生成的表结构/所执行的SQL
执行的SQL
Hibernate: create table tb_address (addId integer not null, zipcode varchar(255), address varchar(255), primary key (addId))
Hibernate: create table tb_student (stuId integer not null auto_increment, stuName varchar(255), primary key (stuId))
Hibernate: alter table tb_address add constraint FK_bssu6l647bdlxvhi84i6c0p8x foreign key (addId) references tb_student (stuId)
共享主键: stuId=1,addId=1 =>两个表的数据是相互顺序对应的。
6. 测试插入数据
TBD - 2018/11/20
外键连接(单向/双向)
1. student.java
2. address.java
同上
3. stduent.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>
<class name="com.java1234.hibernate.model.Student" table="tb_student">
<id name="id" column="stuId">
<generator class="native"/>
</id>
<property name="name" column="stuName"/>
<!-- 使用多对一映射,在tb_student中声明外键,并且使用unique="true" 说明外键只对应唯一的一个 -->
<many-to-one name="address" class="com.java1234.hibernate.model.Address"
column="addressId" cascade="all" unique="true"/>
</class>
</hibernate-mapping>
4. address.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>
<class name="com.java1234.hibernate.model.Address" table="tb_address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<property name="zipCode" column="zipcode"/>
<property name="address" column="address"/>
<!-- 无法通过addressId查到对应的学生信息-->
<one-to-one name="student" class="com.java1234.hibernate.model.Student"/>
<!-- 通过 property-ref=student 能过通过addressId反向映射到student信息,address是student.java中的属性名
<one-to-one name="student" class="com.java1234.hibernate.model.Student" property-ref="address" />
-->
</class>
</hibernate-mapping>
5. 生成的表结构/所执行的SQL
SQLs:
Hibernate: create table tb_address (addressId integer not null auto_increment, zipcode varchar(255), address varchar(255), primary key (addressId))
Hibernate: create table tb_student (stuId integer not null auto_increment, stuName varchar(255), addressId integer, primary key (stuId))
Hibernate: alter table tb_student add constraint UK_3b3r83kx7qks14wojkp07mu10 unique (addressId)
Hibernate: alter table tb_student add constraint FK_3b3r83kx7qks14wojkp07mu10 foreign key (addressId) references tb_address (addressId)