~raginggoblin/infolog/infolog

« back to all changes in this revision

Viewing changes to InfologServer/lib/hibernate-distribution-3.3.2.GA/project/documentation/manual/old/ja-JP/src/main/docbook/content/best_practices.xml

  • Committer: Raging Goblin
  • Date: 2013-11-16 16:51:32 UTC
  • Revision ID: raging_goblin-20131116165132-weujnptzc88uy4ah
Mavenized the project, now using shared project InfologSync

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?xml version="1.0" encoding="UTF-8"?>
2
 
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
3
 
 
4
 
<chapter id="best-practices" revision="3">
5
 
    <title>ベストプラクティス</title>
6
 
 
7
 
    <variablelist spacing="compact">
8
 
        <varlistentry>
9
 
            <term>
10
 
            クラスは細かい粒度で書き <literal>&lt;component&gt;</literal> でマッピングしましょう。</term>
11
 
            <listitem>
12
 
                <para>
13
 
                    <literal>street</literal>(通り), <literal>suburb</literal>
14
 
                    (都市), <literal>state</literal>(州), <literal>postcode</literal> 
15
 
                    (郵便番号)をカプセル化する <literal>Address</literal>(住所)クラスを使いましょう。
16
 
                    そうすればコードが再利用しやすくなり、リファクタリングも簡単になります。
17
 
                </para>
18
 
            </listitem>
19
 
        </varlistentry>
20
 
        <varlistentry>
21
 
            <term>
22
 
            永続クラスには識別子プロパティを定義しましょう。</term>
23
 
            <listitem>
24
 
                <para>
25
 
                    Hibernateでは識別子プロパティはオプションですが、
26
 
                    使用すべき理由がたくさんあります。
27
 
                    識別子は「人工的」(生成された、業務的な意味を持たない)
28
 
                    なものにすることをおすすめします。
29
 
                </para>
30
 
            </listitem>
31
 
        </varlistentry>
32
 
        <varlistentry>
33
 
            <term>自然キーを見つけましょう。</term>
34
 
            <listitem>
35
 
                <para>
36
 
                    すべてのエンティティに対して自然キーを見つけて、
37
 
                    <literal>&lt;natural-id&gt;</literal> でマッピングしましょう。
38
 
                    自然キーを構成するプロパティを比較するために、
39
 
                    <literal>equals()</literal> と <literal>hashCode()</literal> を実装しましょう。
40
 
                </para>
41
 
            </listitem>
42
 
        </varlistentry>
43
 
        <varlistentry>
44
 
            <term>クラスのマッピングはそれぞれのクラス専用のファイルに書きましょう。</term>
45
 
            <listitem>
46
 
                <para>
47
 
                     単一の巨大なマッピングドキュメントを使用しないでください。
48
 
                     <literal>com.eg.Foo</literal> クラスなら 
49
 
                     <literal>com/eg/Foo.hbm.xml</literal> ファイルにマッピングしましょう。
50
 
                     このことは、特にチームでの開発に意味があります。
51
 
                </para>
52
 
            </listitem>
53
 
        </varlistentry>
54
 
        <varlistentry>
55
 
            <term>リソースとしてマッピングをロードしましょう。</term>
56
 
            <listitem>
57
 
                <para>
58
 
                    マッピングを、それらがマッピングするするクラスと一緒に配置しましょう。
59
 
                </para>
60
 
            </listitem>
61
 
        </varlistentry>
62
 
        <varlistentry>
63
 
            <term>クエリ文字列を外部に置くことを考えましょう</term>
64
 
            <listitem>
65
 
                <para>
66
 
                    クエリがANSI標準でないSQL関数を呼んでいるなら、これはよいプラクティスです。
67
 
                    クエリ文字列をマッピングファイルへ外出しすればアプリケーションがポータブルになります。
68
 
                </para>
69
 
            </listitem>
70
 
        </varlistentry>
71
 
        <varlistentry>
72
 
            <term>バインド変数を使いましょう。</term>
73
 
            <listitem>
74
 
                <para>
75
 
                     JDBCの場合と同じように、定数でない値は必ず"?"で置き換えましょう。
76
 
                     定数でない値をバインドするために、クエリで文字列操作を使ってはいけません。
77
 
                     名前付きのパラメータを使うようにするとさらに良いです。
78
 
                </para>
79
 
            </listitem>
80
 
        </varlistentry>
81
 
        <varlistentry>
82
 
            <term>JDBCコネクションを管理してはいけません。</term>
83
 
            <listitem>
84
 
                <para>
85
 
                    HibernateではアプリケーションがJDBCコネクションを管理することが許されています。
86
 
                    しかしこれは最終手段だと思ってください。
87
 
                    組み込みのコネクションプロバイダを使うことができなければ、
88
 
                    <literal>org.hibernate.connection.ConnectionProvider</literal> を実装することを考えてください。
89
 
                </para>
