hibernate一对一映射外键关联
一对一外键关联

外键关联:一个外键和一个主键关联

一﹑确定数据的一对一关联关系

数据脚本

drop database if exists test; 


create database test; 


use test; 


create table company 


( 


 ID int auto_increment not null primary key, 


 companyName varchar(20) not null, 


 addressID int not null 


); 




create table address 


( 


 ID int auto_increment not null primary key, 


 address varchar(20) not null 


);




Address表中的主键ID与company表中的外键addressID构成一对一外键关联关系.

双向关联:可以根据company得到address,也可以根据address得到company,双向关联时需要在company.hbm.xml中配置 <many-to-one unique=”true” name=”address” column=”addressID” cascade=”all”></many-to-one>;在address.hbm.xml中配置<one-to-one name=”company” property-ref=”address”></one-to-one>,property-ref的值应与<many-to-one>中的name属性的值对应,说明company对象是与address对象建立的关联关系.



单向关联:只可以根据company得到address,单向关联时只需在company.hgm.xml中配置<many-to-one unique=”true” name=”address” column=”addressID” cascade=”all”>



二﹑ORM映射

Company表 




package com.guopeng.bo; 




import java.io.Serializable; 


public abstract class AbstractCompany implements Serializable 


{ 


 private int hashValue = 0; 


 private java.lang.Integer id; 


 private java.lang.String companyname; 




private Address address;//address属性用于建立与address的关系 




 public AbstractCompany() 


 { 


 } 


 public AbstractCompany(java.lang.Integer id) 


 { 


 this.setId(id); 


 } 


 public java.lang.Integer getId() 


 { 


 return id; 


 } 


 public void setId(java.lang.Integer id) 


 { 


 this.hashValue = 0; 


 this.id = id; 


 } 


 public java.lang.String getCompanyname() 


 { 


 return this.companyname; 


 } 


 public void setCompanyname(java.lang.String companyname) 


 { 


 this.companyname = companyname; 


 } 


 public boolean equals(Object rhs) 


 { 


 if (rhs == null) 


 return false; 


 if (! (rhs instanceof Company)) 


 return false; 


 Company that = (Company) rhs; 


 if (this.getId() != null && that.getId() != null) 


 { 


 if (! this.getId().equals(that.getId())) 


 { 


 return false; 


 } 


 if(! this.getCompanyname().equals(that.getCompanyname())) 


 { 


 return false; 


 } 


 } 


 return true; 


 } 


 public int hashCode() 


 { 


 if (this.hashValue == 0) 


 { 


 int result = 17; 


 int idValue = this.getId() == null ? 0 : this.getId().hashCode(); 


 result = result * 37 + idValue; 


 idValue = this.getCompanyname() == null ? 0 : this.getCompanyname().hashCode(); 


 result = result * 37 + idValue; 


 this.hashValue = result; 


 } 


 return this.hashValue; 


 } 


 public Address getAddress() { 


 return address; 


 } 


 public void setAddress(Address address) { 


 this.address = address; 


 } 


}




Address表

package com.guopeng.bo; 




import java.io.Serializable; 


public abstract class AbstractAddress implements Serializable 


{ 


 private int hashValue = 0; 


 private java.lang.Integer id; 


 private java.lang.String address; 




private Company company; 


//单向关联时不需要此属性 


 public AbstractAddress() 


 { 


 } 


 public AbstractAddress(java.lang.Integer id) 


 { 


 this.setId(id); 


 } 


 public java.lang.Integer getId() 


 { 


 return id; 


 } 


 public void setId(java.lang.Integer id) 


 { 


 this.hashValue = 0; 


 this.id = id; 


 } 


 public java.lang.String getAddress() 


 { 


 return this.address; 


 } 


 public void setAddress(java.lang.String address) 


 { 


 this.address = address; 


 }oolean equals(Object rhs) 


 { 


 if (rhs == null) 


 return false; 


 if (! (rhs instanceof Address)) 


 return false; 


 Address that = (Address) rhs; 


 if (this.getId() != null && that.getId() != null) 


 { 


 if (! this.getId().equals(that.getId())) 


 { 


 return false; 


 } 


 } 


 return true; 


 } 


