データベースアクセスにSpring JPAを使用しています。 findByNameやcountByNameなどの例を見つけることができますが、メソッドの実装を記述する必要はありません。何らかの条件に基づいてレコードのグループを削除する例を見つけたいと思っています。
Spring JPAはdeleteByNameのような削除をサポートしていますか?どんなポインターでも大歓迎です。
よろしくお願いします。
非推奨の回答(Spring Data JPA <= 1.6.x):
@Modifying
アノテーションが助けになります。ただし、カスタムSQLの動作を提供する必要があります。
@Transactional(readOnly = true)
public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Transactional
@Query("delete from User u where u.firstName = ?1")
void deleteUsersByFirstName(String firstName);
}
更新:
Spring Data JPA(> = 1.7.x)の最新バージョンでは、delete
、remove
、およびcount
操作のクエリ派生にアクセスできます。
public interface UserRepository extends CrudRepository<User, Long> {
Long countByFirstName(String firstName);
@Transactional
Long deleteByFirstName(String firstName);
@Transactional
List<User> removeByFirstName(String firstName);
}
特定のメソッド名を使用した削除クエリの派生は、Spring Data JPAのバージョン 1.6.0.RC1 以降でサポートされています。キーワードremove
およびdelete
がサポートされています。戻り値として、削除されたエンティティの数またはリストから選択できます。
Long removeByLastname(String lastname);
List<User> deleteByLastname(String lastname);
Spring Data JPAのソースコード、特にPartTreeJpaQuery
クラスを見ると、PartTree
をインスタンス化しようとしていることがわかります。そのクラス内で次の正規表現
private static final Pattern PREFIX_TEMPLATE = Pattern.compile("^(find|read|get|count|query)(\\p{Lu}.*?)??By")
何が許可され、何が許可されないかを示す必要があります。
もちろん、このようなメソッドを追加しようとすると、実際には機能しないことがわかり、完全なスタックトレースが取得されます。
Spring Data JPAのバージョン1.5.0.RELEASE
を見て使用していたことに注意してください
Spring JPAが直接提供する定義済みの削除メソッドを使用する場合、以下の2つのクエリがフレームワークによって実行されます。
最初に、delete query where句を使用してselectクエリを実行することにより、データ(IDやその他の列など)を収集します。
次に、最初のクエリのresultSetを取得した後、すべてのIDに対して2番目の削除クエリが実行されます(1つずつ)
注:これは、単一のMYSQL削除クエリに対して多くのクエリが実行されるため、アプリケーションに対して最適化された方法ではありません。
これは、以下のカスタマイズされたメソッドを使用して1つの削除クエリのみを実行するため、削除クエリコードの別の最適化された方法です。
@NamedNativeQueries({
@NamedNativeQuery(name = "Abc.deleteByCreatedTimeBetween",
query = "DELETE FROM abc WHERE create_time BETWEEN ?1 AND ?2")
,
@NamedNativeQuery(name = "Abc.getByMaxId",
query = "SELECT max(id) from abc")
})
@Entity
public class Abc implements Serializable {
}
@Repository
public interface AbcRepository extends CrudRepository {
int getByMaxId();
@Transactional
@Modifying
void deleteByCreatedTimeBetween(String startDate, String endDate);
}
バッチ削除に派生クエリを使用する場合は注意してください。あなたが期待するものではありません: 実行の削除