90
 
            </listitem>
91
 
        </varlistentry>
92
 
        <varlistentry>
93
 
            <term>カスタム型の使用を考えましょう。</term>
94
 
            <listitem>
95
 
                <para>
96
 
                    あるライブラリから持ってきたJava型を永続化する必要があるとしましょう。
97
 
                    しかしその型には、コンポーネントとしてマッピングするために必要なアクセサがないとします。
98
 
                    このような場合は <literal>org.hibernate.UserType</literal> の実装を考えるべきです。
99
 
                    そうすればHibernate型との実装変換を心配せずにアプリケーションのコードを扱えます。
100
 
                </para>
101
 
            </listitem>
102
 
        </varlistentry>
103
 
        <varlistentry>
104
 
            <term>ボトルネックを解消するにはJDBCをハンドコードしましょう。</term>
105
 
            <listitem>
106
 
                <para>
107
 
                    システムのパフォーマンスクリティカルな領域では、
108
 
                    ある種の操作にJDBCを直接使うと良いかもしれません。
109
 
                    しかし何がボトルネックになっているか <emphasis>はっきりする</emphasis> までは待ってください。
110
 
                    またJDBCを直接使うからといって、必ずしも速くなるとは限らないことも理解してください。
111
 
                    JDBCを直接使う必要があれば、Hibernateの <literal>Session</literal> をオープンして、
112
 
                    JDBCコネクションを使うと良いかもしれません。
113
 
                    依然として同じトランザクション戦略とコネクションプロバイダが使えるからです。
114
 
                </para>
115
 
            </listitem>
116
 
        </varlistentry>
117
 
        <varlistentry>
118
 
            <term><literal>Session</literal> のフラッシュを理解しましょう。</term>
119
 
            <listitem>
120
 
                <para>
121
 
                    Sessionが永続状態をデータベースと同期させることがときどきあります。
122
 
                    しかしこれがあまりに頻繁に起こるようだと、パフォーマンスに影響が出てきます。
123
 
                    自動フラッシュを無効にしたり、特定のトランザクションのクエリや操作の順番を変更することで、
124
 
                    不必要なフラッシュを最小限にできます。
125
 
                </para>
126
 
            </listitem>
127
 
        </varlistentry>
128
 
        <varlistentry>
129
 
            <term>3層アーキテクチャでは分離オブジェクトの使用を考えましょう。</term>
130
 
            <listitem>
131
 
                <para>
132
 
                    サーブレット / セッションビーンアーキテクチャを使うとき、
133
 
                    サーブレット層 / JSP層間でセッションビーンでロードした永続オブジェクトをやり取りできます。
134
 
                    その際リクエストごとに新しいSessionを使ってください。
135
 
                    また <literal>Session.merge()</literal> や <literal>Session.saveOrUpdate()</literal> 
136
 
                    を使って、オブジェクトとデータベースを同期させてください。
137
 
                </para>
138
 
            </listitem>
139
 
        </varlistentry>
140
 
        <varlistentry>
141
 
            <term>2層アーキテクチャでは長い永続コンテキストの使用を考えましょう。</term>
142
 
            <listitem>
143
 
                <para>
144
 
                    最高のスケーラビリティを得るには、
145
 
                    データベーストランザクションをできるだけ短くしなければなりません。
146
 
                    しかし長い間実行する <emphasis>アプリケーショントランザクション</emphasis> 
147
 
                    の実装が必要なことはしばしばです。
148
 
                    これはユーザの視点からは1個の作業単位(unit of work)になります。
149
 
                    アプリケーショントランザクションはいくつかのクライアントのリクエスト/レスポンスサイクルにまたがります。
150
 
                    アプリケーショントランザクションの実装に分離オブジェクトを使うのは一般的です。
151
 
                    
152
 
                    そうでなければ、2層アーキテクチャの場合は特に適切なことですが、
153
 
                    アプリケーショントランザクションのライフサイクル全体に対して
154
 
                    単一のオープンな永続化コンテキスト(セッション)を維持してください。
155
 
                    そして単純にリクエストの最後にJDBCコネクションから切断し、
156
 
                    次のリクエストの最初に再接続します。
157
 
                    
158
 
                    決して複数のアプリケーショントランザクションユースケースに渡って
159
 
                    1個のSessionを使い回さないでください。
160
 
                    そうでなければ、古いデータで作業することになります。
161
 
                </para>
162
 
            </listitem>
163
 
        </varlistentry>
164
 
        <varlistentry>
165
 
            <term>例外を復帰可能なものとして扱ってはいけません。</term>
166
 
            <listitem>
167
 
                <para>
168
 
                    これは「ベスト」プラクティス以上の、必須のプラクティスです。
169
 
                    例外が発生したときは <literal>Transaction</literal> をロールバックして、
170
 
                    <literal>Session</literal> をクローズしてください。
171
 
                    そうしないとHibernateはメモリの状態が永続状態を正確に表現していることを保証できません。
