JDBC中如何获取插入ID?
我想使用 Java 中的 JDBC 在数据库(在我的例子中是 Microsoft SQL Server)中INSERT
一条记录。同时我想获取插入ID。如何使用 JDBC API 实现此目的?
I want to INSERT
a record in a database (which is Microsoft SQL Server in my case) using JDBC in Java. At the same time, I want to obtain the insert ID. How can I achieve this using JDBC API?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
如果它是自动生成的密钥,那么您可以使用
Statement#getGenerateKeys()
为此。您需要在与用于INSERT
的语句相同的Statement
上调用它。您首先需要使用Statement.RETURN_GENERATED_KEYS
通知 JDBC 驱动程序返回密钥。下面是一个基本示例:
请注意,您依赖 JDBC 驱动程序来确定它是否有效。目前,大多数最新版本都可以工作,但如果我是正确的,Oracle JDBC 驱动程序在这方面仍然有些麻烦。 MySQL 和 DB2 已经支持它很长时间了。 PostgreSQL不久前开始支持它。我无法评论 MSSQL,因为我从未使用过它。
对于 Oracle,您可以使用
RETURNING
子句或SELECT CURRVAL(sequencename)
(或任何特定于数据库的语法来执行此操作)调用CallableStatement
) 直接在同一事务中的INSERT
之后获取最后生成的密钥。另请参阅此答案。If it is an auto generated key, then you can use
Statement#getGeneratedKeys()
for this. You need to call it on the sameStatement
as the one being used for theINSERT
. You first need to create the statement usingStatement.RETURN_GENERATED_KEYS
to notify the JDBC driver to return the keys.Here's a basic example:
Note that you're dependent on the JDBC driver as to whether it works. Currently, most of the last versions will work, but if I am correct, Oracle JDBC driver is still somewhat troublesome with this. MySQL and DB2 already supported it for ages. PostgreSQL started to support it not long ago. I can't comment about MSSQL as I've never used it.
For Oracle, you can invoke a
CallableStatement
with aRETURNING
clause or aSELECT CURRVAL(sequencename)
(or whatever DB-specific syntax to do so) directly after theINSERT
in the same transaction to obtain the last generated key. See also this answer.创建生成列
将此生成的列传递到您的语句
使用
ResultSet
对象获取语句上的GenerateKeysCreate Generated Column
Pass this geneated Column to your statement
Use
ResultSet
object to fetch the GeneratedKeys on Statement使用
Statement.RETURN_GENERATED_KEYS
时遇到“不支持的功能”错误时,请尝试以下操作:其中
BATCHID
是自动生成的 ID。When encountering an 'Unsupported feature' error while using
Statement.RETURN_GENERATED_KEYS
, try this:Where
BATCHID
is the auto generated id.我从基于 JDBC 的单线程应用程序访问 Microsoft SQL Server 2008 R2,并在不使用 RETURN_GENERATED_KEYS 属性或任何PreparedStatement 的情况下拉回最后一个 ID。看起来像这样:
这篇博客文章很好地隔离了三个主要的 SQL Server“最后 ID”选项:
http://msjawahar.wordpress.com/2008/01/25/how-to-find-the-last-identity-value-inserted-in-the-sql-server/ - 避风港'还不需要另外两个。
I'm hitting Microsoft SQL Server 2008 R2 from a single-threaded JDBC-based application and pulling back the last ID without using the RETURN_GENERATED_KEYS property or any PreparedStatement. Looks something like this:
This blog post nicely isolates three main SQL Server "last ID" options:
http://msjawahar.wordpress.com/2008/01/25/how-to-find-the-last-identity-value-inserted-in-the-sql-server/ - haven't needed the other two yet.
我只想回答,而不是 评论邮政。
接口java. sql.PreparedStatement
columnIndexes « 您可以使用接受columnIndexes 和SQL 语句的prepareStatement 函数。
其中columnIndexes允许的常量标志是Statement.RETURN_GENERATED_KEYS1< /a> 或 Statement.NO_GENERATED_KEYS[2],可能包含一个或多个“?”的 SQL 语句IN 参数占位符。
语法 «
示例:
columnNames « 列出列名称,如
'id'、'uniqueID'、...
。在包含应返回的自动生成键的目标表中。如果 SQL 语句不是INSERT
语句,驱动程序将忽略它们。语法 «
示例:
完整示例:
Instead of a comment, I just want to answer post.
Interface java.sql.PreparedStatement
columnIndexes « You can use prepareStatement function that accepts columnIndexes and SQL statement.
Where columnIndexes allowed constant flags are Statement.RETURN_GENERATED_KEYS1 or Statement.NO_GENERATED_KEYS[2], SQL statement that may contain one or more '?' IN parameter placeholders.
SYNTAX «
Example:
columnNames « List out the columnNames like
'id', 'uniqueID', ...
. in the target table that contain the auto-generated keys that should be returned. The driver will ignore them if the SQL statement is not anINSERT
statement.SYNTAX «
Example:
Full Example:
我正在使用 SQLServer 2008,但我有一个开发限制:我无法为其使用新的驱动程序,我必须使用“com.microsoft.jdbc.sqlserver.SQLServerDriver”(我无法使用“ com.microsoft.sqlserver.jdbc.SQLServerDriver”)。
这就是为什么解决方案
conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
为我引发了 java.lang.AbstractMethodError 。在这种情况下,我发现的一种可能的解决方案是微软建议的旧方案:
如何使用 JDBC 检索 @@IDENTITY 值
这个解决方案对我有用!
我希望这有帮助!
I'm using SQLServer 2008, but I have a development limitation: I cannot use a new driver for it, I have to use "com.microsoft.jdbc.sqlserver.SQLServerDriver" (I cannot use "com.microsoft.sqlserver.jdbc.SQLServerDriver").
That's why the solution
conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
threw a java.lang.AbstractMethodError for me.In this situation, a possible solution I found is the old one suggested by Microsoft:
How To Retrieve @@IDENTITY Value Using JDBC
This solution worked for me!
I hope this helps!
您可以使用以下 java 代码来获取新插入的 id。
You can use following java code to get new inserted id.
也可以将其与普通的
Statement
一起使用(不仅仅是PreparedStatement
)It is possible to use it with normal
Statement
's as well (not justPreparedStatement
)使用 Hibernate 的 NativeQuery,您需要返回 ResultList 而不是 SingleResult,因为 Hibernate 会修改本机查询,
就像
您尝试获取单个结果一样,这会导致大多数数据库(至少是 PostgreSQL)抛出语法错误。然后,您可以从列表(通常仅包含一项)中获取结果 id。
With Hibernate's NativeQuery, you need to return a ResultList instead of a SingleResult, because Hibernate modifies a native query
like
if you try to get a single result, which causes most databases (at least PostgreSQL) to throw a syntax error. Afterwards, you may fetch the resulting id from the list (which usually contains exactly one item).
大多数其他人建议为此使用 JDBC API,但就我个人而言,我发现对于大多数驱动程序来说这非常痛苦。事实上,您可以只使用本机 T-SQL 功能,
OUTPUT
子句:这是 SQL Server 以及其他一些 SQL 方言(例如 Firebird、 MariaDB、PostgreSQL,您可以在其中使用
RETURNING
而不是OUTPUT
)。我在博客中详细介绍了此主题详细信息请参见此处。
Most others have suggested to use JDBC API for this, but personally, I find it quite painful to do with most drivers. When in fact, you can just use a native T-SQL feature, the
OUTPUT
clause:This is the simplest solution for SQL Server as well as a few other SQL dialects (e.g. Firebird, MariaDB, PostgreSQL, where you'd use
RETURNING
instead ofOUTPUT
).I've blogged about this topic more in detail here.
就我而言 ->
In my case ->
如果您使用的是Spring JDBC,则可以使用Spring的生成Keyolder类来获取插入的ID。
看到这个答案...
如何使用Spring jdbctemplate jdbctemplate in .update(字符串SQL,obj ... args)
If you are using Spring JDBC, you can use Spring's GeneratedKeyHolder class to get the inserted ID.
See this answer...
How to get inserted id using Spring Jdbctemplate.update(String sql, obj...args)
如果您使用的是JDBC(使用MySQL进行了测试),并且只需要使用最后的插入ID,则有一种简单的方法来获取它。我正在使用的方法如下:(
以及以防万一)获取
ConnectionImpl
的方法如下:请记住添加 connector/j 到引用的库中。
就我而言,连接器/J版本是5.1.42。也许如果要使用更现代的连接器/J(例如版本8.0.28),则必须对
ConnectionPath
应用一些更改。在文件中,请记住导入以下资源:
希望这会有所帮助。
If you are using JDBC (tested with MySQL) and you just want the last inserted ID, there is an easy way to get it. The method I'm using is the following:
Also, (and just in case) the method to get the
ConnectionImpl
is the following:Remember to add the connector/J to the project referenced libraries.
In my case, the connector/J version is the 5.1.42. Maybe you will have to apply some changes to the
connectionPath
if you want to use a more modern version of the connector/J such as with the version 8.0.28.In the file, remember to import the following resources:
Hope this will be helpful.
您可以使用
executeQuery(query)
函数,然后添加
返回 *
子句到查询指定列名称
而是
*
您可以为示例create表第一个
创建查询
应用查询
键是您的结果。因此,您可以返回任何列集或完整对象
You can use
executeQuery(query)
functionand add
RETURNING *
clause to your queryinstead
*
you can specify column nameFor example
create table first
create query
apply query
keys is your result. So you can return any column set or full object
要获取 MSSQL 中表上最后插入的 ID,有多种选项:
我使用的是这个:
还有一些其他选项,例如 SCOPE_IDENTITY() 和 @@IDENTITY也是如此,但上面的方法要容易得多。
示例:
有关详细信息
我希望这有帮助......
To get the last inserted Id on a table in MSSQL there are various options:
What I use is this one:
There are some other options like SCOPE_IDENTITY() and @@IDENTITY as well but the above is much easier.
Example:
For more info check this out
I hope this helps...