JPQL使用UNION查询复杂的SELECT

时间:2018-01-31 21:10:59

标签: hibernate jpa spring-boot spring-data jpql

MySQL 5.6支持的Spring Boot REST服务。我有以下表格:

DESCRIBE profiles;
+----------------------------+---------------------+------+-----+---------+----------------+
| Field                      | Type                | Null | Key | Default | Extra          |
+----------------------------+---------------------+------+-----+---------+----------------+
| profile_id                 | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| profile_given_name         | varchar(100)        | YES  | MUL | NULL    |                |
| profile_surname            | varchar(100)        | YES  | MUL | NULL    |                |
+----------------------------+---------------------+------+-----+---------+----------------+

describe friendships;
+----------------------+---------------------+------+-----+---------+----------------+
| Field                | Type                | Null | Key | Default | Extra          |
+----------------------+---------------------+------+-----+---------+----------------+
| friendship_id        | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| requester_profile_id | bigint(20) unsigned | NO   | MUL | NULL    |                |
| recipient_profile_id | bigint(20) unsigned | NO   | MUL | NULL    |                |
+----------------------+---------------------+------+-----+---------+----------------+

profiles表表示系统的用户,friendships表示用户与其他用户成为朋友的多对多关系。当用户/个人资料向用户发送“朋友请求”时,他们被认为是友情的requester。相反,那些收到其他人的朋友请求的人是recipients

这些表对应于以下JPA实体:

@MappedSuperclass
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

@Entity
@Table(name = "profiles")
@AttributeOverrides({
        @AttributeOverride(name = "id", column=@Column(name="profile_id"))
})
@JsonDeserialize(using = ProfileDeserializer)
public class Profile extends BaseEntity implements Comparable<Profile> {
    @Column(name = "profile_given_name")
    private String givenName;

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

@Entity
@Table(name = "friendships")
@AttributeOverrides({
        @AttributeOverride(name = "id", column=@Column(name="friendship_id"))
})
public class Friendship extends BaseEntity {
    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinColumn(name = "requester_profile_id", referencedColumnName = "profile_id")
    @NotNull
    private Profile requester;

    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinColumn(name = "recipient_profile_id", referencedColumnName = "profile_id")
    @NotNull
    private Profile recipient;
}

在MySQL命令行客户端中,我可以根据以下查询找出特定个人资料的朋友:

SELECT      f.recipient_profile_id as profile_friends
FROM        profiles p
INNER JOIN  friendships f
ON f.requester_profile_id = p.profile_id
WHERE       p.profile_id = 1

UNION

SELECT      f.requester_profile_id
FROM        profiles p
INNER JOIN  friendships f
ON  f.recipient_profile_id = p.profile_id
WHERE       p.profile_id = 1;

这会产生如下输出:

+-----------------+
| profile_friends |
+-----------------+
|               2 |
|               3 |
|               4 |
+-----------------+

上面,我们看到profile_id = 1是其他3个个人资料的朋友,profile_id IN {2,3,4}

我正在尝试在我的CrudRepository中编写等效的JPQL查询并且遇到困难:

public interface FriendshipRepository implements CrudRepository<Friendship,Long> {
    @Query(" ??? ")
    public Set<Profile> getFriendsByProfile(@Param("profile") Profile profile);
}

关于如何编写@Query(...)以运行上述等效SELECT语句的任何想法

0 个答案:

没有答案