 public int hashCode() 


 { 


 if (this.hashValue == 0) 


 { 


 int result = 17; 


 int idValue = this.getId() == null ? 0 : this.getId().hashCode(); 


 result = result * 37 + idValue; 


 this.hashValue = result; 


 } 


 return this.hashValue; 


 } 


 public Company getCompany() { 


 return company; 


 } 


 public void setCompany(Company company) { 


 this.company = company; 


 } 


}




映射XML

Company.hbm.xml 


<?xml version="1.0"?> 


<!DOCTYPE hibernate-mapping PUBLIC 


 "-//Hibernate/Hibernate Mapping DTD 2.0//EN" 


 "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > 




<!-- DO NOT EDIT: This is a generated file that is synchronized --> 


<!-- by MyEclipse Hibernate tool integration. --> 


<!-- Created Mon Jul 24 21:19:07 CST 2006 --> 


<hibernate-mapping package="com.guopeng.bo"> 




 <class name="Company" table="company" batch-size="4" > 


 <id name="id" column="ID" type="java.lang.Integer"> 


 <generator class="native" /> 


 </id> 




 <property name="companyname" column="companyName" 


 type="java.lang.String" not-null="true" /> 




 <!-- 与address中的one-to-one的property-ref属性相对应,property-ref的值应为many-to-one的name属性的值,表明建立了从address对象到company对象的关联--> 


 <many-to-one name="address" class="Address" column="addressID" 


 cascade="all" unique="true"> 


 </many-to-one> 




 </class> 




</hibernate-mapping> 




Address.hbm.xml 


<?xml version="1.0"?> 


<!DOCTYPE hibernate-mapping PUBLIC 


 "-//Hibernate/Hibernate Mapping DTD 2.0//EN" 


 "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > 




<!-- DO NOT EDIT: This is a generated file that is synchronized --> 


<!-- by MyEclipse Hibernate tool integration. --> 


<!-- Created Mon Jul 24 21:18:45 CST 2006 --> 


<hibernate-mapping package="com.guopeng.bo"> 




 <class name="Address" table="address" batch-size="4" > 


 <id name="id" column="ID" type="java.lang.Integer"> 


 <generator class="native" /> 


 </id> 




 <property name="address" column="address" 


 type="java.lang.String" not-null="true" /> 


 <!—如果为单向关联,不用配置<one-to-one>可以把他删除,如果配置了<one-to-one>则address.class里面必须要有company属性 -à 


 <one-to-one name="company" class="Company" 


 property-ref="address"> 


 <!--property-ref="address"与company中的many-to-one 的name属性相对应 --> 


 </one-to-one> 




 </class> 




</hibernate-mapping>




查询数据时,双向关联与单向关联所执行的SQL语句

双向关联

Hibernate: select company0_.ID as x0_0_ from company company0_ 




Hibernate: select company0_.ID as ID1_, company0_.companyName as companyN2_1_, company0_.addressID as addressID1_, address1_.ID as ID0_, address1_.address as address0_ from company company0_ left outer join address address1_ on company0_.addressID=address1_.ID where company0_.ID=? 




Hibernate: select company0_.ID as ID1_, company0_.companyName as companyN2_1_, company0_.addressID as addressID1_, address1_.ID as ID0_, address1_.address as address0_ from company company0_ left outer join address address1_ on company0_.addressID=address1_.ID where company0_.addressID=?



单向关联

Hibernate: select company0_.ID as x0_0_ from company company0_ 




Hibernate: select company0_.ID as ID1_, company0_.companyName as companyN2_1_, company0_.addressID as addressID1_, address1_.ID as ID0_, address1_.address as address0_ from company company0_ left outer join address address1_ on company0_.addressID=address1_.ID where company0_.ID=?



由此可以看出,双向关联要比单向关联多执行一条select语句,因此在实际的应用中,如果没有必要配置双向关联就不要配,以便于提高系统性能.