如何在Spring JpaRepository中使用JPQL选择组中的最新记录?

阿久库什

在SpringBoot微服务中,我试图为每个mean_of_payment_id选择一个演员的最新记录。要实现此目的,请使用mean_of_payment_id上的group by子句为actor_id选择actor内容,其中created_date等于max(created_date)嵌套查询的子集。我正在使用JPQL。下面是表的结构和查询。

在此处输入图片说明

    @Query("select ac from ActorContent ac "
        + "where (ac.actor.uuid=:actorUuid ) and "
        + "ac.createdDate IN ( SELECT MAX(aci.createdDate) "
            + "FROM ActorContent aci WHERE ac.actor.uuid=aci.actor.uuid "
            + "and aci.uuid = ac.uuid group by ac.meanOfPayment.id)"
        )

在此处输入图片说明

不幸的是,执行查询后,我得到了所有记录,但我期望的是前三行。MeanOfPayment和Actor是ActorContent的引用表。

尼古拉斯

我认为在关系代数方面,您要ActorContent 减去的集合是ActorContent受actor = actor和meanOfPayment = meanOfPayment和createDate <createDate约束的集合因此,思考的方法是从ActorContentwith的叉积获得第二组ac1.meanOfPayment = ac2.meanOfPayment and ac1.actor = ac2.actor and ac1.createDate < ac2.createDate然后从中减去该集合ActorContent我没有看过它是否比使用MAXGroup By例如更有效

@Query("select ac from ActorContent ac where ac.id not in (select ac1.id from ActorContent ac1, ActorContent ac2 where ac1.meanOfPayment = ac2.meanOfPayment and ac1.actor = ac2.actor and ac1.createDate < ac2.createDate)")

这给了我UPPER表中的前四行,分别代表第一个演员和他的唯一meanOfPayment,第二个演员和他对所有三个meanOfPayments的最新付款。

ActorContent [id=1, actor=Actor [id=1], meanOfPayment=MeanOfPayment [id=1], amount=10500.00, createDate=2018-10-09 00:00:00.887]
ActorContent [id=2, actor=Actor [id=2], meanOfPayment=MeanOfPayment [id=1], amount=-10400.00, createDate=2018-10-02 00:00:00.887]
ActorContent [id=3, actor=Actor [id=2], meanOfPayment=MeanOfPayment [id=3], amount=6000.00, createDate=2018-10-02 00:00:00.887]
ActorContent [id=4, actor=Actor [id=2], meanOfPayment=MeanOfPayment [id=2], amount=200.00, createDate=2018-09-30 00:00:00.887]

之后,您可能希望通过联接获取ActorMeanOfPayment实例来优化查询通过示例:

@Query("select ac from ActorContent ac left outer join fetch ac.actor left outer join fetch ac.meanOfPayment where ac.id not in (select ac1.id from ActorContent ac1, ActorContent ac2 where ac1.meanOfPayment = ac2.meanOfPayment and ac1.actor = ac2.actor and ac1.createDate < ac2.createDate)")

这将导致以下休眠生成的SQL查询:

select actorconte0_.id as id1_1_0_, actor1_.id as id1_0_1_, meanofpaym2_.id as id1_2_2_, actorconte0_.actor_id as actor_id4_1_0_, actorconte0_.amount as amount2_1_0_, actorconte0_.create_date as create_d3_1_0_, actorconte0_.mean_of_payment_id as mean_of_5_1_0_ from actor_content actorconte0_ left outer join actor actor1_ on actorconte0_.actor_id=actor1_.id left outer join mean_of_payment meanofpaym2_ on actorconte0_.mean_of_payment_id=meanofpaym2_.id where actorconte0_.id not in  (select actorconte3_.id from actor_content actorconte3_ cross join actor_content actorconte4_ where actorconte3_.mean_of_payment_id=actorconte4_.mean_of_payment_id and actorconte3_.actor_id=actorconte4_.actor_id and actorconte3_.create_date<actorconte4_.create_date)

