【问题标题】:Spring Data JPA JPQL queries on parent interface父接口上的 Spring Data JPA JPQL 查询
【发布时间】:2015-12-23 20:16:37
【问题描述】:

假设我有一个这样的@MappedSuperClass

@MappedSuperclass
public abstract class Rating
{
    @Id
    private Long id;

    @Column(name="USER_ID")
    private Long userId;

    private int rating;
    ...

像这样的具体子实体

@Entity
@Table(name="ACTIVITY_RATING")
public class ActivityRating extends Rating
{
    private Long activitySpecificData;
    ...

然后有一个像这样的 Spring Data JPA 存储库:

@NoRepositoryBean
public interface RatingRepository<R extends Rating> extends JpaRepository<R, ID>
{
    public List<R> findByUserId(Long userId);
    ...

还有这个:

public interface ActivityRatingRepository extends RatingRepository<ActivityRating>
{

}

这一切都很好,我可以在任何扩展 RatingRepository 的特定评级存储库上调用 findByUserId()。我现在想在RatingRepository 中写一些 JPQL,所有子接口都可以继承。我只是不知道在查询中的FROM 之后放置什么(或者是否有可能)。例如:

@Query("SELECT NEW com.foo.RatingCountVo(e.rating, COUNT(e.rating)) FROM ??????? e GROUP BY e.rating")
public List<RatingCountVo> getRatingCounts();

我可以将此方法添加到扩展 RatingRepository 的每个单独的存储库中,但除了特定的实体名称之外,一切都将完全相同。如果我想更改查询,则必须访问所有子存储库并单独更新它们。我真的希望查询存在于父类中而不是重复。有没有办法做到这一点?

我目前正在使用 spring-data-jpa 1.7.2 和 eclipselink 2.5.2。如有必要,我不一定反对切换到较新的版本。

【问题讨论】:

    标签: jpa spring-data-jpa jpql


    【解决方案1】:

    如果将查询拆分为 3 部分:查询的开始、实体和结束,它会起作用吗?比,如果它会工作,在每个接口中定义常量,如

    String ENTITY = "ActivityRating";
    

    然后你可以像这样使用它

    @Query(RatingRepository.QUERY_START + ENTITY + RatingRepository.QUERY_END)
    List<RatingCountVo> getRatingCounts();
    

    顺便说一句,接口中不需要定义public修饰符。

    更新:here is described 另一种方式:

    @Query("SELECT NEW com.foo.RatingCountVo(e.rating, COUNT(e.rating)) FROM #{#entityName} e GROUP BY e.rating
    

    【讨论】:

    • 这当然可行,但它仍然意味着在所有子接口上使用相同的方法,而不是在父接口上使用一次。
    • 完美!这正是我所追求的。
    猜你喜欢
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 2015-03-18
    • 1970-01-01
    • 2021-04-13
    • 2019-05-03
    • 2020-01-14
    相关资源
    最近更新 更多