一对一外键关联

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

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

数据脚本

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语句,因此在实际的应用中,如果没有必要配置双向关联就不要配,以便于提高系统性能.