Spring Boot JPA – 按实体集合排序

huangapple go评论84阅读模式
英文:

Spring boot JPA - Order by Entity collection

问题

以下是已翻译的内容:

我正在尝试按照特定时间段内的收藏大小对数据进行排序。

我有

Title实体

@Entity
@Getter
@Setter
public class Title {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Long id;

    @Column(length=120, nullable=false)
    private String name;

    @OneToMany(mappedBy = "title", cascade = CascadeType.MERGE, orphanRemoval = true)
    private Set<TitleVisitor> visitors = new HashSet<>();

    @CreatedDate
    private LocalDateTime createdAt;
    @LastModifiedDate
    private LocalDateTime updatedAt;
}

TitleVisitor实体

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TitleVisitor implements Serializable {

    @EmbeddedId
    private TitleVisitorId id = new TitleVisitorId();

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("titleId")
    private Title title;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("visitorId")
    private Visitor visitor;

    @CreatedDate
    private LocalDateTime createdAt;
}

Title repository

@Repository
public interface MovieRepository extends JpaRepository<Movie, Long> {
    @Override
    Optional<Movie> findById(Long aLong);

    @Query(
            value = "SELECT m FROM Movie m LEFT JOIN TitleVisitor tv ON m.id = tv.id.titleId WHERE tv.createdAt >= DATEADD(day,-7, NOW()) GROUP BY tv.id.titleId",
            countQuery = "select count(tv.id.titleId) from TitleVisitor tv"
    )
    Page<Movie> findAllWithTitleVisitorCountOrderByCountDesc(Pageable pageable);
}

Title service

    public Page<Title> findPaginated(int page, int size) {
        Pageable paging = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "visitors"));

        return this.titleRepository.findAll(paging);
    }

我需要选择分页数据(Title实体),并按最近一天/一周/一个月/总体内的标题访问次数对所有标题实体进行排序。

英文:

I am try to sort the data by collection size for a certain period.

I have

Title Entity


@Entity
@Getter
@Setter
public class Title {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private Long id;

    @Column(length=120, nullable=false)
    private String name;

    @OneToMany(mappedBy = &quot;title&quot;, cascade = CascadeType.MERGE, orphanRemoval = true)
    private Set&lt;TitleVisitor&gt; visitors = new HashSet&lt;&gt;();

    @CreatedDate
    private LocalDateTime createdAt;
    @LastModifiedDate
    private LocalDateTime updatedAt;

TitleVisitor Entity

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TitleVisitor implements Serializable {

    @EmbeddedId
    private TitleVisitorId id = new TitleVisitorId();

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId(&quot;titleId&quot;)
    private Title title;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId(&quot;visitorId&quot;)
    private Visitor visitor;

    @CreatedDate
    private LocalDateTime createdAt;

Title repository

@Repository
public interface MovieRepository extends JpaRepository&lt;Movie, Long&gt; {
    @Override
    Optional&lt;Movie&gt; findById(Long aLong);

    @Query(
            value = &quot;SELECT m FROM Movie m LEFT JOIN TitleVisitor tv ON m.id = tv.id.titleId WHERE tv.createdAt &gt;= DATEADD(day,-7, NOW()) GROUP BY tv.id.titleId&quot;,
            countQuery = &quot;select count(tv.id.titleId) from TitleVisitor tv&quot;
    )
    Page&lt;Movie&gt; findAllWithTitleVisitorCountOrderByCountDesc(Pageable pageable);
}

Title service

    public Page&lt;Title&gt; findPaginated(int page, int size) {
        Pageable paging = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, &quot;visitors&quot;));

        return this.titleRepository.findAll(paging);
    }

I need select paginated data (Title Entity) and sort all title entities by count of title visits in the last day/week/month/overall

Thanks.

答案1

得分: 0

你可以在JPQL中使用ORDER BY,而不是在pageable中使用排序参数,因为你使用了自定义顺序。

@Query(value = "SELECT t FROM Title t LEFT JOIN t.visitors tv "
         + "WHERE tv.createdAt >= :dateTime GROUP BY t ORDER BY COUNT(tv.visitor.id) DESC",
            countQuery = "select count(t.id) from Title t")
Page<Title> findByTitleVisitorCountCount(LocalDateTime dateTime, Pageable pageable);

在这里,计算dateTime用于过去的一天/一周/一个月/全部时间。

英文:

You can use ORDER BY in JPQL rather than use sort param in pageable since you use custom order.

@Query(value = &quot;SELECT t FROM Title t LEFT JOIN t.visitors tv &quot;
         + &quot;WHERE tv.createdAt &gt;= :dateTime GROUP BY t ORDER BY COUNT(tv.visitor.id) DESC&quot;,
            countQuery = &quot;select count(t.id) from Title t&quot;)
    Page&lt;Title&gt; findByTitleVisitorCountCount(LocalDateTime dateTime, Pageable pageable);

Here, calculate dateTime for last day/week/month/overall

huangapple
  • 本文由 发表于 2020年10月26日 19:52:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/64536598.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定