2016-04-30 9 views
1

だから、私は私のentitesの一つでOneToManyの関係を持っている:パフォーマンスの良いJPAエンティティでラムダ式を使用できますか?

私はいくつかの基準によってに基づいてこれらの「結果」の内部に含まれるオブジェクトを取得したい
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.LAZY) 
@OrderBy("priority") 
    private List<Result> results 

:「

Stream<Item> itemsToReturn = results.stream().filter(result -> result.getPriority() > 5) 
       .map(Result::getItem) 
       .filter(/*some filtering logic*/) 
       .limit(numberOfItems); 

それはdoesnのを私はすべてのアイテムがフィルタリングと制限にもかかわらずすべてのフィルタリングが行われる前にメモリにロードされると思うので、非常に効果的であるようです。

私の前提は正しいですか?もしそうなら、私はこのエンティティでラムダを使用できるように何かをすることができますか、またはこれらのアイテムを取得するJPAクエリを記述する必要がありますか?

JPAでラムダを使用することはできますか?

+1

@Sleimanが示しているように、これはおそらく非常に高価な操作です。なぜ部分が単純な線形検索で句を行うために組み込まれたデータベースを置き換えるのですか?もし私がそれを見直すのが私の責任であれば、私はこのコードを拒絶するだろう。 – stdunbar

答えて

3

結果が良いかどうかは、結果セットの大きさによって異なります。しかし、コードを実行するときに何が起こるかを知ることは価値があります。

  1. フルスキャンは、テーブル全体のデータがリニアスキャン
  2. 結果セット全体がJVMメインメモリにロードされる
  3. ネットワークワイヤ上を走行するDBテーブル
  4. 上で実行されますストリーム上でファイラーを実行すると結果全体で実行されます。

上記のコードは、for-loopの古いファッションと変わりありません。

2

JPAエンティティは、プレーンフィールド、コレクション、取得/設定メソッドなどを含むPOJOクラスである必要があります。すべてのロジックをDAOクラスに移動することをお勧めします。

あなたの質問に答える:JPAには既に十分な速さで動作するフィルタリング(別名Criteria API)があります。ほとんどの場合、フィルタリングのためにラムダを使用する必要はありません。

0

Jinqを使用すると、問合せにラムダを使用でき、JPAを使用したJavaでも良好なデータベース・パフォーマンスを得ることができます。

JinqはC#のLinqに似ているので、ラムダクエリはSQL(JPQL)に変換され、他のクエリと同様にデータベースによって実行されます。これらはJavaによって実行されません。

List<Item> items = jinq.users() 
    .where(user -> user.getId() == someId) 
    .selectAllList(user -> user.getItems())  // <- a very simple type of join 
    .where(item -> item.getPriority() > 5) 
    .where(item -> /*some more filtering logic*/) 
    .limit(numberOfItems) 
    .toList();          // <- this fetches the result from the DB 

(*)これは明らかにも何の制限があることを意味していること注:(*)

あなたに少し似た簡単な例ではJinqでは、このようなものを見ることができますあなたのラムダに置くことができます - たとえば、データベースエンジンがそれらを実行できないので、任意のjavaメソッドを呼び出すことはできません。制限されたメソッドセットのみが許可されます。エンティティリレーションgetterメソッドは、そのような許可されたメソッドの一例です。