【问题标题】:JPA count related entities without joining themJPA 计算相关实体而不加入它们
【发布时间】:2015-12-06 15:28:28
【问题描述】:

我有两个实体:

@Entity
class X {
  @Id
  int id;
}

@Entity
class Y {
  @Id
  int id;

  @ManyToOne
  @JoinColumn(name = "x_id")
  X x;
}

我想计算 y 表中 x_id 的不同值。我试过了:

select count(distinct Y.x) from Y;

它可以工作,但在 sql 中我加入了 x 表,这是 uneccesery:

select count(distinct x.id) from y, x where y.x_id = x.id;

这个连接对我来说是不必要的,而且成本很高。没有原生查询有什么办法可以避免吗?

【问题讨论】:

  • 请注意,这里的答案可能取决于实现。例如,Hibernate 可能会生成更高效的查询。
  • 我害怕这个。我使用eclipselink
  • 一个 JPA 解决方案是,如果您不想加入到表 X,请不要将其映射为关系。您可以将“x_id”外键映射为基本,以便在没有连接的查询中使用它。EclipseLink 还具有可以创建的查询键,以将查询中的字段用作基本映射,这样您就可以准确控制何时需要你想要它。至于这个查询,你用的是什么版本?

标签: java oracle jpa eclipselink


【解决方案1】:

您可以尝试使用select count(distinct Y.x.id) from Y(T.x.id 而不是 Y.x)。我不确定,但智能 JPA 实现应该发现只有 id 是必需的并且不会添加连接。

另一种方法是向 Y 添加一个 int 字段,并将只读映射到 x_id 列:

@Entity
class Y {
  @Id
  int id;

  @ManyToOne
  @JoinColumn(name = "x_id")
  X x;

  @Column(name = "x_id", insertable = false, updatable = false, nullable = false)
  int xId;
}

您的查询将只是select count(distinct Y.xId) from Y

【讨论】:

  • 像魅力一样工作。我没有意识到我可以将一列映射到多个字段。谢谢!
【解决方案2】:

对于 JPA 存储库中的计数,您甚至可以使用:

假设有两个实体:EntityAEntityB。如果EntityAEntityB 有任何关系,那么您可以在您的

@Entity
@Table(name = "entity_a")
public class EntityA {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ea_id")
    private Long eaId;

    @ManyToOne
    @JoinColumn(name = "eb_id")
    private EntityB entityB;
    
    ...
}

还有一个EntityB

@Entity
@Table(name = "entity_b")
public class EntityB {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "eb_id")
    private Long ebId;

    ...
}

为此,您可以在EntityAJPARepository 中使用以下方法来获取计数。请记住,_. 的替换,用于存储库中的方法签名。

int countByEntityB_EbId(long ebId);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 2015-05-17
    • 2015-07-31
    • 1970-01-01
    相关资源
    最近更新 更多