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 数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何得到JDBC Insert 语句执行后插入Oracle 数据库记录的主键

Java程序连接Oracle数据库时怎么设置主键自增

简单的jdbc框架

java(jdbc)向oracle中插入记录

java使用jdbc连接oracle数据库怎么关闭连接

火花 jdbc 读取调整 where 没有主键的表