Hibernate中映射一对一关联(按主键映射和外键映射)和组件映射
Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射。
下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方式分别完成以下持久化操作:
(1)保存员工档案的同时分配给员工一个账号。
(2)加载员工档案的同时加载账号信息。
1.按照外键映射
步骤一:创建实体类Users1和Resume1
package cn.happy.onetoone.fk; public class Resume1 {
private Integer resId;
private Integer resUserId;
private String resName;
private String resCardNo;
private Users1 users1; public Integer getResId() {
return resId;
}
public void setResId(Integer resId) {
this.resId = resId;
}
public Integer getResUserId() {
return resUserId;
}
public void setResUserId(Integer resUserId) {
this.resUserId = resUserId;
}
public String getResName() {
return resName;
}
public void setResName(String resName) {
this.resName = resName;
}
public String getResCardNo() {
return resCardNo;
}
public void setResCardNo(String resCardNo) {
this.resCardNo = resCardNo;
}
public Users1 getUsers1() {
return users1;
}
public void setUsers1(Users1 users1) {
this.users1 = users1;
} }
Resume1
<?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="cn.happy.onetoone.fk"> <class name="Resume1" table="Resume1">
<id name="resId" column="RESID">
<generator class="sequence">
<param name="sequence">STU_SID</param>
</generator>
</id>
<property name="resName" type="string" column="RESRNAME"></property>
<property name="resCardNo" type="string" column="RESCARDNO"></property>
<many-to-one name="users1" class="Users1" column="RESUSERSID" cascade="all" unique="true"></many-to-one>
</class> </hibernate-mapping>
Resume1.hbm.xml
package cn.happy.onetoone.fk; public class Users1 {
private Integer userId;
private String userName;
private String userpass;
public String getUserpass() {
return userpass;
}
public void setUserpass(String userpass) {
this.userpass = userpass;
}
private Resume1 resume1; public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
} public Resume1 getResume1() {
return resume1;
}
public void setResume1(Resume1 resume1) {
this.resume1 = resume1;
}
}
Users1.java
<?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="cn.happy.onetoone.fk"> <class name="Users1" table="Users1">
<id name="userId" column="USERID">
<generator class="sequence">
<param name="sequence">STU_SID</param>
</generator>
</id>
<property name="userName" type="string" column="USERNAME"></property>
<property name="userpass" type="string" column="USERPASS"></property>
<one-to-one name="resume1" class="Resume1" property-ref="users1"></one-to-one>
</class> </hibernate-mapping>
Users1.hbm.xml
步骤二:配置文件Users1.hbm.xml和Resume1.hbm.xml
步骤三:测试方法书写
package cn.happy.onetoone.fk; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import cn.happy.util.HibernateUtil; public class Testone {
/**
* 一对一 按外键映射
* **/
@Test
public void onetoont(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Resume1 re=new Resume1();
re.setResName("学院不");
re.setResCardNo("002"); Users1 use=new Users1();
use.setUserName("王喜"); use.setResume1(re);
re.setUsers1(use); session.save(re);
tx.commit();
HibernateUtil.closeSession(); } @Test
public void select(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Users1 u =(Users1) session.get(Users1.class, 2);
System.out.println(u.getResume1().getResName());
tx.commit();
HibernateUtil.closeSession();
} }
测试
二:按照主键映射
步骤一:创建实体类Users2和Resume2
package cn.happy.onetoone.pk; public class Resume2 {
private Integer resId;
private Integer resUserId;
private String resName;
private String resCardNo;
private Users2 users1; public Integer getResId() {
return resId;
}
public void setResId(Integer resId) {
this.resId = resId;
}
public Integer getResUserId() {
return resUserId;
}
public void setResUserId(Integer resUserId) {
this.resUserId = resUserId;
}
public String getResName() {
return resName;
}
public void setResName(String resName) {
this.resName = resName;
}
public String getResCardNo() {
return resCardNo;
}
public void setResCardNo(String resCardNo) {
this.resCardNo = resCardNo;
}
public Users2 getUsers1() {
return users1;
}
public void setUsers1(Users2 users1) {
this.users1 = users1;
} }
Resume2.java
<?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="cn.happy.onetoone.pk"> <class name="Resume2" table="Resume2">
<id name="resId" column="RESID">
<generator class="sequence">
<param name="sequence">STU_SID</param>
</generator>
</id>
<property name="resName" type="string" column="RESRNAME"></property>
<property name="resCardNo" type="string" column="RESCARDNO"></property>
<one-to-one name="users1" class="Users2" cascade="all" ></one-to-one>
</class> </hibernate-mapping>
Resume2.hbm.xml
package cn.happy.onetoone.pk; public class Users2 {
private Integer userId;
private String userName;
private Resume2 resume1; public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
} public Resume2 getResume1() {
return resume1;
}
public void setResume1(Resume2 resume1) {
this.resume1 = resume1;
}
}
Users2.java
<?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="cn.happy.onetoone.pk"> <class name="Users2" table="Users2">
<id name="userId" column="USERID">
<generator class="foreign">
<param name="property">resume1</param>
</generator>
</id>
<property name="userName" type="string" column="USERNAME"></property> <one-to-one name="resume1" class="Resume2" constrained="true"></one-to-one>
</class> </hibernate-mapping>
Users2.hbm.xml
步骤二:配置文件Users2.hbm.xml和Resume2.hbm.xml
步骤三:测试方法书写
package cn.happy.onetoone.pk; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import cn.happy.util.HibernateUtil; public class Testone {
/**
* 一对一 按主键映射
* */
@Test
public void onetoont(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Resume2 re=new Resume2();
re.setResName("学院不2");
re.setResCardNo("2"); Users2 use=new Users2();
use.setUserName("王喜2"); use.setResume1(re);
re.setUsers1(use); session.save(re);
tx.commit();
HibernateUtil.closeSession(); } @Test
public void select(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Users2 u =(Users2) session.get(Users2.class, 1);
System.out.println(u.getResume1().getResName());
tx.commit();
HibernateUtil.closeSession();
} }
测试代码
3.组件映射
建立关系数据模型的一个重要原则是在不会导致数据冗余的前提下,尽可能减少数据库表的数目及表之间的外键参照关系。以员工信息为例,员工信息中有员工的家庭地址信息,如果把地址信息单独放在一张表中,然后建立员工信息表和地址信息表之间的外键参照关系,当每次查询员工信息时,都需建立者两个表的连接。建立表的连接是很耗时的操作,为了提高数据库运行性能,可以把这两张表的信息整合在一张员工信息表EMPINFO中
步骤一:创建EmpHomeAddress和EmpInfo
package cn.happy.zujian; public class EmpInfo {
private Integer eId;
private String eName;
private EmpHomeAddress eHome; public Integer geteId() {
return eId;
}
public void seteId(Integer eId) {
this.eId = eId;
}
public String geteName() {
return eName;
}
public void seteName(String eName) {
this.eName = eName;
}
public EmpHomeAddress geteHome() {
return eHome;
}
public void seteHome(EmpHomeAddress eHome) {
this.eHome = eHome;
}
}
EmpInfo.java
package cn.happy.zujian; public class EmpHomeAddress {
private String ehomestreet;
private String ehomecity;
private String ehomeprovince;
private String ehomezipcode; private EmpInfo empinfo;
public EmpInfo getEmpinfo() {
return empinfo;
}
public void setEmpinfo(EmpInfo empinfo) {
this.empinfo = empinfo;
}
public String getEhomestreet() {
return ehomestreet;
}
public void setEhomestreet(String ehomestreet) {
this.ehomestreet = ehomestreet;
}
public String getEhomecity() {
return ehomecity;
}
public void setEhomecity(String ehomecity) {
this.ehomecity = ehomecity;
}
public String getEhomeprovince() {
return ehomeprovince;
}
public void setEhomeprovince(String ehomeprovince) {
this.ehomeprovince = ehomeprovince;
}
public String getEhomezipcode() {
return ehomezipcode;
}
public void setEhomezipcode(String ehomezipcode) {
this.ehomezipcode = ehomezipcode;
} }
EmpHomeAddress
<?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="cn.happy.zujian"> <class name="EmpInfo" table="EMPINFO">
<id name="eId" column="EID">
<generator class="sequence">
<param name="sequence">STU_SID</param>
</generator>
</id>
<property name="eName" type="string" column="ENAME"></property> <component name="eHome" class="EmpHomeAddress">
<parent name="empinfo"/>
<property name="ehomestreet" column="EHOMESTREET" type="string"></property>
<property name="ehomecity" column="EHOMECITY" type="string"></property>
<property name="ehomeprovince" column="EHOMEPROVINCE" type="string"></property>
<property name="ehomezipcode" column="EHOMEZIPCODE" type="string"></property>
</component> </class> </hibernate-mapping>
EmpInfo.hbm.xml
步骤二:创建配置文件EmpInfo.hbm.xml
步骤三:书写测试类
package cn.happy.zujian; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import cn.happy.util.HibernateUtil; public class TestInfo {
/**
* 组件映射
* */
@Test
public void zujian(){
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction(); EmpInfo empinfo=new EmpInfo();
empinfo.seteName("回青"); EmpHomeAddress address=new EmpHomeAddress();
address.setEhomecity("北京");
address.setEhomeprovince("北京市");
address.setEhomestreet("成府路");
address.setEhomezipcode("10002");
empinfo.seteHome(address); session.save(empinfo);
tx.commit(); HibernateUtil.closeSession(); }
}
测试代码