无法在Spring Data JPA自定义存储库中编写SQL查询

时间:2015-02-13 14:04:55

标签: java spring hibernate jpa

我想在自定义JPA存储库中实现SQL的一部分

SELECT * FROM users u
    JOIN skills_user sku on sku.user_id = u.id
    JOIN specs_user spu on spu.user_id = u.id
    GROUP BY u.id
    HAVING ANY(sku.dictionary_id in (15,20) or spu.dictionary_id in (15,20))
    ORDER BY u.id

我试过了:

//Other predicates    
if (filterQuery.getSkills() != null && !filterQuery.getSkills().isEmpty()) {
            String[] tmp = filterQuery.getSkills().replaceAll(" ", "").split(",");
            List<Integer> ids = new ArrayList<>();
            for (String s : tmp) {
                ids.add(Integer.parseInt(s));
            }
            List<Predicate> tmpPredicates = new ArrayList<>();
            Join<User, Dictionary> skillJoin = root.join("skillList");
            Join<User, Dictionary> specsJoin = root.join("specsList");
            for (Integer id : ids) {
                tmpPredicates.add(builder.or(builder.equal(skillJoin.get("id"), id), builder.equal(specsJoin.get("id"), id)));
            }
            predicates.add(builder.and(tmpPredicates.toArray(new Predicate[tmpPredicates.size()])));
        }
//Other predicates

但它无法正常工作。

如何在JPA自定义存储库中正确实现这一点?

有用户和词典类的代码:

    @Entity
@SequenceGenerator(name = "user_gen", sequenceName = "users_seq")
@Table(name = "users")
public class User {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_gen")
    private Long id;

    @Column(name = "login")
    private String login;

    @Column(name = "password")
    private String password;

    @Column(name = "name")
    private String name;

    @Column(name = "surname")
    private String surname;

    @Column(name = "middlename")
    private String middlename;

    @Column(name = "academic_group")
    private String academicGroup;

    @Column(name = "entrance_year")
    private int entranceYear;

    @Column(name = "avatar_URL")
    private String avatarURL;

    @Column(name = "salt")
    private String salt;

    @Enumerated(EnumType.ORDINAL)
    @Column(name = "user_group")
    private UserGroup group;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "SocialRole_User", joinColumns = {
            @JoinColumn(name = "user_id", nullable = false, updatable = false) },
            inverseJoinColumns = { @JoinColumn(name = "socialRole_id",
                    nullable = false, updatable = false) })
    private List<SocialRole> socialRoleList;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "specs_user", joinColumns = {
            @JoinColumn(name = "user_id", nullable = false, updatable = true)},
            inverseJoinColumns = {@JoinColumn(name = "dictionary_id",
                    nullable = false, updatable = true)})
    private List<Dictionary> specsList;
    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "skills_user", joinColumns = {
            @JoinColumn(name = "user_id", nullable = false, updatable = true)},
            inverseJoinColumns = {@JoinColumn(name = "dictionary_id",
                    nullable = false, updatable = true)})
    private List<Dictionary> skillList;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Contacts> contactsList;

//Getters and setters
}

字典:

 @Entity
    @SequenceGenerator(name = "dictionary_gen", sequenceName = "dictionary_seq")
    @Table(name = "dictionary")
    public class Dictionary {

        @Id
        @Column(name = "id")
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "dictionary_gen")
        private Long id;

        @Column(name = "dic_name")
        private String name;

        @Enumerated(EnumType.STRING)
        @Column(name = "dic_type")
        private DictionaryType type;

    // Getters and Setters
    }

1 个答案:

答案 0 :(得分:0)

您是否尝试使用JPQL编写查询?

SELECT a FROM User a
INNER JOIN a.specsList b
INNER JOIN a.skillList c
GROUP BY a.id
HAVING ANY(b.id in (15,20) OR c.id in (15,20))
ORDER BY a.id;

此JPQL应与普通SQL一样工作。