一对一外键关联
外键关联:一个外键和一个主键关联
一﹑确定数据的一对一关联关系
数据脚本
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语句,因此在实际的应用中,如果没有必要配置双向关联就不要配,以便于提高系统性能.