简单的Jdbc模板。 - 插入和检索ID
我使用 simpleJdbcTemplate 将数据放入数据库中。
simpleJdbcTemplate.update("insert into TABLE values(default)");
我不想放置任何数据,因为我不需要它来进行单元测试。
如何从插入的行中获取 id?我可以检索当前序列值,但如果其他人进行插入,那么我将获得下一个序列值。
有没有办法使用 simpleJdbcTemplate 插入行并获取 id?更新方法重新调整插入的行数,我想要 ID。感谢您的帮助。
I'm putting the data into database with simpleJdbcTemplate.
simpleJdbcTemplate.update("insert into TABLE values(default)");
I dont want to put any data because i dont need it for my unit test purpose.
How can i get the id from the inserted row? I can retriev the current sequence value but if somebody else will do a insert then i will be get a next sequence value.
Is there any way to use simpleJdbcTemplate to insert a row and get id? The update method retuns the number of inserted rows and i would like to have the id. Thank you for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你找到答案了吗?如果没有,请尝试使用
SimpleJdbcInsert
代替。例如:
然后检索
Did you find the answer yet? If not, try to use
SimpleJdbcInsert
instead.For example:
then retrieve
您需要手动处理序列才能轻松获取 id,而无需将自己束缚在任何特定的 RDBMS 产品中。
这意味着您必须指定特定于部署的
DataFieldMaxValueIncrementer
bean 并将其注入到数据库处理类中,就像您最有可能对DataSource
所做的那样。 bean 定义应该类似于这样(此示例适用于 PostgreSQL):然后,当您的类中有增量器时,您可以在代码中使用它来获取 id 值,如下所示:
You need to manually handle the sequence to get the id easily without tying yourself into any specific RDBMS product.
This means that you have to specify a deployment-specific
DataFieldMaxValueIncrementer
bean and inject that to your database handling class just as you most likely do with yourDataSource
. The bean definition should look something like this (this example is for PostgreSQL):Then when you have the incrementer in your class, you can use it in your code to get the id value somewhat like this:
我不认为它看起来像那么困难.. :-O
Y 不要尝试类似的事情:
现在 newID 将包含新插入的行 ID。
干杯..!! :)
I dun think its as tough as it seems.. :-O
Y dont you try something like :
Now newID wil contains the newly Inserted row ID.
CHEERS..!! :)
使用 NamedParameterJdbcTemplate 你就有了一个密钥持有者。它抽象了 DBMS 密钥生成。
检查创建方法。
Using NamedParameterJdbcTemplate you have a keyholder. It abstracts DBMS key generation.
Check create method.
您应该首先从适当的
序列
中查询id
,然后在插入语句中提供该id
。就这么简单。此外,我们可以将其称为集成测试,而不是单元测试。您可能想参考这个SO线程来了解有关集成测试和 ids。
[评论后编辑]
在这种情况下,请删除该触发器。并在进行
插入
之前直接从序列
检索id
。好吧,您可以在桌子上触发
SELECT ... FOR UPDATE
,并获取最后一个id
,并将其增加1。如果您的id
code> 不是连续的,我猜情况并非如此,您可以保存特定于 Oracle AFAIK 的ROWID
。然后使用它查询id
。事实上,这一切都可以解决。注意: 我强烈建议您查看 Aaron Digulla 的帖子。看看是否足够。
You should first query the
id
from the appropriatesequence
, and then provide thatid
in your insert statement. As simple as that.Further, we call it integration test, instead of unit test, arguably. You might like to refer to this SO thread to have an idea regarding integration tests and ids.
[Edited after comment]
In that case, get rid of that trigger. And retrieve the
id
from thesequence
directly, prior to make ainsert
.Well, you can fire a
SELECT... FOR UPDATE
on the table, and grab the lastid
, and increment that by 1. If yourid
is not sequential, which I guess wouldn't be the case, you can hold theROWID
, specific to Oracle AFAIK. And then query forid
using that. Indeed, its all kinda work around.Note: I strongly suggest you to look at Aaron Digulla's post. See if any of that suffice.
回答这个问题:您想通过测试实现什么目标?检查更新运行是否没有错误?你每次都会得到一个新的ID吗?该表存在吗?
根据答案,您必须修改您的测试。如果您只是想知道语句的语法是否正确,则无需执行任何操作,只需运行该语句即可(如果出现错误导致测试失败,则会抛出异常)。
如果要确保每次都获得新的 ID,则必须查询序列两次并检查第二个值是否与第一个值不同。
如果您想检查是否插入了具有新唯一 ID 的行,只需运行插入并检查它是否返回 1。如果有效,您就会知道主键(ID)没有被违反,并且行已插入。因此,“添加唯一ID”机制必须起作用。
[编辑] 无法测试将 ID 添加到新行的触发器,因为 Oracle 无法返回它刚刚创建的 ID。您可以读取该序列,但不能保证
nextval-1
会给您与触发器看到的相同结果。您可以尝试
select max(ID)
,但如果其他人在您运行查询之前插入另一行并提交它(使用默认事务级别READ_COMMITTED
),则可能会失败。因此,我强烈建议摆脱触发器并使用其他人使用的标准两步(“获取新 ID”加上“插入新 ID”)算法。它将使您的测试更加简单且不那么脆弱。
Answer this question: What are you trying to achieve with your test? Check that the update runs without error? That you get a new ID every time? That the table exists?
Depending on the answer, you must modify your test. If you just want to know that the syntax of the statement is correct, you don't need to do anything but run the statement (it will throw an exception if there is an error making the test fail).
If you want to make sure you get a new ID every time, you must query the sequence two times and check that the second value is different from the first.
If you want to check that a row with a new unique ID is inserted, just run the insert and check that it returns 1. If it works, you'll know that the primary key (the ID) wasn't violated and that a row was inserted. Hence, the "add with unique ID" mechanism must work.
[EDIT] There is no way to test a trigger which adds an ID to a new row because Oracle has no means to return the ID it just created. You could read the sequence but there is no guarantee that
nextval-1
will give you the same result that the trigger saw.You could try
select max(ID)
but that can fail if anyone else inserts another row and commits it before you can run the query (using the default transaction levelREAD_COMMITTED
).Therefore I strongly suggest to get rid of the trigger and use the standard 2-step ("get new ID" plus "insert with new ID") algorithm that anyone else uses. It will make your tests more simple and less brittle.
simpleJdbcTemplate 已弃用,取而代之的是 NamedParameterJdbcTemplate。
Pello X 有正确的答案,但他提交的内容太繁琐,难以理解。
简化:
如果您有一个名为 SAMPLE 的非常简单的表,其中包含名为 NAME 的列和生成的名为 bigint 类型的 ID 的主键:
这将返回更新中唯一生成的键,如果超过 1 行受到影响,则返回 -1。
请注意,由于只有 1 个生成的键,所以我不关心列名称。
如果生成了超过 1 个密钥,请查看 http://docs.spring.io/spring/docs/3.2.7.RELEASE/javadoc-api/org/springframework/jdbc/support/KeyHolder。 html#getKeys%28%29
simpleJdbcTemplate is deprecated in favour of NamedParameterJdbcTemplate.
Pello X has the correct answer, but his submission is too cumbersome to understand.
Simplified:
If you have a very simple table called SAMPLE with a column called NAME and a primary key that is generated called ID of type bigint:
This will return the only generated key in the update or -1 if more than 1 row was affected.
Note that since there was only 1 generated key I didn't care about the column name.
If there is more than 1 key that is generated, look into http://docs.spring.io/spring/docs/3.2.7.RELEASE/javadoc-api/org/springframework/jdbc/support/KeyHolder.html#getKeys%28%29
通过 Spring 的
JdbcTemplate
,您可以将其update
方法与PreparedStatementCreator
和GeneratedKeyholder
一起使用来保存对象的主键新插入的行。With Spring's
JdbcTemplate
you can use itsupdate
method with aPreparedStatementCreator
and aGeneratedKeyholder
to hold the primary key of the newly inserted row.