2016-06-13 16 views
0

SQLステートメントとプリミティブアクセスを取り除き、Spring Data JPA(Hibernateにバックアップされている)で近代化するために、コードベースをリファクタリングしています。私は他の用途のためにプロジェクトでQueryDSLを使用します。SpringデータJPA、QueryDSLを使用してレコードの集合を更新する

私は、大量のレコードを一括更新し、更新する値を選択できるシナリオを持っています。古い方法では、コードは手作業で更新ステートメントを作成し、PKの場所(更新する項目)と手動でSET句を作成しました(SET句のオプションはユーザー更新したい)。

QueryDSLのドキュメントを見て、私がしたいことをサポートしていることを示しています。 http://www.querydsl.com/static/querydsl/4.1.2/reference/html_single/#d0e399

私はSpring Data JPAでこれを行う方法を探していましたが、運がなかったのです。私が紛失している再校正用のインターフェースや、必要とされる別のライブラリがありますか?あるいは、カスタムのリポジトリ実装にqueryFactoryをautowireして、QueryDSLの例でコードを実装する必要がありますか?

答えて

0

カスタムメソッドを記述するか、@Queryアノテーションを使用できます。

カスタムメソッドの場合。

public interface RecordRepository extends RecordRepositoryCustom, 
              CrudRepository<Record, Long> 
{ 
} 

public interface RecordRepositoryCustom { 
     // Custom method 
     void massUpdateRecords(long... ids); 
} 

public class RecordRepositoryImpl implements RecordRepositoryCustom { 
     @Override 
     public void massUpdateRecords(long... ids) { 
      //implement using em or querydsl 
     } 
} 

@Queryアノテーションについては、

public interface RecordRepository extends CrudRepository<Record, Long> 
{ 
     @Query("update records set someColumn=someValue where id in :ids") 
     void massUpdateRecords(@Param("ids") long... ids); 
} 

あなたのモデルクラスは、カスタムメソッドを持つ再利用可能にしたい場合は@NamedQueryオプションもあります。詳細は、スプリングのデータ参照文書で

@Entity 
@NamedQuery(name = "Record.massUpdateRecords", query = "update records set someColumn=someValue where id in :ids") 
@Table(name = "records") 
public class Record { 
     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO) 
     private Long id; 
     //rest of the entity... 
} 

public interface RecordRepository extends CrudRepository<Record, Long> 
{ 
     //this will use the namedquery 
     void massUpdateRecords(@Param("ids") long... ids); 
} 

チェックrepositories.custom-implementationsjpa.query-methods.at-queryjpa.query-methods.named-queries

+0

私はや、質問を参照してください(設定2番目の段落「と、彼らがしたいいくつかの値を選択してもしなくてもよい性質の束があるのでこれは、動作しません更新")。私が今までに思い付くことができるのは、個々のプロパティごとに異なる一括更新メソッドを持たせることだけですが、それは無駄です(複数の更新を実行する)ようです。私はこれをすべて1回の呼び出しで行う方法を探しています。 –

+0

私はこの方法を使わなくてはなりませんでした。私は大量更新が可能な私のbeanの各プロパティのリポジトリメソッドを作成しました。私はその後、サービスでユーザーが更新したいプロパティを確認し、適切な更新メソッドを呼び出すロジックを確認しました。 –

0

この質問は私の現在のプロジェクトでこの問題を解決していたので、私の興味深い話です。特に、我々はあなたの質問の後半部分に興味を持っていた:SET句のオプションは、ユーザー が

を更新したい内容に応じて変化させることができる

私はこれはおそらく答えはあなたであることを理解します取得したくないが、そこに何も見つかりませんでした:(春のデータは、特に柔軟性になると、特に更新の操作が面倒です。

私はあなたの質問を見た後、私は春とQueryDSL統合(あなたが知っている、多分何か過去数ヶ月の間にリリースされたが)何もリリースされなかった。

かなり近い私をもたらした唯一のことは、あなたが次のシナリオをたどる可能性が意味エンティティマネージャで.flushです:

  1. あなたは
  2. は、これらのIDにより、すべてのエンティティを取得更新したいエンティティのIDを取得する(をdbに最初の実際のクエリ)
  3. あなたはN個別のアップデートトンを結果
  4. コールentityManager.flushを好きなようにそれらを変更しますoデータベース

このアプローチは、データベースにN + 1の実際のクエリを結果ここN =更新する必要IDSの数。さらに、データを前後に移動していますが、これは実際にはうまくいきません。私は

に助言する

は、また、カスタムリポジトリ 実装

にqueryFactoryをautowire spring data and querydsl exampleに顔をしています。しかし、検索の例だけがあります。

は、私の悲観的な答えがお役に立てば幸いです:)

+0

N + 1アプローチは本当にここではうまくいきません。私はOnurの答え(私が避けようとしていた方法として私の質問で暗示された)を使用しなければならなくなった。詳細は私のコメントを参照してください –

関連する問題