多个到多个的JPA Criteria API规范

Atu*_*ary 9 java spring jpa-2.0 spring-data-jpa spring-boot

我有三个课程,如下所述.我正在尝试创建一个规范来过滤链接表中匹配的数据.

public class Album {
    private Long id;
    private List<AlbumTag> albumTags;
}

public class Tag {
    private Long id;
    private String category;
}

public class AlbumTag{
    private Long id;
    private Album album;
    private Tag tag;
}
Run Code Online (Sandbox Code Playgroud)

在上面给出的模式中,我想要找到的是Album表中所有相册的列表以及AlbumTag中的链接.我想要实现的SQL不必相同,如下所示

select *
from Album A 
where (A.Id in (select [AT].AlbumId 
from AlbumTag [AT]))
Run Code Online (Sandbox Code Playgroud)

到目前为止,我所尝试的当时没有工作的是下面的内容

public class AlbumWithTagSpecification implements Specification<Album> {

    @Override
    public Predicate toPredicate(Root<Album> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

         final Subquery<Long> personQuery = cq.subquery(Long.class); 
         final Root<Album> album = personQuery.from(Album.class); 
         final Join<Album, AlbumTag> albumTags = album.join("albumTags");
         personQuery.select((albumTags.get("album")).get("id"));
         personQuery.where(cb.equal(album.get("id"), (albumTags.get("album")).get("id"))); 
         return cb.in(root.get("id")).value(personQuery);

    }
}
Run Code Online (Sandbox Code Playgroud)

Pra*_*n D 4

使用 spring boot 和 spring data JPA,您可以更喜欢实体关系来获取数据。

1.用实体关系注释领域类,如下所示:

@Entity
@Table(name="Album")
public class Album {
    @Id
    @Column(name="id")
    private Long id;
    @OneToMany(targetEntity = AlbumTag.class, mappedBy = "album")
    private List<AlbumTag> albumTags;

    //getter and setter
}

@Entity
@Table(name="Tag")
public class Tag {
    @Id
    @Column(name="id")
    private Long id;
    @Column(name="category")
    private String category;

    //getter and setter
}

@Entity
@Table(name="AlbumTag")
public class AlbumTag{
    @Id
    @Column(name="id")
    private Long id;
    @ManyToOne(optional = false, targetEntity = Album.class)
    @JoinColumn(name = "id", referencedColumnName="id", insertable = false, updatable = false)
    private Album album;
    @ManyToOne(optional = false, targetEntity = Tag.class)
    @JoinColumn(name = "id", referencedColumnName="id", insertable = false, updatable = false)
    private Tag tag;

    //getter and setter
}
Run Code Online (Sandbox Code Playgroud)

2.使用 spring 数据通过以下方式获取详细信息:

Album album = ablumRepository.findOne(1); // get the complete details about individual album.
List<AlbumTag> albumTags = ablum.getAlbumTags(); // get the all related albumTags details for particular album.
Run Code Online (Sandbox Code Playgroud)

我希望这能帮助你解决这个问题。