触发额外查询以获取序列下一个值-spring JPA
Posted
技术标签:
【中文标题】触发额外查询以获取序列下一个值-spring JPA【英文标题】:Extra query getting triggered for fetching sequence next value - spring JPA 【发布时间】:2020-12-25 14:52:48 【问题描述】:我有一个主键列从 oracle 序列中获取值的表。如果我在表中插入一条记录,最好的方法是 -
INSERT INTO TABLE VALUES(SCHEMA.SEQUENCE.NEXTVAL, value1, value2, value3)
但是,当我使用 JPARepository 中的保存方法时,在创建对象时运行一个仅获取 SCHEMA.SEQUENCE.NEXTVAL
的选择查询,然后在事务结束时运行一个额外的 INSERT 查询。
SELECT SCHEMA.SEQUENCE.NEXTVAL FROM DUAL
INSERT INTO TABLE VALUES(val_from_select_query, value1, value2, value3)
这导致几乎双倍的时间。有没有办法配置我的实体,使其在插入查询中获取序列值,从而导致总体上只有 1 次往返数据库?
【问题讨论】:
【参考方案1】:序列的增量是多少? 因为这只发生在您在增量边界内插入的第一行。
假设增量为 50,当您插入多个值(即使有延迟)时,您会看到:
SELECT SCHEMA.SEQUENCE.NEXTVAL FROM DUAL
INSERT INTO TABLE VALUES(val_from_select_query, value1, value2, value3)
INSERT INTO TABLE VALUES(val_from_select_query+1, value1, value2, value3)
INSERT INTO TABLE VALUES(val_from_select_query+2, value1, value2, value3)
...
INSERT INTO TABLE VALUES(val_from_select_query+48, value1, value2, value3)
INSERT INTO TABLE VALUES(val_from_select_query+49, value1, value2, value3)
SELECT SCHEMA.SEQUENCE.NEXTVAL FROM DUAL
INSERT INTO TABLE VALUES(val_from_select_query2, value1, value2, value3)
INSERT INTO TABLE VALUES(val_from_select_query2+1, value1, value2, value3)
...
我通常通过create sequence a_sequence_name start with 1 increment by 50
将增量设置为 50。
然而,这会导致 ids (1, 2, 3, 4, 5, 6, 7, 51, 52, 101
) 出现一些差距,例如重新启动应用程序时。
【讨论】:
我必须根据收到的请求在表中插入 n 条记录。所以,我不能总是增加 50。此外,我放了一个循环并创建了 10 个对象并为每个对象调用 save。在这种情况下,select 和 insert 语句仍然被触发了 10 次。 您不必总是递增 50,它只是数据库中序列的设置。 Hibernate 会询问“当前起点”,然后它知道它可以填充接下来的 50 个 id,所以它不会再询问了。您是说您放置了一个循环来创建 10 个对象,并且 select 被调用了 10 次-您是否忘记将 DB 序列更改为增加 50(或任何其他大于 1 的数字)?这不必与您的“批次”相匹配 - 因为这些东西往往是动态的(例如,每个请求都不同)。【参考方案2】:使用 ID 生成策略GenerationType.AUTO
,JPA(或者更确切地说是底层 ORM 框架)需要知道生成的 ID,以便它可以在创建的对象上设置它。由于 INSERT 语句不返回 ID,因此需要额外的 SELECT。
在 Oracle 12 上,您可以使用 GenerationType.IDENTITY
,这将产生一条语句:
INSERT INTO <TABLE> (...) values (?) RETURNING <PRIMARY_KEY> INTO ?
【讨论】:
以上是关于触发额外查询以获取序列下一个值-spring JPA的主要内容,如果未能解决你的问题,请参考以下文章
用于从序列生成 id 的 Oracle 触发器的 HIbernate 问题
序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询