【问题标题】:How to make JpaRepository only save the IDs that do not yet exist?如何让 JpaRepository 只保存尚不存在的 ID?
【发布时间】:2019-08-04 06:58:34
【问题描述】:

给定一张桌子:

CREATE TABLE mytable (
    some_id      BIGINT PRIMARY KEY NOT NULL,
    timestamp    TIMESTAMP WITH TIME ZONE NOT NULL
);

一个实体:

@Entity
@Table(name = "mytable")
class Thing(
        @Id
        var some_id: Long,
        var timestamp = ZonedDateTime.now()
)

一个存储库:

interface MyRepo : JpaRepository<Thing, Long>

还有这个循环:

val myRepo: MyRepo

while (True) {
    val some_id: Long = ComesFromSomewhere()
    if (myRepo.findById(some_id) == null) {
        myRepo.save(Thing(some_id))
    }
}

目的是仅在该 ID 第一次出现时存储该 ID 的时间戳。

上面的代码有效,但在我的用例中每秒产生超过 100 个 save 事务,这给数据库带来了沉重的负担。所以我想优化,积累一批Things,然后使用saveAll之类的东西,把所有东西都放在一个事务中。

不过,仅使用 saveAll 也会覆盖表中已存在的 ID 的时间戳,这不是有意的。

如何解决这个问题,理想情况下不需要太多低级代码?

【问题讨论】:

    标签: spring-boot kotlin spring-data-jpa


    【解决方案1】:

    如果您将上述循环放在 @Transactional 方法中,您应该只有 1 个事务 - 当然有很多 INSERT-s 和 SELECT-s,但只有 1 个事务。这将减轻数据库的负担。

    此外,save() 是在这种情况下调用的正确方法。还有一个名为 saveAndFlush() 的方法,它与您想要的相反。

    您还可以通过执行 repo.findAllById() 而不是大量 findById() 来限制 SELECT 的数量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多