Hibernate配置の詳細(5)
4658 ワード
9) hibernate.batch_fetchスタイル:
この配置はhibernate 4.2.0が新たに追加されたもので、この設定を使用して、hibernateをbatch-fetchを作成する際にSQLを生成する戦略を設定することができます。この構成項目のオプション値は、org.hibernate.loader.BatFetch Styleという列挙タイプの中の任意の値である。したがって、現在は3つのオプションがあります。レガシー、PADDED、DYNAMIC。それぞれ紹介します。
1,LEGACY:このバッチキャプチャパターンは、予め定義された配列から指定されたマッチングの数を取得して、inの後の疑問符の個数を包装しています。この定義された配列は、org.hibernal.util.co llection s.ArayHelper咻 方法で入手しました。LEGACYもこの設定項目のデフォルト値です。簡単な例を挙げると、データテーブルに39のデータを挿入すると、
hibernate.batch_fetchスタイル リーガル.
テストを実行し、内容を出力する(簡略化してから):
ハイベルナ: プロジェクト employee 0_.id。 as id 1_1_、 employee 0_.name as name 2_1_、 employee 0_.DEPT_ID as DEPT 3_1_ from Employee employee 0_
ハイベルナ: プロジェクト department 0_.id。 as id 1_0_0_、 department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id。 in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:1 はい、 employee:14
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:15 はい、 employee:28
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:28 はい、 employee:38
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id=
employee:39
14ロットを使って2回のデータを取った後、最後のロットのデータ(11個)を一度に取り出したのではなく、それぞれ10+1を使って2回に分けてデータを取りました。原理分析は以下の通りです。
まず設定されたbatch-size=14に基づいて、14を最大のbatch数としてorg.hibernane.internal.util.co llection s.rayHelper佼getBatch Sizes方法に伝え、一つの前処理を得る配列は:[14,10,9,8,7,5,4,2,1]である。つまり、INの後ろに置くことができるロットの数字はこの配列のいずれかの値しかないので、一回目、39>14、最大ロット14、第二次取り、25>14、最大ロット14、第三次取り11<14、だから第二の大きい11>10、10ロットを取り、最後に一つ取ります。
2,PADDED:この方式はLEGACYと同様に、予め定義された配列から指定されたマッチングの個数を取得してinの後ろの疑問符の個数を包装します。この事前定義されている配列はorg.hibernae.internal.util.com.ArayHelper命ŝ 方法によります。LEGACYとは違って、残りの数量が足りない場合、この方法は常に現在のマッチしている量より大きい量を選択します。同じ例では、ロットスタイルを変更します。
hibernate.batchtchアメリカtyle PADDED
テストを実行し、コンソール出力(簡略化後):
ハイベルナ: プロジェクト employee 0_.id as id 1_1_1_ employee 0_.name as name 2_1_ employee 0_.DEPT_ID as DEPT 3_1_ from Employee employee 0_
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:1 employeeへ:14
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:15 employeeへ:28
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:29 employeeまで
PADDEDとLEGACYの違いがよく分かります。PADDEDは3回のロットだけを使ってすべてのデータを取り出しました。
まず設定されたbatch-size=14に基づいて、14を最大のbatch数としてorg.hibernane.internal.util.co llection s.rayHelper佼getBatch Sizes方法に伝え、一つの前処理を得る配列は:[14,10,9,8,7,5,4,2,1]である。つまり、INの後ろに置くことができるロットの数字はこの配列の中のいずれかの値しかないので、第1回取り、39>14、最大ロット14、第2回取り、25>14、最大ロット14、第3回取り11<14、ただし、PADDEDは10大1の数、つまり14を選択し、残りの11つのオブジェクトを14で一括して取り出します。
3,DYNAMIC:数があれば、1ロットを使って全部取り出しますが、設定されたbatch-sizeを超えてはいけません。だから、DYNAMICを使ったら、14+14+14の方式で3回のロットに分けてデータを調べます。
最後に、PADDED+より大きなbatch-sizeを使えばいいと思っている学生もいるかもしれませんが、実はそうではありません。大量に関連データを取得しますので、関連データが大きすぎると、特に大量に集合データを取得すると、結果集が大きくなり、性能も遅くなります。小さいのも慎重に考えるべきです。
この配置はhibernate 4.2.0が新たに追加されたもので、この設定を使用して、hibernateをbatch-fetchを作成する際にSQLを生成する戦略を設定することができます。この構成項目のオプション値は、org.hibernate.loader.BatFetch Styleという列挙タイプの中の任意の値である。したがって、現在は3つのオプションがあります。レガシー、PADDED、DYNAMIC。それぞれ紹介します。
1,LEGACY:このバッチキャプチャパターンは、予め定義された配列から指定されたマッチングの数を取得して、inの後の疑問符の個数を包装しています。この定義された配列は、org.hibernal.util.co llection s.ArayHelper咻 方法で入手しました。LEGACYもこの設定項目のデフォルト値です。簡単な例を挙げると、データテーブルに39のデータを挿入すると、
@Before
public void save() {
for (int i = 0; i < 39; i++) {
Department d = new Department();
d.setName("d" + i);
Employee e=new Employee();
e.setName("e"+i);
e.setDept(d);
Session session = HibernateUtil.getInstance().getSession();
session.beginTransaction();
session.save(d);
session.save(e);
session.getTransaction().commit();
session.close();
}
}
一括取得するには、batch-fetchサイズを14に設定します。@Test
public void testBatchFetch() {
Session session = HibernateUtil.getInstance().getSession();
List emps = session.createQuery("FROM Employee").list();
for (Employee emp : emps) {
System.out.printf("employee:%s belong %s department \r
",
emp.getId(), emp.getDept().getName());
}
session.close();
}
すべてのEmployeeを取得し、Employee対応のDepartmentにアクセスし、一括サイズは14:
hibernate.propertiesファイルに配置する:hibernate.batch_fetchスタイル リーガル.
テストを実行し、内容を出力する(簡略化してから):
ハイベルナ: プロジェクト employee 0_.id。 as id 1_1_、 employee 0_.name as name 2_1_、 employee 0_.DEPT_ID as DEPT 3_1_ from Employee employee 0_
ハイベルナ: プロジェクト department 0_.id。 as id 1_0_0_、 department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id。 in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:1 はい、 employee:14
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:15 はい、 employee:28
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:28 はい、 employee:38
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id=
employee:39
14ロットを使って2回のデータを取った後、最後のロットのデータ(11個)を一度に取り出したのではなく、それぞれ10+1を使って2回に分けてデータを取りました。原理分析は以下の通りです。
まず設定されたbatch-size=14に基づいて、14を最大のbatch数としてorg.hibernane.internal.util.co llection s.rayHelper佼getBatch Sizes方法に伝え、一つの前処理を得る配列は:[14,10,9,8,7,5,4,2,1]である。つまり、INの後ろに置くことができるロットの数字はこの配列のいずれかの値しかないので、一回目、39>14、最大ロット14、第二次取り、25>14、最大ロット14、第三次取り11<14、だから第二の大きい11>10、10ロットを取り、最後に一つ取ります。
2,PADDED:この方式はLEGACYと同様に、予め定義された配列から指定されたマッチングの個数を取得してinの後ろの疑問符の個数を包装します。この事前定義されている配列はorg.hibernae.internal.util.com.ArayHelper命ŝ 方法によります。LEGACYとは違って、残りの数量が足りない場合、この方法は常に現在のマッチしている量より大きい量を選択します。同じ例では、ロットスタイルを変更します。
hibernate.batchtchアメリカtyle PADDED
テストを実行し、コンソール出力(簡略化後):
ハイベルナ: プロジェクト employee 0_.id as id 1_1_1_ employee 0_.name as name 2_1_ employee 0_.DEPT_ID as DEPT 3_1_ from Employee employee 0_
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:1 employeeへ:14
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:15 employeeへ:28
ハイベルナ: プロジェクト department 0_.id as id 1_0_0_ department 0_.name as name 2_0_0_ from Department department 0_ where department 0_.id in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
employee:29 employeeまで
PADDEDとLEGACYの違いがよく分かります。PADDEDは3回のロットだけを使ってすべてのデータを取り出しました。
まず設定されたbatch-size=14に基づいて、14を最大のbatch数としてorg.hibernane.internal.util.co llection s.rayHelper佼getBatch Sizes方法に伝え、一つの前処理を得る配列は:[14,10,9,8,7,5,4,2,1]である。つまり、INの後ろに置くことができるロットの数字はこの配列の中のいずれかの値しかないので、第1回取り、39>14、最大ロット14、第2回取り、25>14、最大ロット14、第3回取り11<14、ただし、PADDEDは10大1の数、つまり14を選択し、残りの11つのオブジェクトを14で一括して取り出します。
3,DYNAMIC:数があれば、1ロットを使って全部取り出しますが、設定されたbatch-sizeを超えてはいけません。だから、DYNAMICを使ったら、14+14+14の方式で3回のロットに分けてデータを調べます。
最後に、PADDED+より大きなbatch-sizeを使えばいいと思っている学生もいるかもしれませんが、実はそうではありません。大量に関連データを取得しますので、関連データが大きすぎると、特に大量に集合データを取得すると、結果集が大きくなり、性能も遅くなります。小さいのも慎重に考えるべきです。