職業訓練覚え書き

52日目(Spring Framework10)

HibernateORMの設定方法から昨日のおさらい

今日は少し応用

 

  • 1対1(one-to-one)
  • 多対1(many-to-one)

ER図で少し触れた、テーブル同士の対応関係を扱う


one-to-one

それぞれのテーブルに対応したdomainクラスを作成
Typeクラス(親)
 [フィールド]

  • id
  • name
  • TypeDetail typeDetail※紐づけに必要

 

TypeDetailクラス(子)
 [フィールド]

  • id
  • target
  • description

 

マッピングファイルの用意

①Typeクラスのマッピングファイル 

 one-to-oneタグ 

 name属性の値がtypeDetail

 class属性でTypeDetailの完全修飾クラスを記述する

 

②テーブルとTypeDetailクラスを紐づけるためのマッピングファイル
 generatorタグに親クラスの情報が必要
 <generator class="native">
  <param name="property">types</param>
 </generator>
 ※typesは親クラス


many-to-one

membersテーブル(親)

  • id
  • name
  • type_id

member_types(子)

  • id
  • name

domainクラスの作成

Memberクラス

  • id
  • name
  • MemberType memberType※typeIdではなく、指すのはMemberTypeクラス

MemberTypeクラス

  • id
  • name

one-to-one,many-to-oneどちらも親クラス側に子クラスと紐づけるフィールドを用意する

 

many-to-oneの子クラスのマッピングファイルはこれまでに習ったものと同じ

 

親クラスのマッピングファイル
 many-to-oneタグ
 name属性にmemberType(domainクラスのフィールド変数名)
 column="type_id"※これはmemberテーブルのtype_id

 

(補足)データベースからのデータの取得方法としてFetch Typeというものがあり、LAZY、EAGERという種類があるらしいが基本は記述をしない方針らしい
EAGERは紐づくデータをすべて取得できるが処理がそのぶん重くなり、LAZYは指定したテーブルのみ取得するものとのこと

 

要するに

one-to-one,many-to-oneともに

が必要

 

先日作成した会員一覧のページでmany-to-oneを実践

 

domainクラスのMemberType.javaの作成

  • id
  • name

のフィールド、アクセッサを用意

また、先日作成していたMember.java(domainクラス)の修正

フィールドのtypeIdをMembertype membertype;に変更、アクセッサも併せて変更


次はマッピングファイル
既存のhbm/Member.hbm.xmlの修正
 many-to-oneタグを記述し、
 name属性にmemberType(domainのフィールド)
 column="type_id"

 

MemberTypeのxmlも作成
ほぼMember.javaマッピングファイルの流用
idとnameフィールド以外のpropertyタグは削除
マッピングファイルを増やしたので、Bean定義ファイルのmappingResourcesに追記をする

 

MemberDaoの修正
member.setMemberType(newInfo.getMemberType());

 

listMember.jspの修正
<td><c:out value="${member.memberType.name}" /></td>


memberDaoの.createQuery()で使うHQLを修正
from Member m join fetch m.memberType
※mはエイリアスというらしい


個別表示の修正
<form:select path="memberType.id">

 

ここまでで会員一覧と会員の個別表示ができた。

 

HQL文のよく使うもの

テーブルの全データ取得 getResultList()
IDを指定した単一オブジェクト uniqueResult()

 

検索条件のHQL

HQL文のみ
from Member where age >= :age1 and age < :age2
 ※age1、age2はdomainクラスのフィールド

全体の書き方例
List<Member> memberList = getSession()

.createQuery(from Member where age >= :age1 and age < :age2)

.setParameter(":age1", 20).setParameter(":age2", 30).getResultList();

 

LIMITに相当する取得範囲の限定

 

Query<Member> query

= getSesion().createQuery("from Member", Member.class);
query.setFirstResult(0);
query.setMaxResults(3);

List<Member> members = query.getResultList();

 


ここまでがHibernateORMの学習内容で主に触れた部分

あとはページネーションの実装
これは本当に複雑だった。
まだ消化しきれてないのと、ブログに書くには煩雑すぎるので断念
頭の中が整理できたら書く