JPA(標準)の使用:
- @OneToMany関係は、デフォルトで遅延読み込みされます(つまり、fetch = FetchType.LAZYのデフォルト値)。ただし、呼び出す
Entity.getCollection().size()
と遅延読み込みがトリガーされ、すべての子コレクションが取得されます。したがって、とにかくすべて/ほとんどの要素を操作する必要がない限り、かなり遅くなります。注:JPAのすべての(正常な)実装では、これは30,000の個別のクエリを発行しません。結果セットに30,000行を返す1つのクエリを発行します。
- ほとんどの要素が必要な場合、または事前にキャッシュしたい場合は、
@OneToMany(fetch=FetchType.EAGER)
- すべてのオブジェクトを取得せずにデータ統計を取得する一般的な方法は、単にJPQL via
EntityManager.getQuery()/getTypedQuery()/getNamedQuery()
(またはSQL via getNativeQUery()
)を使用することです。これは非常にシンプルでパフォーマンスが高いです。
int empSize = em.createQuery("SELECT SIZE(d.employees) FROM Department d")
.getSingleResult();
OR ALTERNATIVELY
// Pre-compiled query placed against entity class for highest performance
@NamedQueries({
@NamedQuery(name="Department.EmployeeSize",
query="SELECT SIZE(d.employees) FROM Department"),
... // other named queries
})
@Entity
public class Department {
...
}
// Then to use the query:
int empSize = em.createNamedQuery("Department.EmployeeSize", Integer.class)
.getSingleResult();
Map propertiesMap = new HashMap();
// Valid values are ALL, NONE, ENABLE_SELECTIVE, DISABLE_SELECTIVE
propertiesMap.add("javax.persistence.sharedCache.mode", "ENABLE_SELECTIVE");
EntityManagerFactory = Persistence.createEntityManagerFactory("myPUName", propertiesMap);
ALTERNATIVELY use persistence.xml:
<persistence-unit name="EmployeeService">
...
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
</persistence-unit>
次に、レベル2キャッシュに自動的にキャッシュするエンティティをマークします。
@Cacheable(true)
@Entity
public class Employee {
...
}
- 特定のクエリの一部として、キャッシュを動的に構成することもできます
独自のアプローチを使用する(例:休止状態の「Extra-Lazy」コレクション):
- 単にJPQL/SQLクエリを発行するのと同じパフォーマンス
- 数行のコードを保存します(@ org.hibernate.annotations.LazyCollection(EXTRA)アノテーションv @NamedQueryアノテーションと実行)
- 標準ではありません-JPAのトレーニングを受けた開発者はそれについて知りません
- ポータブルではありません-そのベンダーでのみ使用できます。独自の機能から離れて、標準のJPAに向かう業界の傾向があります。多くの異なるJPA実装があります。