次のドメインモデルがあります。
Playlist
-> List<PlaylistItem>
-> Video
@Entity
class Playlist{
// id, name, etc
List<PlaylistItem> playlistItems;
// getters and setters
}
@Entity
class PlaylistItem{
// id, name, etc.
Video video;
// getters and setters
}
@Entity
class Video{
// id, name, etc.
boolean isDeleted;
// getters and setters
}
そして私のリポジトリ:
public interface PlaylistRepository extends JpaRepository<Playlist, Long> {
List<Playlist> findAll();
}
ここで、既存のビデオのみを含む再生リストを返す方法を示します。つまり、データベースに3つのビデオがその再生リストアイテムに割り当てられており、それらのビデオの1つにisDeletedがtrueに設定されている場合、代わりに2つのアイテムのみを取得する必要があります。
あなたがしなければならないすべてはあなたのPlaylistRepository
インターフェースでこのメソッドを宣言することです:
List<Playlist> findByPlaylistItemsVideoIsDeleted(boolean isDeleted);
次のように呼び出します。
playListRepository.findByPlaylistItemsVideoIsDeleted(false);
削除されていない動画を含むすべての再生リストが返されます。
Maksim、次のように@ query注釈を使用できます。
public interface PlaylistRepository extends JpaRepository<Playlist, Long> {
@Query("select playlist from Playlist playlist
fetch join playlist.playlistItems itens
fetch join itens.video as video
where video.isDeleted = false")
List<Playlist> findAll();
}
またはさらに良い方法:
public interface PlaylistRepository extends JpaRepository<Playlist, Long> {
@Query("select playlist from Playlist playlist
fetch join playlist.playlistItems itens
fetch join itens.video as video
where video.isDeleted = :hasVideo ")
List<Playlist> findPlayList(@Param("hasVideo") boolean hasVideo);
}
Springデータ仕様を調べることができます。それらを使用するには、repository.findAll(s);を呼び出します。
仕様を使用すると、追加するフィルターを含め、クエリに任意の条件を追加できます。仕様のもう1つの良い点は、タイプセーフであるということです。こちらをご覧ください:
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#specifications
あなたはすでにこの問題を解決しているかもしれませんが、あなたやこのページにアクセスしている他の人に役立つことを期待して、私はこれを寄稿すると思いました。
Spring JPA仕様を使用して、次のことを行います。
PlaylistRepository
がJPA仕様を使用できるようにしますSpecification
を再利用可能なメソッドとして記述するSpecification
をクエリとして使用する詳細はこちら。
JpaSpecificationExecutor
PlaylistRepository
を実装するためにJpaSpecificationExecutor
を更新します。これにより、find*
パラメータを受け入れるSpecification<T>
メソッドがPlaylistRepository
に追加されます。
public interface PlaylistRepository extends JpaRepository<Playlist, Long>,
JpaSpecificationExecutor<Playlist> {
}
Specification
を作成しますreusableSpecification
の作成に使用する静的メソッドでクラスを作成します。
public final class PlaylistSpecifications {
private PlaylistSpecifications() {}
public static Specification<Playlist> hasExistingVideos() {
return (root, query, cb) -> {
return cb.equal(root.join("playlistItems").join("video")
.get("isDeleted"), false);
};
}
}
root.join
(および後続のjoin
s)の使用は、SQLでのJOIN
の使用に似ています。ここでは、テーブルの列ではなくクラスのフィールドで結合しています。
クエリをどのように発行するかはわかりませんが、以下は「サービス」クラスでどのように実行できるかの例です。
@Service
public class PlaylistService {
@Autowired
private PlaylistRepository playlistRepository;
public List<Playlist> findPlaylistsWithExistingVideos() {
Specification<Playlist> spec = PlaylistSpecifications.hasExistingVideos();
return playlistRepository.findAll(spec);
}
}
お役に立てれば!