我想在数据库中插入一个记录(在我的情况下是Microsoft SQL Server)使用Java中的JDBC。同时,我想获取插入ID。我如何使用JDBC API实现这一点?


当前回答

当使用Statement时遇到“不支持的功能”错误。RETURN_GENERATED_KEYS,试试这个:

String[] returnId = { "BATCHID" };
String sql = "INSERT INTO BATCH (BATCHNAME) VALUES ('aaaaaaa')";
PreparedStatement statement = connection.prepareStatement(sql, returnId);
int affectedRows = statement.executeUpdate();

if (affectedRows == 0) {
    throw new SQLException("Creating user failed, no rows affected.");
}

try (ResultSet rs = statement.getGeneratedKeys()) {
    if (rs.next()) {
        System.out.println(rs.getInt(1));
    }
    rs.close();
}

其中BATCHID是自动生成的id。

其他回答

如果它是一个自动生成的键,那么你可以使用Statement#getGeneratedKeys()。您需要在与INSERT使用的语句相同的Statement上调用它。首先需要使用statement创建语句。RETURN_GENERATED_KEYS通知JDBC驱动程序返回密钥。

这里有一个基本的例子:

public void create(User user) throws SQLException {
    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL_INSERT,
                                      Statement.RETURN_GENERATED_KEYS);
    ) {
        statement.setString(1, user.getName());
        statement.setString(2, user.getPassword());
        statement.setString(3, user.getEmail());
        // ...

        int affectedRows = statement.executeUpdate();

        if (affectedRows == 0) {
            throw new SQLException("Creating user failed, no rows affected.");
        }

        try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
            if (generatedKeys.next()) {
                user.setId(generatedKeys.getLong(1));
            }
            else {
                throw new SQLException("Creating user failed, no ID obtained.");
            }
        }
    }
}

注意,您依赖于JDBC驱动程序来决定它是否工作。目前,最后的大多数版本都可以工作,但如果我是正确的,Oracle JDBC驱动程序在这方面仍然有些麻烦。MySQL和DB2已经支持它很多年了。PostgreSQL不久前开始支持它。我不能评论MSSQL,因为我从未使用过它。

对于Oracle,您可以在同一个事务中的INSERT语句后直接调用带有RETURNING子句或SELECT CURRVAL(sequencename)(或任何特定于db的语法)的CallableStatement来获得最后生成的密钥。看看这个答案。

当使用Statement时遇到“不支持的功能”错误。RETURN_GENERATED_KEYS,试试这个:

String[] returnId = { "BATCHID" };
String sql = "INSERT INTO BATCH (BATCHNAME) VALUES ('aaaaaaa')";
PreparedStatement statement = connection.prepareStatement(sql, returnId);
int affectedRows = statement.executeUpdate();

if (affectedRows == 0) {
    throw new SQLException("Creating user failed, no rows affected.");
}

try (ResultSet rs = statement.getGeneratedKeys()) {
    if (rs.next()) {
        System.out.println(rs.getInt(1));
    }
    rs.close();
}

其中BATCHID是自动生成的id。

如果您正在使用JDBC(用MySQL测试),并且只想要最后插入的ID,有一种简单的方法可以获得它。我使用的方法如下:

public static Integer insert(ConnectionImpl connection, String insertQuery){

    Integer lastInsertId = -1;
    try{
        final PreparedStatement ps = connection.prepareStatement(insertQuery);
        ps.executeUpdate(insertQuery);
        final com.mysql.jdbc.PreparedStatement psFinal = (com.mysql.jdbc.PreparedStatement) ps;
        lastInsertId = (int) psFinal.getLastInsertID();
        connection.close();
    } catch(SQLException ex){
        System.err.println("Error: "+ex);
    }

    return lastInsertId;
}

同样,(以防万一)获取ConnectionImpl的方法如下:

public static ConnectionImpl getConnectionImpl(){
    ConnectionImpl conexion = null;

    final String dbName = "database_name";
    final String dbPort = "3306";
    final String dbIPAddress = "127.0.0.1";
    final String connectionPath = "jdbc:mysql://"+dbIPAddress+":"+dbPort+"/"+dbName+"?autoReconnect=true&useSSL=false";
    
    final String dbUser = "database_user";
    final String dbPassword = "database_password";
    try{
        conexion = (ConnectionImpl) DriverManager.getConnection(connectionPath, dbUser, dbPassword);
    }catch(SQLException e){
        System.err.println(e);
    }
    
    return conexion;
}

记得将连接器/J添加到项目引用的库中。

在我的例子中,连接器/J版本是5.1.42。如果您想使用连接器/J的更现代的版本,例如8.0.28版本,那么您可能必须对connectionPath应用一些更改。

在文件中,请记住导入以下资源:

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.mysql.jdbc.ConnectionImpl;

希望这对你有所帮助。

Connection cn = DriverManager.getConnection("Host","user","pass");
Statement st = cn.createStatement("Ur Requet Sql");
int ret  = st.execute();

在我的例子中是>

ConnectionClass objConnectionClass=new ConnectionClass();
con=objConnectionClass.getDataBaseConnection();
pstmtGetAdd=con.prepareStatement(SQL_INSERT_ADDRESS_QUERY,Statement.RETURN_GENERATED_KEYS);
pstmtGetAdd.setString(1, objRegisterVO.getAddress());
pstmtGetAdd.setInt(2, Integer.parseInt(objRegisterVO.getCityId()));
int addId=pstmtGetAdd.executeUpdate();              
if(addId>0)
{
    ResultSet rsVal=pstmtGetAdd.getGeneratedKeys();
    rsVal.next();
    addId=rsVal.getInt(1);
}