Java Spring数据查询中的筛选子对象

Java Spring数据查询中的筛选子对象,java,spring,spring-data,spring-data-jpa,Java,Spring,Spring Data,Spring Data Jpa,我有以下域模型: 播放列表->列表->视频 @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 Vi

我有以下域模型:

播放列表
->
列表
->
视频

@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();
}
公共接口播放库扩展了JpaRepository{
列出findAll();
}
现在,如何返回仅包含现有视频的播放列表,即,如果数据库中有三个视频分配给该播放列表项,并且其中一个视频已被删除并设置为true,则我只需要获取两个项目。

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();
}
公共接口播放库扩展了JpaRepository{
@查询(“从播放列表中选择播放列表
获取加入播放列表。播放项目列表项
获取加入itens.video作为视频
其中video.isDeleted=false”)
列出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);
}
公共接口播放库扩展了JpaRepository{
@查询(“从播放列表中选择播放列表
获取加入播放列表。播放项目列表项
获取加入itens.video作为视频
其中video.isDeleted=:hasVideo”)
List findPlayList(@Param(“hasVideo”)布尔值hasVideo);
}

您可以查看Spring数据规范。您可以通过调用repository.findAll来使用它们

规范允许您向查询中添加任意条件,包括要添加的筛选器。规范的另一个优点是它们可以是类型安全的。请看这里:


您所要做的就是在
播放库
界面上声明此方法:

List<Playlist> findByPlaylistItemsVideoIsDeleted(boolean isDeleted);

这将返回包含未删除视频的所有播放列表。

您可能已经解决了此问题,但我想我会提供此信息,希望它能帮助您或访问此页面的任何其他人

使用Spring JPA规范,您将:

  • 启用您的
    播放列表存储库
    以使用JPA规范
  • 作为可重用的方法编写
    规范
  • 使用
    规范
    作为查询
  • 详情如下

    1.实施
    JpaSpecificationExecutor
    更新
    播放列表存储库
    以实现
    JpaSpecificationExecutor
    。这会将接受
    规范
    参数的
    find*
    方法添加到
    播放库

    public interface PlaylistRepository extends JpaRepository<Playlist, Long>, 
                JpaSpecificationExecutor<Playlist> {
    
    }
    
    使用
    root.join
    (以及随后的
    join
    s)类似于在SQL中使用
    join
    。这里,我们是在类的字段上连接,而不是在表的列上连接

    3.发出查询 我不知道您打算如何发出查询,但下面是如何在“服务”类中执行查询的示例:

    @服务
    公共类播放服务{
    @自动连线
    私人播放库;
    公共列表查找现有视频的播放列表(){
    Specification spec=播放规范。hasExistingVideos();
    返回playlistepository.findAll(spec);
    }
    }
    

    希望这有帮助

    我猜你是在问一些类似于Hibernate FilterDef和Filter功能的问题。不幸的是,我不知道在SpringDataJPA中使用类似内容的简单方法。仅供参考:你能解释一下这是如何神奇地工作的吗?有没有关于jpa的任何描述?@judos可以看看,如何使用
    Video.isDeleted()
    构造jpa规范来查询
    Playlist
    s?这会涉及到使用
    加入
    ?不幸的是,我不再从事同一个项目,因此我与该技术失去了联系-希望其他人能提供帮助!
    
    public interface PlaylistRepository extends JpaRepository<Playlist, Long>, 
                JpaSpecificationExecutor<Playlist> {
    
    }
    
    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);
            };
        }
    }
    
    @Service
    public class PlaylistService {
    
        @Autowired
        private PlaylistRepository playlistRepository;
    
        public List<Playlist> findPlaylistsWithExistingVideos() {
    
            Specification<Playlist> spec = PlaylistSpecifications.hasExistingVideos();
            return playlistRepository.findAll(spec);
        }
    }