172
 
                    この特別な場合として、与えられた識別子を持つインスタンスがデータベースに存在するかどうかを判定するために、
173
 
                    <literal>Session.load()</literal> を使うことはやめてください。
174
 
                    その代わりに <literal>Session.get()</literal> かクエリを使ってください。
175
 
                </para>
176
 
            </listitem>
177
 
        </varlistentry>
178
 
        <varlistentry>
179
 
            <term>関連にはなるべく遅延フェッチを使いましょう。</term>
180
 
            <listitem>
181
 
                <para>
182
 
                    即時フェッチは控えめにしましょう。
183
 
                    二次キャッシュには完全に保持されないようなクラスの関連には、
184
 
                    プロキシと遅延コレクションを使ってください。
185
 
                    キャッシュされるクラスの関連、つまりキャッシュがヒットする可能性が非常に高い関連は、
186
 
                    <literal>lazy="false"</literal> で積極的なフェッチを明示的に無効にしてください。
187
 
                    結合フェッチが適切な特定のユースケースには、
188
 
                    クエリで <literal>left join fetch</literal> を使ってください。
189
 
                </para>
190
 
            </listitem>
191
 
        </varlistentry>
192
 
        <varlistentry>
193
 
            <term>
194
 
                フェッチされていないデータに関わる問題を避けるために、
195
 
                <emphasis>ビューの中でオープンセッションを使う(open session in view)</emphasis> 
196
 
                パターンか、統制された <emphasis>組み立てフェーズ(assembly phase)</emphasis> を使いましょう。
197
 
            </term>
198
 
            <listitem>
199
 
                <para>
200
 
                    Hibernateは <emphasis>Data Transfer Objects</emphasis> (DTO)を書く退屈な作業から開発者を解放します。
201
 
                    伝統的なEJBアーキテクチャではDTOは二つ目的があります:
202
 
                    1つ目は、エンティティビーンがシリアライズされない問題への対策です。
203
 
                    2つ目は、プレゼンテーション層に制御が戻る前に、
204
 
                    ビューに使われるすべてのデータがフェッチされて、DTOに復元されるような組み立てフェーズを暗黙的に定義します。
205
 
                    Hibernateでは1つ目の目的が不要になります。
206
 
                    しかしビューのレンダリング処理の間、永続コンテキスト(セッション)をオープンにしたままにしなければ、
207
 
                    組み立てフェーズはまだ必要です(分離オブジェクトの中のどのデータが利用可能かについて、
208
 
                    プレゼンテーション層と厳密な取り決めをしているビジネスメソッドを考えてみてください)。
209
 
                    これはHibernate側の問題ではありません。
210
 
                    トランザクション内で安全にデータアクセスするための基本的な要件です。
211
 
                </para>
212
 
            </listitem>
213
 
        </varlistentry>
214
 
        <varlistentry>
215
 
            <term>Hibernateからビジネスロジックを抽象化することを考えましょう。</term>
216
 
            <listitem>
217
 
                <para>
218
 
                    インターフェイスで(Hibernateの)データアクセスコードを隠蔽しましょう。
219
 
                    <emphasis>DAO</emphasis> と <emphasis>Thread Local Session</emphasis> パターンを組み合わせましょう。
220
 
                    <literal>UserType</literal> でHibernateに関連付けると、
221
 
                    ハンドコードしたJDBCで永続化するクラスを持つこともできます。
222
 
                    (このアドバイスは「十分大きな」アプリケーションに対してのものです。
223
 
                    テーブルが5個しかないようなアプリケーションには当てはまりません。)
224
 
                </para>
225
 
            </listitem>
226
 
        </varlistentry>
227
 
        <varlistentry>
228
 
            <term>珍しい関連マッピングは使わないようにしましょう。</term>
229
 
            <listitem>
230
 
                <para>
231
 
                    よいユースケースに本当の多対多関連があることは稀(まれ)です。
232
 
                    ほとんどの場合「リンクテーブル」の付加的な情報が必要になります。
233
 
                    この場合、リンククラスに2つの1対多関連を使う方がずっと良いです。
234
 
                    実際ほとんどの場合関連は1対多と多対1なので、
235
 
                    他のスタイルの関連を使うときは本当に必要かどうかを考えてみてください。
236
 
                </para>
237
 
            </listitem>
238
 
        </varlistentry>
239
 
        <varlistentry>
240
 
            <term>なるべく双方向関連にしましょう。</term>
241
 
            <listitem>
242
 
                <para>
243
 
                    単方向関連は双方向に比べて検索が難しくなります。
244
 
                    大きなアプリケーションでは、
245
 
                    ほとんどすべての関連が双方向にナビゲーションできなければなりません。
246
 
                </para>
247
 
            </listitem>
248
 
        </varlistentry>
249
 
    </variablelist>
250
 
 
251
 
</chapter>
252