Hibernate中one-to-one的深入学习

原创 2005年04月23日 17:51:00

题记:Hibernate是个好东西,可我感觉这个好东东不好驾御,一个one-to-one就让我花费了很多时间,现在终于有点理解,所以想给大家分享分享我的观点,如有差错,还请各位批评指正!

1.关于one-to-one

    持久化对象之间一对一的关联关系是通过one-to-one元素定义:

<one-to-one
        name="propertyName"                                (1)
        class="ClassName"                                  (2)
        cascade="all|none|save-update|delete"              (3)
        constrained="true|false"                           (4)
        outer-join="true|false|auto"                       (5)
        property-ref="propertyNameFromAssociatedClass"     (6)
        access="field|property|ClassName"                  (7)
        
/>
(1)

name: 属性的名字[POJO中的]。

(2)

class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。

(3)

cascade(级联) (可选) 表明操作是否从父对象级联到被关联的对象。

(4)

constrained(约束) (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。这个选项影响save()delete()在级联执行时的先后顺序(也在schema export tool中被使用)。

(5)

outer-join(外连接) (可选 - 默认为 自动): 当设置hibernate.use_outer_join的时候,对这个关联允许外连接抓取。

(6)

property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键[POJO中POJO类的实例]。

(7)

access (可选 - 默认是 property): Hibernate用来访问属性的策略。

2.one-to-one分类

主键关联

惟一外键关联

主键关联不需要额外的表字段;两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!

另一种方式是一个外键和一个惟一关键字对应。

3.one-to-one中惟一外键关联操作

(1)数据库DDL

#
# Table structure for table 'author'
#

CREATE TABLE author (
  author_id char(20) NOT NULL default '',
  person_id char(20) default NULL,
  PRIMARY KEY  (author_id)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;

#
# Table structure for table 'person'
#

CREATE TABLE person (
  person_id char(20) NOT NULL default '',
  name char(20) default NULL,
  PRIMARY KEY  (person_id)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;

(2)映射文件

Author.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 Sat Apr 23 14:28:37 CST 2005                         -->
<hibernate-mapping package="po">

    <class name="Author" table="author">
        <id name="authorId" column="author_id" type="java.lang.String">
            <generator class="assigned"/>
        </id>
       
        <many-to-one
   cascade="all"
   class="po.Person"
   column="person_id"
   name="person"
   not-null="true"
   outer-join="auto"
   unique="true"
   />
       
    </class>
   
</hibernate-mapping>

Person.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 Sat Apr 23 14:28:39 CST 2005                         -->
<hibernate-mapping package="po">

    <class name="Person" table="person">
        <id name="personId" column="person_id" type="java.lang.String">
            <generator class="assigned"/>
        </id>
 
        <property name="name" column="name" type="java.lang.String" />
       
        <one-to-one name="author" class="Author" property-ref="person"/>
       
    </class>
   
</hibernate-mapping>

(2)POJO文件

AbstractAuthor.java

package po;

import java.io.Serializable;

public abstract class AbstractAuthor
    implements Serializable
{
    /** The cached hash code value for this instance.  Settting to 0 triggers re-calculation. */
    private int hashValue = 0;

    /** The composite primary key value. */
    private java.lang.String authorId;

    /** The value of the simple personId property. */
    private java.lang.String personId;

    /**
     * Simple constructor of AbstractAuthor instances.
     */
    public AbstractAuthor()
    {
    }

    /**
     * Constructor of AbstractAuthor instances given a simple primary key.
     * @param authorId
     */
    public AbstractAuthor(java.lang.String authorId)
    {
        this.setAuthorId(authorId);
    }

    /**
     * Return the simple primary key value that identifies this object.
     * @return java.lang.String
     */
    public java.lang.String getAuthorId()
    {
        return authorId;
    }

    /**
     * Set the simple primary key value that identifies this object.
     * @param authorId
     */
    public void setAuthorId(java.lang.String authorId)
    {
        this.hashValue = 0;
        this.authorId = authorId;
    }

    /**
     * Return the value of the person_id column.
     * @return java.lang.String
     */
    public java.lang.String getPersonId()
    {
        return this.personId;
    }

    /**
     * Set the value of the person_id column.
     * @param personId
     */
    public void setPersonId(java.lang.String personId)
    {
        this.personId = personId;
    }

    /**
     * Implementation of the equals comparison on the basis of equality of the primary key values.
     * @param rhs
     * @return boolean
     */
    public boolean equals(Object rhs)
    {
        if (rhs == null)
            return false;
        if (! (rhs instanceof Author))
            return false;
        Author that = (Author) rhs;
        if (this.getAuthorId() != null && that.getAuthorId() != null)
        {
            if (! this.getAuthorId().equals(that.getAuthorId()))
            {
                return false;
            }
        }
        return true;
    }

    /**
     * Implementation of the hashCode method conforming to the Bloch pattern with
     * the exception of array properties (these are very unlikely primary key types).
     * @return int
     */
    public int hashCode()
    {
        if (this.hashValue == 0)
        {
            int result = 17;
            int authorIdValue = this.getAuthorId() == null ? 0 : this.getAuthorId().hashCode();
            result = result * 37 + authorIdValue;
            this.hashValue = result;
        }
        return this.hashValue;
    }
}

Author.java

package po;

import java.io.Serializable;

public class Author
    extends AbstractAuthor
    implements Serializable
{
    private Person person;
 
 /**
     * Simple constructor of Author instances.
     */
    public Author()
    {
    }

    /**
     * Constructor of Author instances given a simple primary key.
     * @param authorId
     */
    public Author(java.lang.String authorId)
    {
        super(authorId);
    }

    /* Add customized code below */
 public void setPerson(Person person){
  this.person=person;
 }
 public Person getPerson(){
  return person;
 }

}

AbstractPerson.java

package po;

import java.io.Serializable;

public abstract class AbstractPerson
    implements Serializable
{
    /** The cached hash code value for this instance.  Settting to 0 triggers re-calculation. */
    private int hashValue = 0;

    /** The composite primary key value. */
    private java.lang.String personId;

    /** The value of the simple name property. */
    private java.lang.String name;

    /**
     * Simple constructor of AbstractPerson instances.
     */
    public AbstractPerson()
    {
    }

    /**
     * Constructor of AbstractPerson instances given a simple primary key.
     * @param personId
     */
    public AbstractPerson(java.lang.String personId)
    {
        this.setPersonId(personId);
    }

    /**
     * Return the simple primary key value that identifies this object.
     * @return java.lang.String
     */
    public java.lang.String getPersonId()
    {
        return personId;
    }

    /**
     * Set the simple primary key value that identifies this object.
     * @param personId
     */
    public void setPersonId(java.lang.String personId)
    {
        this.hashValue = 0;
        this.personId = personId;
    }

    /**
     * Return the value of the name column.
     * @return java.lang.String
     */
    public java.lang.String getName()
    {
        return this.name;
    }

    /**
     * Set the value of the name column.
     * @param name
     */
    public void setName(java.lang.String name)
    {
        this.name = name;
    }

    /**
     * Implementation of the equals comparison on the basis of equality of the primary key values.
     * @param rhs
     * @return boolean
     */
    public boolean equals(Object rhs)
    {
        if (rhs == null)
            return false;
        if (! (rhs instanceof Person))
            return false;
        Person that = (Person) rhs;
        if (this.getPersonId() != null && that.getPersonId() != null)
        {
            if (! this.getPersonId().equals(that.getPersonId()))
            {
                return false;
            }
        }
        return true;
    }

    /**
     * Implementation of the hashCode method conforming to the Bloch pattern with
     * the exception of array properties (these are very unlikely primary key types).
     * @return int
     */
    public int hashCode()
    {
        if (this.hashValue == 0)
        {
            int result = 17;
            int personIdValue = this.getPersonId() == null ? 0 : this.getPersonId().hashCode();
            result = result * 37 + personIdValue;
            this.hashValue = result;
        }
        return this.hashValue;
    }
}

Person.java
package po;

import java.io.Serializable;

public class Person
    extends AbstractPerson
    implements Serializable
{
    private Author author;
 /**
     * Simple constructor of Person instances.
     */
    public Person()
    {
    }

    /**
     * Constructor of Person instances given a simple primary key.
     * @param personId
     */
    public Person(java.lang.String personId)
    {
        super(personId);
    }

    /* Add customized code below */
 public void setAuthor(Author author){
  this.author=author;
 }
 public Author getAuthor(){
  return author;
 }

}

(3)测试文件

TestOO.java

package test;

import po.Author;
import po.Person;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;


public class TestOO {
 
 private Session sesssion=null;

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  try {
       Configuration cfg = new Configuration().configure();
       SessionFactory sessions = cfg.buildSessionFactory();
       Session session = sessions.openSession();
       Transaction tx = session.beginTransaction();
      
       Person person = new Person();
         
       person.setPersonId("1");
    person.setName("Blake Stone");
         
       Author author = new Author();

       author.setAuthorId("11");
    author.setPerson(person);

       
   session.save(person);
   session.save(author);

   System.out.print("i will dead if i don't get success!");
     
       tx.commit();
      session.close();
     } catch (Exception e) {
      System.out.println(e);
     }
   }
}

(4)分享喜悦

     运行测试类,数据正常添加进数据库。

(5)深入探讨

     a.由于主键采用assigned方式,必须自己指定ID;

    b.如果只采用session.save(author);将会产生级联错误[ Could not synchronize database state with session             net.sf.hibernate.HibernateException: Batch update row count wrong: 0],看看执行的SQL语句[Hibernate: insert into author (person_id, author_id) values (?, ?)   Hibernate: update person set name=? where person_id=?]很明白是吧,因为person表还是空的,当然执行update操作会失败!虽然解决的方法很简单,可问题值得思考!虽然对person进行了setter方法,可不要忘了他仍旧是VO而不是PO!



版权声明:本文为博主原创文章,未经博主允许不得转载。

hibernate映射文件one-to-one元素属性

one-to-one 元素属性:name:映射类属性的名字class:映射的目标类cascade:设置操作中的级联策略 可选值为 all所有操作情况均进行级联、none所有操作情况均不进行级联、sav...
  • qwerasdf123
  • qwerasdf123
  • 2010年11月15日 10:34
  • 10625

Hibernate One-To-One 关联

现实生活中,一对一(One To One)关系的实体比比皆是。比如,人和身份证的关系,人和社会属性的关系等。 在Hibernate中,OneToOne关系分为两种策略:主键关联和唯一外键关联。主键关联...
  • chenjie19891104
  • chenjie19891104
  • 2011年03月15日 14:26
  • 3428

Hibernate one-to-one一对一映射

 hibernate 关系映射 one-to-one主要有三种实现方式 1.通过外键方式实现 以学生和电脑为例(Student-Computer) 建表sql语句: Java代码 CREATE DAT...
  • scorpio3k
  • scorpio3k
  • 2009年03月13日 12:40
  • 26603

深入学习Hibernate4_01 Hibernate简介(是什么?为什么)

很开心,今天重新学习Hibernate,其实也不算重新学习,算是Hibernate进阶吧,因为之前学习的版本是3,现在学习的版本是4,两者还是有些不同。闲话少说,进入正题。 学习一门技术,我常常...
  • sinat_35598260
  • sinat_35598260
  • 2017年06月03日 18:08
  • 306

【SSH快速进阶】——Hibernate一对一映射(one-to-one)——唯一外键关联

接着上篇文章,唯一外键关联,就是给一对一关联关系中某个对象加一个外键。比如这里给t_person表添加一个外键,指向t_idcard的主键,并且规定t_person中的外键idCard唯一,也可以达到...
  • huyuyang6688
  • huyuyang6688
  • 2015年12月11日 11:31
  • 3020

hibernate 4.O 注解 one-to-one 异常

Caused by: java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/...
  • mexican_jacky
  • mexican_jacky
  • 2015年04月06日 23:30
  • 2243

【SSH快速进阶】——Hibernate一对一映射(one-to-one)——主键关联映射

在Hibernate中实现一对一映射,有两种实现方式:1、主键关联;2、唯一外键关联,这里先说一下主键关联映射。   主键关联映射:其中一个表的主键依赖于另一张表的主键而建立起的一对一的关系,这两张互...
  • huyuyang6688
  • huyuyang6688
  • 2015年12月10日 16:50
  • 2046

深入理解Hibernate

映射一对多关联关系一对多双向关联关系映射例子 用户与订单关系 customer表和order表 order表有个一个字段是customerid那么在用户的entity中就存在一个set来存放订单...
  • chenjianandiyi
  • chenjianandiyi
  • 2016年09月16日 18:07
  • 751

(**)hibernate中基于主键和基于外键的one-to-one

基于主键的单向 1-1       基于主键关联的持久化类不能拥有自己的主键生成器,它的主键由关联类负责生成。      one-to-one:必须为one-to-one元素增加constrain...
  • haojiahj
  • haojiahj
  • 2013年05月21日 21:40
  • 1512

Follow Me:深入浅出学习Hibernate一:Hibernate概述

花絮              现在编程过程中框架越来越多,框架的好处我们每个人都享受这它的魅力,有了框架我们最受益的是我们在编程过程中的是重用,采用框架统一定义的接口,从而使构件间的通信简单。 ...
  • qiulongtianshi
  • qiulongtianshi
  • 2012年06月04日 07:43
  • 3425
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Hibernate中one-to-one的深入学习
举报原因:
原因补充:

(最多只允许输入30个字)