Java JDBC 主键 Oracle 数据库
Posted
技术标签:
【中文标题】Java JDBC 主键 Oracle 数据库【英文标题】:Java JDBC Primary Key Oracle Database 【发布时间】:2014-06-10 08:26:11 【问题描述】:我正在使用 Java 开发一个应用程序,并且我有一个 Oracle 数据库。为了存储数据,我使用 JDBC。在 Oracle 数据库中,没有什么能比得上自动增量。所以我使用触发器来获取最新的主键。
目前应用程序已经实现,我得到了保存的主键。设置 connection.setAutoCommit(true) 时会发生这种情况。我想知道如果我设置了connection.setAutoCommit(false) 是否可以获取主键?
我问这个的原因是因为我遇到了多个线程的并发问题,一个线程保存数据,另一个线程可以获取保存的记录。我不希望这种情况发生。我希望代码在其他线程查看数据之前按顺序完成。所以,我试图调查 JDBC 行锁,但没有这样的东西存在。
在同一个线程中输入另一个方法需要这个主键。
【问题讨论】:
为什么不能使用oracle sequences
而不是触发器
如何将数据持久化到 Oracle 表中?即您使用存储过程还是 DML 语句?
我不记得名字了,但是是的,序列和触发器都被使用了。
我使用 PreparedStatement 和 SELECT 等 SQL 查询。
@user3189663 序列不受事务控制,如果同时执行多个插入操作,使用 SELECT sequenceName.CURRVAL FROM DUAL
选择主键可能会产生错误的结果。
【参考方案1】:
检索主键的正确方法是使用getGeneratedKeys
工具(可以通过使用Statement.RETURN_GENERATED_KEYS
值和Statement.execute*
或Connection.prepareStatement
方法之一来激活。
在大多数数据库中,这可用于直接检索主键。然而,在 Oracle 的情况下,这将允许您获取 ROWID
,此 ROWID
可用于查询表中插入的行并获取主键。
例如:
stmt.executeUpdate("INSERT INTO theTable(column1) VALUES ('a')",
Statement.RETURN_GENERATED_KEYS);
ResultSet keys = stmt.getGeneratedKeys();
int primaryKey = -1;
if (keys.next())
try (PreparedStatement keyStatement =
connection.prepareStatement("SELECT ID FROM theTable WHERE ROWID = ?"))
keyStatement.setRowId(keys.getRowId(1));
try (ResultSet rs = keyStatement.executeQuery())
primaryKey = rs.getInt(1);
【讨论】:
【参考方案2】:除了@Mark Rotteveel 提供的解决方案之外,您还可以使用Connection.prepareStatement(String, String[]) 指定您希望从中返回值的确切列。在这种情况下,如果您为主键提供列名,则该值将在从Statement.getGeneratedKeys 返回的 ResultSet 中。
另一种选择是从序列中获取主键的值并作为插入语句的一部分插入,而不是使用触发器:
select mysequence.nextval from dual
【讨论】:
以上是关于Java JDBC 主键 Oracle 数据库的主要内容,如果未能解决你的问题,请参考以下文章