我正在使用Java开发应用程序,我有一个Oracle数据库。要存储数据我正在使用JDBC。在Oracle数据库中,没有像自动增量那样的东西。所以我使用触发器来获得最新的主键。
目前应用程序已经实现,我将保存的主键恢复。设置connection.setAutoCommit(true)时会发生这种情况。如果我设置了connection.setAutoCommit(false),我想知道是否有可能获得主键?
我之所以这样问是因为我遇到了多个线程的并发问题,其中一个线程保存数据,另一个线程可以获取保存的记录。我不希望这种情况发生。我希望在另一个线程查看数据之前顺序完成代码。所以,我试图调查JDBC行锁定,但不存在这样的情况。
这个主键是在同一个Thread中输入另一个方法所必需的。
答案 0 :(得分: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);
}
}
}
答案 1 :(得分:1)
除了@Mark Rotteveel提供的解决方案之外,您还可以使用Connection.prepareStatement(String, String[])指定要从中返回值的确切列。在这种情况下,如果您为主键提供列名,则该值将位于从Statement.getGeneratedKeys返回的ResultSet中。
另一种选择是从序列中获取主键的值,并作为insert语句的一部分插入,而不是使用触发器:
select mysequence.nextval from dual