`
ssydxa219
  • 浏览: 622260 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

hibernate对象关系的映射

 
阅读更多

hibernate对象之间存在关系,

 

=-=================================================================

 

 

 

一对一(主键关联,和单向的外键关联)

   单向(主键,外键)HusbandWife表,a,主键关联 b,外键关联(wifeparent c,主键关联 d,外键关联(husbandparent

一对一单向外键关联:

annotation@oneToOne  @JoinColumn(name="wifeId")

                    xml     <many-to-one  unique="true"/>
一对一单向主键关联:annotation@PrimaryKeyJoinColumn(name="id",referencedColumnName="id")
                    xml: <one-to-one name="stu" constrained="true"/>

 

 双向(主键,外键)

一对一双向外键关联:

annotation:在husband类中:@oneToOne

              wife类中:@OneToOne(mappedBy="wife")对方为主导,对于一对一双向外键关联必须写mappedBy

                    xml : <many-to-one name="stu" unique="true" column="stuid" not-null="true"/>

                        <one-to-one name="idCard

property-ref="stu"></one-to-one>

               <generator class="foreign">

                        <param name="property">stu</param>

</generator>

一对一双向主键关联:

annotation

@OneToOne

    @PrimaryKeyJoinColumn(name="id",referencedColumnName="id")

 

    @OneToOne(mappedBy="wife")

    @PrimaryKeyJoinColumn(name="id",columnDefinition="id")

a Husbandidwifeid相互关联  bhusband的外键wifeidwifehusbandid

联合主键关联(不重要):

Annotation

    @OneToOne

    @JoinColumns(

        {

            @JoinColumn(name="wifid",referencedColumnName="id"),

            @JoinColumn(name="wifename",referencedColumnName="name")

        }     

    )

   中间表 建立一张中间表

一对一(主键关联,和单向的外键关联)

   单向(主键,外键)HusbandWife表,a,主键关联 b,外键关联(wifeparent c,主键关联 d,外键关联(husbandparent

一对一单向外键关联:

annotation@oneToOne  @JoinColumn(name="wifeId")

                    xml     <many-to-one  unique="true"/>
一对一单向主键关联:annotation@PrimaryKeyJoinColumn(name="id",referencedColumnName="id")
                    xml: <one-to-one name="stu" constrained="true"/>

 

 双向(主键,外键)

一对一双向外键关联:

annotation:在husband类中:@oneToOne

              wife类中:@OneToOne(mappedBy="wife")对方为主导,对于一对一双向外键关联必须写mappedBy

                    xml : <many-to-one name="stu" unique="true" column="stuid" not-null="true"/>

                        <one-to-one name="idCard

property-ref="stu"></one-to-one>

               <generator class="foreign">

                        <param name="property">stu</param>

</generator>

一对一双向主键关联:

annotation

@OneToOne

    @PrimaryKeyJoinColumn(name="id",referencedColumnName="id")

 

    @OneToOne(mappedBy="wife")

    @PrimaryKeyJoinColumn(name="id",columnDefinition="id")

a Husbandidwifeid相互关联  bhusband的外键wifeidwifehusbandid

联合主键关联(不重要):

Annotation

    @OneToOne

    @JoinColumns(

        {

            @JoinColumn(name="wifid",referencedColumnName="id"),

            @JoinColumn(name="wifename",referencedColumnName="name")

        }     

    )

   中间表 建立一张中间表

  一对多

   单向:

annotation在一的一方加集合(Set),这种处理方式,hibernate把它当做了多对多关系处理,在数据库中建立了一张关系表。

    @OneToMany

    @JoinColumn(name="groupid")

    public Set<User> getUsers() {

       return users;

    }

    public void setUsers(Set<User> users) {

       this.users = users;

    } 

Xml

        <set name="users">

            <key column="groupid"></key>

            <one-to-many class="User"/>

        </set>

   双向(多对一的双向关联,一对多的双向关联是一样的)

多对一:

  单向(manytoone的单向关联):在多的一方加外键。1NF,要有主键,列不可分;2NF联合主键不能存在部分依赖3NF不能存在传递依赖。设计原则:不能产生冗余。

 

     annotation@ManyToOne 

     xml:<many-to-one name="g" column="groupid"></many-to-one>

 

   双向:(多对一的双向关联,一对多的双向关联是一样的)

   Annotation@ManyToOne 

 

   xml:

<set name="aliases" table="person_aliases" order-by="lower(name) asc">
    <key column="person"/>
    <element column="name" type="string"/>
</set>

 

 

 

 

多对多

   单向 

annotation: @ManyToMany

 

xml :

<class name="Person">

    <id name="id" column="personId">

        <generator class="native"/>

    </id>

    <set name="addresses" table="PersonAddress">

        <key column="personId"/>

        <many-to-many column="addressId"

            class="Address"/>

    </set>

</class>

 

<class name="Address">

    <id name="id" column="addressId">

        <generator class="native"/>

    </id>

</class>

 

   双向:

Annotation

/**

 *ManyToMany指明多对多关系

 *JoinTable生成中间表,name指定中间表的名字,joinColumns

 *指定参考这张表的主键的中间表的属性名,inverseJoinColumns

 *指定参考相关表的主键的中间表的属性名。 

 *

 */

    @ManyToMany

    @JoinTable(name="t_t",joinColumns={

           @JoinColumn(name="t_id")

    },inverseJoinColumns={@JoinColumn(name="s_id")})

 

    @ManyToMany(mappedBy="students")

Xml:

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

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

 

<hibernate-mapping package="com.xie.hibernate.modal" >

 

    <class name="Teacher" table="t_teacher">

         <id name="id" column="id">

            <generator class="native"></generator>

         </id>

         <property name="name" column="name"></property>

        <set name="students" table="t_s">

            <key column="t_id"></key>

            <many-to-many column="s_id" class="Student"/>

        </set>

    </class>

</hibernate-mapping>

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

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

 

<hibernate-mapping package="com.xie.hibernate.modal" >

 

    <class name="Student" table="t_student">

         <id name="id" column="id">

            <generator class="native"></generator>

         </id>

         <property name="name" column="name"></property>

         <set name="teachers" table="t_s" inverse="true">

            <key column="s_id"/>

            <many-to-many column="t_id" class="Teacher"/>

         </set>

        

    </class>

</hibernate-mapping>

  

=-=================================================================

该如何映射呢?有3中方式,反映在数据库表上:

Single tableStudentTeacher类的父类是Person类,用一张数据库表反应3个类的所有信息。这样设计的缺点是:表的信息反映了所有类的属性,造成大量的数据冗余。

Table per class:为每个类设计一张表,其缺点是:

Joined:用一张表存共有的字段,而其子类对应的表存其特有字段。优缺点:查询能提高效率,然而需要作表连接,当添加新的子类时,需要添加新的表。

=====================================继承关系的映射=====================================================

Annotation

     sigle_table

package com.xie.hibernate.modal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.sun.xml.internal.bind.v2.runtime.Name;
@Entity
//指定继承映射的策略
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
//在数据库表中加上一个字段,用以区分是哪个子类,name表示表的字段名字,discriminatorType
//表示name字段的数据类型
@DiscriminatorColumn(name="dis",discriminatorType=DiscriminatorType.STRING)
//指定这个类存到数据库中用什么区分,value表明dis的值
@DiscriminatorValue(value="person")
public class Person {
      private int id;
      private String name;
     
      @Id
      @GeneratedValue
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }    
}

package com.xie.hibernate.modal;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@DiscriminatorValue("student")
public class Student extends Person {
 private int score;

 public int getScore() {
  return score;
 }

 public void setScore(int score) {
  this.score = score;
 } 
}

package com.xie.hibernate.modal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@DiscriminatorValue("teacher")
public class Teacher extends Person{
 private String title;

 public String getTitle() {
  return title;
 }

 public void setTitle(String title) {
  this.title = title;
 } 
}

 

 

      ⑵table_per_class

 

package com.xie.hibernate.modal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.TableGenerator;

import com.sun.xml.internal.bind.v2.runtime.Name;
@Entity
//指定继承映射的策略
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@TableGenerator(
  name="k_gen",
        table="key_table",
        pkColumnName="p_key",
        pkColumnValue="p_value",
        initialValue=1,
        allocationSize=1
)
public class Person {
      private int id;
      private String name;
     
      @Id
      @GeneratedValue(generator="k_gen",strategy=GenerationType.TABLE)
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }    
}

 

package com.xie.hibernate.modal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
public class Teacher extends Person{
 private String title;

 public String getTitle() {
  return title;
 }

 public void setTitle(String title) {
  this.title = title;
 } 
}

 

 

      ⑶joined

 

package com.xie.hibernate.modal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.TableGenerator;

import com.sun.xml.internal.bind.v2.runtime.Name;
@Entity
//指定继承映射的策略
@Inheritance(strategy=InheritanceType.JOINED)

public class Person {
      private int id;
      private String name;
     
      @Id
      @GeneratedValue
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }    
}

 

package com.xie.hibernate.modal;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
public class Student extends Person {
 private int score;

 public int getScore() {
  return score;
 }

 public void setScore(int score) {
  this.score = score;
 } 
}

 

package com.xie.hibernate.modal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
public class Teacher extends Person{
 private String title;

 public String getTitle() {
  return title;
 }

 public void setTitle(String title) {
  this.title = title;
 } 
}

 

===============================hibernate n+1==========================

 

 在多对一关系中,当我们需要查询多的一方对应的表的记录时,可以用一条sql语句就能完成操作。然而,在多的一方的实体类中的@ManyToOne标注的fetch的默认值是eager,这时,hibernate除了发出查询多的一方对应的表的记录的sql语句外,还会发出n(多方记录数)条sql语句,这就是1+n问题。如:bbs的板块(Category),主题(topic),回复(msg)。一个板块有多个主题,而一个主题属于一个板块,则Categorytopic属于一对多的关系,在topic里设置@ManyToOne。当需要取出所有的主题时,只需要发出select * from topic一条语句就能做到。然而,hibernate会查询出每个topic所对应的Category,所以会发出1+nsql语句。

 

解决的方法是:设置@ManyToOnefetch属性值为lasy,这种方式解决后,后面的nsql语句按需而发。

设置@BatchSize(size=5),这样发出的sql语句减少。这个设置在一定程度上提高了效率。

join fetch,事实上Criteria用的就是这种方法。

 

 

 

    //join fetch

    @Test

    public void test1_N3(){

       Session session=sf.getCurrentSession();

       session.beginTransaction();

       //List<Topic> topics=(List<Topic>)session.createCriteria(Topic.class).list();

       List<Topic> topics=(List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list();

       for (Topic t:topics) {

           System.out.println(t.getId()+"----"+t.getTitle());

           System.out.println(t.getCategory().getName());

       }

      

       session.getTransaction().commit();

      

  }

 

========================================================================

nativeSQL(本地sql,功能强大)>HQL>EJBQL(是hql的子集)>QBC(query by cretra,cretra接口查询)>QBE 

 

 

 

============================================================

 

===============================hibernate n+1  over=========================

 

分享到:
评论

相关推荐

    Hibernate对象关系映射

    Hibernate对象关系映射一对多 很基础等文档

    hibernate对象关系映射实例

    标题“Hibernate对象关系映射实例”表明我们将探讨的是使用Hibernate框架进行对象关系映射(ORM)的实际应用。ORM是将数据库表结构映射为Java类对象的一种技术,它使得开发者可以使用面向对象的方式来操作数据库,而...

    基于Java的Hibernate对象关系映射框架设计源码

    该项目是基于Java的Hibernate对象关系映射框架设计源码,包含11786个文件,其中Java源文件10296个,XML配置文件794个,SQL脚本235个,AsciiDoc文档71个,HTML文件60个,CSS样式表59个,JavaScript脚本59个,属性文件...

    hibernate对象关系映射案例demo

    **hibernate对象关系映射案例demo** 在Java开发领域,对象关系映射(ORM)是一种将数据库中的数据与程序中的对象进行关联的技术,它极大地简化了数据操作。Hibernate作为一款流行的ORM框架,使得开发者无需关注底层...

    Hibernate 对象关系映射

    本人在厦门邦初培训时候用的ppt 快速入门文档 内容: 建立一对多的关联关系域模型 建立一对多的参照关系的模型 映射一对多关联关系 通过hibernateAPI级联操作关联对象 其它关系的映射:一对一,多对多

    基于Java语言的Hibernate对象关系映射技术课程设计源码

    该项目是一个基于Java语言的Hibernate对象关系映射技术课程设计源码,共计48个文件,包括24个JAR包文件、13个XML配置文件、8个Java源文件、2个Git忽略文件以及1个Idea项目文件。该课程设计旨在让学生深入理解对象...

    对象-关系映射—Hibernate 培训 (中文)

    对象-关系映射—Hibernate 培训 (中文) 目录 一、持久化层-O/R Mapping 二、Hibernate入门 三、Hibernate映射申明(Mapping declaration) 四、持久化对象的状态和生命周期 五、Hibernate查询 六、Hibernate最佳...

    hibernate的关系映射

    在Java编程领域,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,将Java对象与数据库表之间的交互转化为简单的API调用。关系映射是Hibernate的核心特性之一,它允许我们将复杂的数据库结构与...

    hibernate关联关系映射

    在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作转换为面向对象的方式,从而简化了数据访问层的编程。"hibernate关联关系映射"是Hibernate的核心概念之一,它定义了如何...

    JAVA数据类型与Hibernate的类型映射

    在Java编程语言中,...这涉及到对Java基本类型、复杂类型以及自定义对象的映射,还包括对数据库NULL值的处理、对象关系映射以及工具的使用策略。熟悉这些知识,可以帮助开发者更高效地利用Hibernate进行数据持久化。

    对象/关系映射

    对象/关系映射 —Hibernate 对象/关系映射 —Hibernate 对象/关系映射 —Hibernate

    hibernate的多种映射关系

    Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,消除了直接编写 SQL 的需要。在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系...

    Hibernate关系映射

    在Java世界中,Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者将数据库操作转化为面向对象的方式,极大地简化了数据持久化的复杂性。"多对一"关系映射是Hibernate支持的四种基本关联类型之一,包括一...

    Hibernate教程09_关系映射之组件映射

    Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,它允许开发人员以面向对象的方式处理数据库操作,极大地简化了数据层的开发。组件映射是Hibernate中的一种高级映射策略,用于将一个类的属性组织成一个...

    Hibernate继承关系映射.pdf

    标题:“Hibernate继承关系映射.pdf” 描述:“简明扼要地介绍了Hibernate中继承关系的映射方式,深入探讨了三种不同的映射策略及其优缺点,同时解析了多态查询的概念。” 知识点: ### Hibernate继承关系映射...

    Hibernate对象关系详解

    **Hibernate对象关系详解** 在Java世界中,Hibernate作为一款强大的对象关系映射(ORM)框架,使得开发者可以方便地在Java对象与数据库表之间进行数据操作。本篇将深入探讨Hibernate中的对象关系映射,包括一对一...

    开源对象关系映射框架Hibernate知识培训

    标题和描述都在强调"开源对象关系映射框架Hibernate知识培训",这意味着主要内容将围绕Hibernate这一框架,探讨如何进行对象关系映射(ORM)以及相关的学习和应用。 **对象关系映射(ORM)** 对象关系映射(Object...

    hibernate中的对象关系映射

    【hibernate中的对象关系映射】是Java开发中一种重要的技术,它允许开发者使用面向对象的方式来处理数据库操作,从而避免了直接与SQL打交道的复杂性。Hibernate是Java领域的一个ORM框架,它提供了数据持久化的解决...

    hibernate map 集合映射

    在Java的持久化框架Hibernate中,集合映射是将数据库中的表关系映射到对象的集合属性上,以便更好地管理和操作数据。这篇文章将深入探讨Hibernate中的集合映射机制,包括其基本概念、类型以及如何在实际开发中进行...

Global site tag (gtag.js) - Google Analytics