我有以下域名模型:
Playlist
- &gt; List<PlaylistItem>
- &gt; 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();
}
现在,如何返回仅包含现有视频的播放列表,即如果数据库中有三个视频分配给该播放列表项目,其中一个视频的isDeleted设置为true,那么我只需要获取两个项目代替。
答案 0 :(得分:11)
您所要做的就是在PlaylistRepository
界面上声明此方法:
List<Playlist> findByPlaylistItemsVideoIsDeleted(boolean isDeleted);
并称之为:
playListRepository.findByPlaylistItemsVideoIsDeleted(false);
这将返回包含未删除视频的所有播放列表。
答案 1 :(得分:5)
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);
}
答案 2 :(得分:3)
您可以查看Spring数据规范。您可以通过调用repository.findAll(s);
来使用它们规范允许您在查询中添加任意条件,包括要添加的过滤器。规格的另一个好处是它们可以是类型安全的。见这里:
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#specifications
答案 3 :(得分:0)
您可能已经解决了此问题,但我想我会为此提供帮助,希望它可以对您或其他访问此页面的人有所帮助。
使用Spring JPA规范,您将:
PlaylistRepository
以使用JPA规范Specification
写为可重用的方法Specification
作为查询这是详细信息。
JpaSpecificationExecutor
更新PlaylistRepository
以实现JpaSpecificationExecutor
。这会将find*
个接受Specification<T>
参数的方法添加到您的PlaylistRepository
中。
public interface PlaylistRepository extends JpaRepository<Playlist, Long>,
JpaSpecificationExecutor<Playlist> {
}
Specification
使用静态方法创建一个类,以用于创建可重用 Specification
。
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
)与在SQL中使用JOIN
相似。在这里,我们在类的字段上联接,而不是在表的列上联接。
我不知道您打算如何发布查询,但是下面是在“服务”类中如何进行查询的示例:
@Service
public class PlaylistService {
@Autowired
private PlaylistRepository playlistRepository;
public List<Playlist> findPlaylistsWithExistingVideos() {
Specification<Playlist> spec = PlaylistSpecifications.hasExistingVideos();
return playlistRepository.findAll(spec);
}
}
希望这会有所帮助!