ホームページ  >  記事  >  Java  >  2 種類の Hibernate クラス マッピングの例の詳細な説明

2 種類の Hibernate クラス マッピングの例の詳細な説明

Y2J
Y2Jオリジナル
2017-05-13 11:17:191394ブラウズ

この記事では、主に Hibernate マッピングの基本的なクラス マッピングとオブジェクト リレーショナル マッピングについて詳しく説明します。必要な方は参考にしてください。

ssh を学習していなかったときのことを思い出してください。データベース テーブルを作成するときは、まずデータベース モデリング E-R 図が作成され、次にエンティティ モデルを通じて関係モデルが確立され、その後、対応するテーブルが確立されます。エンティティ間の関係には、1 対 1、1 対多 (または多対 1)、および多対多の 3 つのタイプがあります。ここで、クラスに基づいて対応するテーブルをマップする場合、クラスとマッピング ファイル間の関係を通じてデータベース テーブルをマップすることしかできません。 UML モデリングを学習します。クラス間には 継承、実装、関連付け、依存関係、集約/組み合わせの 5 つの関係があります。これは Hibernate におけるエンティティ クラス間の関係にも当てはまります。コードの実装なので、エンティティ クラスは復習の知識です。

Hibernate の本質はオブジェクト リレーショナル マッピング (Object リレーショナル マッピング) であり、これまではオブジェクト データをデータベースに保存し、追加、削除、変更、クエリなどのタスクを実行していました。今後はリレーションシップを操作するのではなく、テーブルを操作するのではなく、オブジェクトを直接操作します。通常、休止状態の ORM マッピング ファイルには接尾辞 .hbm.xml が付いています。このマッピング ファイルを使用すると、読みやすいだけでなく、手動で変更したり、いくつかのツールを使用してマッピング ドキュメントを生成したりすることもできます。 Hibernate でのマッピングについては以下で紹介します。

以下の図に示すように、Hibernate マッピングの分類。

1 基本クラスマッピング

エンティティクラスに基づいて対応するテーブルを作成するこの単純な関係が Hibernate 基本マッピングです。


User1 エンティティ クラス コードは次のとおりです:



//user实体。 
public classUser1 { 
  //用户编号。 
  private String id; 
  
  //名字。 
  private String name; 
  
  //密码。 
  private String password; 
  
  //创建日期。 
  private Date createTime; 
  
  //失效时间。 
  private Date expireTime; 
  
  public String getId() { 
   return id; 
  } 
  
// publicvoid setId(String id) { 
//  this.id= id; 
// } 
  
  public String getName() { 
   return name; 
  } 
  
  public void setName(String name) { 
   this.name = name; 
  } 
  
  public String getPassword() { 
   return password; 
  } 
  
  public void setPassword(Stringpassword) { 
   this.password = password; 
  } 
  
  public Date getCreateTime() { 
   return createTime; 
  } 
  
  public void setCreateTime(DatecreateTime) { 
   this.createTime = createTime; 
  } 
  
  public Date getExpireTime() { 
   return expireTime; 
  } 
  
  public void setExpireTime(DateexpireTime) { 
   this.expireTime = expireTime; 
  } 
 }

User1.hbm.xml マッピング ファイルは次のとおりです:



<hibernate-mapping package="com.bjpowernode.hibernate"> 
  
  <class name="User1" table="t_user1"> 
   <id name="id"column="user_id" length="32"access="field"> 
     <generator class="uuid" /> 
   </id> 
   <!-- 设置主键不能重复和不能为空的属性. --> 
   <property name="name" length="30"unique="true" not-null="true"/> 
   <property name="password"/> 
   <property name="createTime" type="date" column="create_time"/> 
   <property name="expireTime"/> 
  </class> 
</hibernate-mapping>

User1.hbm を通じて User1 オブジェクトをリレーショナル データベースに変換します。 XML マッピング ファイル テーブル t_user1。


変換結果は以下の通りです:

2 オブジェクトリレーショナルマッピング

2.1 多対一の関連付けマッピング(一方向)

例えば、ユーザーとグループ間の関係は多対 1 の関係であり、複数のユーザーが 1 つのグループに対応します。


エンティティをテーブルにマッピングし、対応するエンティティをテーブルにマッピングします。対応する属性はテーブルのフィールドにマップされます。


多対 1 関連付けマッピングは、多側で関連付けフィールドを維持します。この例では、ユーザー側で関係フィールドが維持されます。


User.hbm.xml ファイル。



<hibernate-mapping package="org.hibernate.auction"> 
  
  <class name="com.bjpowernode.hibernate.User" table="t_user" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
   <many-to-one name="group" column="groupid"cascade="save-update"></many-to-one> 
  </class> 
</hibernate-mapping>

Group.hbm.xml ファイル。



<hibernate-mapping package="org.hibernate.auction"> 
  
  <class name="com.bjpowernode.hibernate.Group" table="t_group"> 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
  </class> 
</hibernate-mapping>

ここで見るコードは *.hbm.mlx コードです。これは、クラス間の関連付けのため、実装中に、あるクラスが別のクラスのプライベート メンバーとして機能するためです。これは、UML モデリングを学習するときです。ここで主に注目するのは、ORM の M、つまり *.hbm.xml ファイルです。


