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ともに
- マッピングファイル
- domainクラス
が必要
先日作成した会員一覧のページで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の学習内容で主に触れた部分
あとはページネーションの実装
これは本当に複雑だった。
まだ消化しきれてないのと、ブログに書くには煩雑すぎるので断念
頭の中が整理できたら書く