2017-07-27 8 views
0

におけるメソッドの有効性を保存します。春データJPAは、Java 8の機能マップ

  1. 我々は全体のリストを取り、古典的なList<S> save(Iterable<S> entities)メソッドを使用することができます。
    例:

    someOtherRepository.save(
        someRepository.findAll() 
        .stream() 
        .map(something -> { 
         //some operations 
         return someOtherThing; 
        }) 
        .collect(Collectors.toList()) 
    ); 
    
  2. 私たちは、単一のエンティティをとるS save(S entity)メソッドを使用してmapstreamでそれを使用することができます。
    例:

    someRepository.findAll() 
    .stream() 
    .map(something -> { 
        //some operations 
        return someOtherThing; 
    }) 
    .map(someOtherRepository::save) 
    .collect(Collectors.toList()); 
    

質問です:
は、これら2つのアプローチの実行時間の違いはありますか?はいの場合は、より効果的です(より速く)。

答えて

2

save(Iterable<S> entities)save(S entity)を反復して呼び出すことに依存しています:

@Transactional 
public <S extends T> List<S> save(Iterable<S> entities) { 

    List<S> result = new ArrayList<S>(); 

    if (entities == null) { 
     return result; 
    } 

    for (S entity : entities) { 
     result.add(save(entity)); 
    } 

    return result; 
} 

ので、2つは、パフォーマンスの面で同じ結果を与える必要があります。

バッチインサートを実行するには、ハイバネート設定(hibernate.jdbc.batch_size)でそれを指定し、フラッシュする必要があります。

1

つ以上の要素を持つリストの場合は、最初のアプローチは、はるかに高速

ちょうど簡潔に理由を説明(リストはただ一つの要素を持っているならば、それは同じでなければなりません)になります。バッチインサート中に、1回の挿入で複数の接続が確立されるオーバーヘッドはありません。

+0

詳しくは教えてください。私は、saveメソッドを使用するたびにデータベースに新たに接続することを信じていません。これは、記述の悪いJDBCコードで発生する可能性がありますが、休止状態には接続プールがあります。特に2つの答えを読んだ後、私はあなたのことを信じていません。 – luke

2

これは多くのことに依存するため、予測することは難しいです。しかし、私はそれが大きな違いを作らないと期待しています。

ここで、質問はhibernateとタグ付けされているため、Spring Data JPAとお話しているようです。トランザクションがsaveへのすべてのコールに及ぶと仮定すると、実際にはデータベースに実際にアクセスせずに、EntityManagerにエンティティを追加するだけです。そして、最後にフラッシュが発生すると(通常、トランザクションの終了時に)、すべてのエンティティはHibernateによって1つのデータベースに永続化されます。

したがって、パフォーマンスの違いは、コードとSpringデータの異なるコードパスにあります。これらの違いは、実際に存続しているエンティティから来るものからは無視できなければなりません。

膨大な数のエンティティについて話している場合、EntityManager自体のパフォーマンス特性が関連する可能性があります。

saveへのすべての呼び出しで、独自のトランザクションの単一コールが作成されると、処理速度が大幅に低下する可能性があります。

だから、最後に、それはつまるところ:あなたは自分のデータでそれをしようとしないのはなぜ

?結果をお知らせください。

関連する問題