2.2 1 対 1 の関連付けマッピング

1 対 1 の関連付けマッピングは、個人と自宅の住所との関係など、実生活では比較的一般的です。人物オブジェクトを通して。


2.2.1 1 対 1 マッピング (一方向の主キー関連付け)

一方向の 1 対 1 の主キー関連付けは、それらの等しい主キーに依存します。IdCard が表示されます。つまり、t_idCard の主キーが t_Pseron の主キーとして取得されます。

Xml ファイル:



<class name="com.bjpowernode.hibernate.Person"table="t_person" > 
   <id name="id"> 
   <!-- 采用foreign生成策略,foreign会取得关联对象的标识 --> 
     <generator class="foreign" > 
     <!--property指的是关联对象。 --> 
      <param name="property">idCard</param> 
     </generator> 
   </id> 
   <property name="name"/> 
   <!-- 一对一关联映射,主键关联. --> 
   <!-- 
   one-to-one标签指示hibernate如何加载其关联对象,默认根据主键加载. 
   也就是拿到关系字段值,根据对端的主键来加载关联对象. 
   constrained="true",表示当前主键(Person的主键)还是一个外键 . 
   参照了对端的主键(IdCard的主键),也就是会生成外键约束语句. 
   --> 
   <one-to-one name="idCard" constrained="true"/> 
  </class>


<hibernate-mapping package="org.hibernate.auction"> 
  
  <class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="cardNo"/> 
  </class> 
</hibernate-mapping>

1 対 1 の関係は、1 対 1 要素によって定義されます。

2.2.2 1対1マッピング(双方向主キー関連付け)

1対1双方向主キー関連付けと1対1一方向主キー関連付けの違いは以下の通りです。 1 対 1 の一方向の主キーの関連付けは、個人側の idCard で確認できますが、idCard は個人側では確認できません。双方向の関連付けは、その人物が idCard 側でも認識されることを意味します。つまり、 タグを Person.hbm.xml に追加するだけでなく、 を IdCard に追加することもできます。 .hbm.xml ファイル。コードを以下に示します。



<hibernate-mapping package="org.hibernate.auction"> 
  
  <class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="cardNo"/> 
   <one-to-one name="person"/> 
  </class> 
</hibernate-mapping>

2.2.3 1対1マッピング(一方向の一意の外部キー関連付け)

一对一单向唯一外键关联,也就是多对一关联的特例,把多的一端限制为一,就是一对一唯一外键关联。同多对一一样,在一端加入另一端的并采用0f3b36ce07ca4f65616ce0254f1e356f标签,通过unique="true",这样来限制了多的一端为一。
先上代码。

IdCard.hbm.xml


<hibernate-mapping package="org.hibernate.auction"> 
  
  <class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="cardNo"/> 
  </class> 
</hibernate-mapping>

Person.hbm.xml


<hibernate-mapping package="org.hibernate.auction"> 
  
  <class name="com.bjpowernode.hibernate.Person" table="t_person" > 
   <id name="id"> 
   <!-- 采用foreign生成策略,foreign会取得关联对象的标识 --> 
     <generator class="native" /> 
    
   </id> 
   <property name="name"/> 
   <many-to-one name="idCard" unique="true"></many-to-one> 
  
  </class> 
</hibernate-mapping>

图如下所示:

 

在t_pserson端加上一个外键字段idCard,限制idCard的唯一性就是一对一唯一外键关联。

2.2.4 一对一映射(双向唯一外键关联)

一对一唯一外键单向关联我们已经了解了,双向反过来就是在没有的一端加上就可以了。

我们的IdCard.hbm.xml中采用eb3c88118c17ef85b056b8a514885a94标签。


<hibernate-mapping package="org.hibernate.auction"> 
  
  <class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="cardNo"/> 
   <one-to-one name="person" property-ref="idCard"></one-to-one> 
  </class> 
</hibernate-mapping>

而person.hbm.xml同一对一唯一外键单向关联一样。


<class name="com.bjpowernode.hibernate.Person" table="t_person" > 
  <id name="id"> 
  <!-- 采用foreign生成策略,foreign会取得关联对象的标识 --> 
    <generator class="native" /> 
   
  </id> 
  <property name="name"/> 
  <many-to-one name="idCard" unique="true"></many-to-one> 
 
 </class>

 

 

从上述中可以总结出,对于一对一关联映射,主键关联和唯一外键关联单向和双向产生出的表结构是一样的,不同的是在加载的时候不同。也就是一对一双向关联和一对一单向关联的相比,只是改变了一对一关联映射的加载,而没有改变存储。

2.3 一对多关联映射

2.3.1 一对多关联映射(单向)

上面我们介绍了多对一,我们反过来看一对多不就是多对一吗?那还用再进行不同的映射吗?有什么差别吗?一对多和多对一映射原理是一致的,存储是相同的,也就是生成的数据库的表是一样的,他们之间不同的是维护的关系不同。

