Java JDBC-插入并返回生成的id,或者如果重复键,则返回旧id

Java JDBC-插入并返回生成的id,或者如果重复键,则返回旧id,java,mysql,jdbc,Java,Mysql,Jdbc,标题很清楚。。。 我希望能够将一个项目添加到数据库中,如果已经有一个项目具有匹配的唯一列,请返回该项目的id 下面的表达式与我找到的解决方案非常接近 INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3; 我能够使用statement.generatedKeys()获取新id(插入新行时)。 如果重复,语句.generatedKeys()中是否会出现“id”?如果没

标题很清楚。。。 我希望能够将一个项目添加到数据库中,如果已经有一个项目具有匹配的唯一列,请返回该项目的id

下面的表达式与我找到的解决方案非常接近

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
我能够使用statement.generatedKeys()获取新id(插入新行时)。 如果重复,语句.generatedKeys()中是否会出现“id”?如果没有,我怎么取

更新:使用存储过程,以下内容正是我所需要的:

INSERT INTO applications (path, displayName) VALUES (?, ?) 
ON DUPLICATE KEY UPDATE 
   id = LAST_INSERT_ID(id), path = ?, displayName = ?;
SELECT LAST_INSERT_ID() INTO ?;
它适用于我正在处理的不同项目,该项目在.NET中使用MySQL连接器,但不幸的是,在这个Java项目中,存储过程不是我的选项

有没有其他方法可以在同一次网络旅行中发送两份声明?

这似乎是合法的

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=3;
但这似乎很疯狂:

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
是否要更新现有记录的ID字段?引用此记录的记录会发生什么情况

无论如何,在正常更新(forst)的情况下进行猜测。
语句。generatedKeys()
不会返回已经存在的ID。 在这种情况下,您可能需要发出一个额外的select语句(where子句中有唯一的键列:
selectid fromtable,where a=1和b=2
)来查找记录的id

或者,您也可以编写一个存储过程,在这两种情况下插入/更新都返回ID。

这似乎是合法的

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=3;
但这似乎很疯狂:

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
是否要更新现有记录的ID字段?引用此记录的记录会发生什么情况

无论如何,在正常更新(forst)的情况下进行猜测。
语句。generatedKeys()
不会返回已经存在的ID。 在这种情况下,您可能需要发出一个额外的select语句(where子句中有唯一的键列:
selectid fromtable,where a=1和b=2
)来查找记录的id


或者,您也可以编写一个存储过程,执行insert/update操作,在这两种情况下都返回ID。

如果您的目标是防止重复记录,则可以使用主键设置表/。然后,您可以在代码中选择以下路径之一:

  • 以编程方式检查要添加的行的唯一性,并处理该行已存在于表中的情况
  • 尝试插入新行。如果它是重复的,则尝试将失败并出现异常,您可以使用相同的条件找到旧的行。我认为这是一个糟糕的方法

  • 如果您的目标是防止重复记录,则可以使用主键/设置表。然后,您可以在代码中选择以下路径之一:

  • 以编程方式检查要添加的行的唯一性,并处理该行已存在于表中的情况
  • 尝试插入新行。如果它是重复的,则尝试将失败并出现异常,您可以使用相同的条件找到旧的行。我认为这是一个糟糕的方法

  • 所以我和OP有同样的要求。Mysql在重复密钥更新时处理INSERT…的方式很愚蠢,但不幸的是我们不得不接受它。在Mysql 5.5或更高版本上使用ON DUPLICATE时,如果插入时没有重复,JDBC将返回count 1和新插入行的ID。如果所采取的操作是由于重复而进行的更新,则JDBC将返回count 2以及原始行的ID和新生成的ID,即使新ID从未实际插入表中

    通过调用PreparedStatement.getGeneratedKeys()可以获得正确的密钥。第一把钥匙几乎总是你感兴趣的。因此,通过上面的例子:

    INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3;
    
    您可以通过调用以下命令获取插入或更新的ID:

    Long key;
    ResultSet keys = preparedStatement.getGeneratedKeys();
    if (keys.next())
        key = keys.getLong("GENERATED_KEY");
    

    所以我和OP有同样的要求。Mysql在重复密钥更新时处理INSERT…的方式很愚蠢,但不幸的是我们不得不接受它。在Mysql 5.5或更高版本上使用ON DUPLICATE时,如果插入时没有重复,JDBC将返回count 1和新插入行的ID。如果所采取的操作是由于重复而进行的更新,则JDBC将返回count 2以及原始行的ID和新生成的ID,即使新ID从未实际插入表中

    通过调用PreparedStatement.getGeneratedKeys()可以获得正确的密钥。第一把钥匙几乎总是你感兴趣的。因此,通过上面的例子:

    INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3;
    
    您可以通过调用以下命令获取插入或更新的ID:

    Long key;
    ResultSet keys = preparedStatement.getGeneratedKeys();
    if (keys.next())
        key = keys.getLong("GENERATED_KEY");
    

    我没有参考上面的确切例子,我只是说插入到。。。在重复键上通常可以帮助我完成我想要的任务使用存储过程对我来说不是一个选项,在JDBC中有没有一种方法可以在一次网络旅行中执行两条语句?我没有参考上面的确切示例,我只是说插入到。。。在复制密钥上通常可以帮助我完成我想要的任务使用存储过程对我来说不是一个选项,JDBC中有没有一种方法可以在一次网络旅行中执行两条语句?实际上,复制时添加了两个ID。我不能只使用第一个,因为我试图一次插入多行,而这个“额外的从未使用过的id”将一切都搞定。实际上,复制时似乎添加了两个id。我不能只使用第一行,因为我试图一次插入多行,而这个“额外的从未使用过的id”会搞定一切。