当然,如果您想要特定的内容,Actor则只需将其添加到where子句中即可。

@Query("select ac from ActorContent ac left outer join fetch ac.actor left outer join fetch ac.meanOfPayment where ac.actor.id = :actorId and ac.id not in (select ac1.id from ActorContent ac1, ActorContent ac2 where ac1.meanOfPayment = ac2.meanOfPayment and ac1.actor = ac2.actor and ac1.createDate < ac2.createDate)")
public List<ActorContent> findLatestForActor(@Param("actorId") Integer actorId);

这给了我“前三行”

ActorContent [id=2, actor=Actor [id=2], meanOfPayment=MeanOfPayment [id=1], amount=-10400.00, createDate=2018-10-02 00:00:00.066]
ActorContent [id=3, actor=Actor [id=2], meanOfPayment=MeanOfPayment [id=3], amount=6000.00, createDate=2018-10-02 00:00:00.066]
ActorContent [id=4, actor=Actor [id=2], meanOfPayment=MeanOfPayment [id=2], amount=200.00, createDate=2018-09-30 00:00:00.066]

如果您对Actor和MeanOfPayment组合使用相同的createDate时遇到问题,则可以采用几种不同的方法来处理。首先,如果您具有逻辑约束以至于不想处理那些重复项,那么您可能还应该具有数据库约束,这样就不会得到它们并确保您首先不要创建它们。另一件事是,您可以手动检查结果列表并将其删除。最后,您可以在查询中使用一个ActorContent非重复,但是您必须省略id字段,因为它不是唯一的。您可以使用DTO进行此操作,但JPA无法处理投影和join fetch同时,因此您只会获得actor.id和meanOfPayment.id,否则您将进行多项选择。在此用例中,多重选择可能不是交易杀手,但您必须自己决定所有这一切。当然,您也可以将ActorContentactor.id,meanOfPayment.id和createDate组合在一起作为主键,这将具有上述约束的好处。

这些是Entities我合作过的。

@Entity
public class Actor {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

@Entity
public class MeanOfPayment {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

@Entity
public class ActorContent {
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    private Actor actor;
    @ManyToOne
    private MeanOfPayment meanOfPayment;

    private BigDecimal amount;
    @Temporal(TemporalType.TIMESTAMP)
    private Date createDate;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用SQl语法从MySQL表中的组中选择最新记录

如何使用SQL仅选择每个组中的最新组?

如何在spring数据中使用JPQL或Criteria Api通过枚举属性获取自定义数据组?

如何在mongodb中获取每个组的最新记录?

如何在Kotlin中使用JpaRepository中的save()

如何在Spring RestTemplate中记录响应?

如何在选择查询中获取组的先前记录日期

如何在Spring Boot中使用KeyHolder?

如何在 Spring Integration 中使用 webClient?

如何在Spring MongoDB中使用$ dateFromString?

如何在Spring Boot中使用CommonsMultipartResolver

如何在Textarea Spring中使用“值”

如何在Spring MVC中使用JasperReports?

如何在Spring MVC中使用Comet?

如何在Spring Data中使用@Transactional?

如何在Spring Boot中使用@NotNull?

如何在Spring Boot中使用CommandLineRunner?

如何在Spring中使用角色?

如何在Spring Boot中使用ORDER BY?

如何在Spring WebFlux中使用Jaeger?

如何在 HOC 中使用 React Spring?

如何在Spring MVC中使用CDN

如何在注释中使用 Spring 变量?

如何在Spring Controller中使用if ...

如何在Odoo 9中使用ORM API的search()方法根据创建记录的日期获取模型的最新记录?

如何在最新的Kubuntu 19.10中使用“按需选择原始”

如何在Spring Boot中摆脱JpaRepository接口

如何在JpaRepository中使用升序降序

如何在Spring Boot应用程序中使用JPQL配置JPA-“无法解析符号..”