他们之间不同点是维护的关系不同

  1. 多对一维护的关系是:多指向一的关系,有了此关系,加载多的时候可以将一加载上来。

  2. 一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来。

 

代码如下所示。

Class.hbm.xml


<class name="com.bjpowernode.hibernate.Classes" table="t_Classes" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
   <set name="students"> 
   <!-- 
     <keycolumn="classesid" not-null="true"/> 
   --> 
     <key column="classesid" /> 
     <one-to-many class="com.bjpowernode.hibernate.Student"/> 
   </set> 
  </class>

Students.hbm.xml


<class name="com.bjpowernode.hibernate.Student" table="t_student" > 
   <id name="id"> 
    <generator class="native" /> 
   </id> 
   <property name="name"/> 
 </class>

从班级能看到学生,是班级来维护关系,不是学生来维护关系,学生不知道自己是哪个班,所以在存储学生的时候,班级的代码不知道。为了更新学生是哪个班级的要发出很多update语句来告诉学生是哪个班级的。当我们设置classesid not-null=“true”时,则将无法保存数据,解决办法我们改为双向关联映射。

2.3.2 一对多关联映射(双向)

为了解决一对多单向可能存在的问题,我们采用双向一对多,每一方都能维护对方。

一对多双向关联映射方式:

  1. 在一的一端的集合上采用42538adbdb6240b2b083a000a615d5bd标签,在多的一端加入一个外键。

  2. 在多的一端采用0f3b36ce07ca4f65616ce0254f1e356f的标签

!~注意42538adbdb6240b2b083a000a615d5bd标签和0f3b36ce07ca4f65616ce0254f1e356f标签加入字段保持一致,否则会产生数据混乱。

代码如下所示。


<class name="com.bjpowernode.hibernate.Classes" table="t_Classes" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
   <set name="students" inverse="true"> 
   <!-- 
     <keycolumn="classesid" not-null="true"/> 
   --> 
     <key column="classesid" /> 
     <one-to-many class="com.bjpowernode.hibernate.Student"/> 
   </set> 
  </class>


<class name="com.bjpowernode.hibernate.Student" table="t_student" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
    <many-to-one name="classes"column="classesid"/> 
  </class>

注意:Inverse属性

1、 Inverse中文意思为相反的,反转。在hibernate中inverse可以用在一对多和多对多双向关联上,inverse默认是false,为false的时候表示本端可以维护关系,如果inverse为true,则本端不能维护关系,会交给另一端维护关系,本端失效,所以在一对多关联映射我们通常在多的一端维护关系,让一的一端失效。

2、Inverse是控制方向上的反转,只影响存储。

比较一对多单向和双向映射,从存储结构上看没有什么区别,但是从配置文件上看,一对多双向比一对多单向,一对多双向关联的配置文件中在多的一端的配置文件上存在0f3b36ce07ca4f65616ce0254f1e356f相关配置,即保证多对一的映射。

2.4 多对多关联映射

2.4.1 多对多关联映射(单向)

多对多对象关系映射,需要加入一张新表完成基本映射。如下图所示。

代码。

Role.hbm.xml


<class name="com.bjpowernode.hibernate.Role" table="t_role"> 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
    
  </class>

User.hbm.xml


<class name="com.bjpowernode.hibernate.User" table="t_user" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
     
   <set name="roles" table="t_user_role"> 
     <key column="user_id"/> 
     <many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/> 
   </set> 
  </class>

2.4.2 多对多关联映射(双向)

双向多对多对象关系映射,是两端都能将对方加载上来,双向都需要加上标签映射。
要注意:

  1. 生成中间表名必须一样

  2. 生成中间表字段必须一样

代码如下所示。

Role.hbm.xml


<class name="com.bjpowernode.hibernate.Role" table="t_role"> 
   <id name="id"> 
    <generator class="native" /> 
   </id> 
   <property name="name"/> 
   
   <set name="users" table="t_user_role"> 
    <key column="role_id"/> 
    <many-to-many class="com.bjpowernode.hibernate.User" column="user_id"/> 
   </set> 
 </class>

User.hbm.xml


<class name="com.bjpowernode.hibernate.User"table="t_user" > 
   <id name="id"> 
     <generator class="native" /> 
   </id> 
   <property name="name"/> 
     
   <set name="roles" table="t_user_role"> 
     <key column="user_id"/> 
     <many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/> 
   </set> 
  </class>

区别:单向多对多和双向多对多存储结构没有任何的区别,但他们的映射文件是有区别的,加载过程是不同的。

 3  关系映射总结

综上所述,可以看出,同一类映射,无论是单向还是双向,他们的存储结构是相同的,之所以映射文件不同,是因为加载时不同(在增删改时)。

无论是多对一、一对多、一对一还是多对一,A对B,A就是主动方,A主动想要了解B的情况,这样把B设置到A端。而双向,也就是A对B,A想了解B的信息,而B也想了解A的信息,那就要同时把A设置到B端了。

【相关推荐】

1. 特别推荐“php程序员工具箱”V0.1版本下载

2. Java免费视频教程

3. 阿里巴巴Java开发手册

以上が2 種類の Hibernate クラス マッピングの例の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。