Spec-Zone .ru
спецификации, руководства, описания, API

21.3.6.4. Получение AUTO_INCREMENT Значения столбцов через JDBC

Перед версией 3.0 API JDBC не было никакого стандартного способа получить значения ключа от баз данных, которые поддерживали автоматический инкремент или столбцы идентификационных данных. С более старыми драйверами JDBC для MySQL Вы могли всегда использовать специфичный для MySQL метод на Statement интерфейс, или проблема запрос SELECT LAST_INSERT_ID() после издания INSERT к таблице, которая имела AUTO_INCREMENT ключ. Используя специфичный для MySQL вызов метода не переносимо, и выходящий a SELECT добраться AUTO_INCREMENT значение ключа требует другой поездки туда и обратно к базе данных, которая не настолько эффективна насколько возможно. Следующие фрагменты кода демонстрируют три различных способа получить AUTO_INCREMENT значения. Во-первых, мы демонстрируем использование нового JDBC 3.0 метода getGeneratedKeys() который является теперь привилегированным методом, чтобы использовать, если Вы должны получить AUTO_INCREMENT у ключей и есть доступ к JDBC 3.0. Второй пример показывает, как можно получить то же самое значение, используя стандарт SELECT LAST_INSERT_ID() запрос. Заключительный пример показывает, как обновляемые наборы результатов могут получить AUTO_INCREMENT значение при использовании insertRow() метод.

Пример 21.8. Connector/J: Получение AUTO_INCREMENT столбец valuesusing Statement.getGeneratedKeys()

   Statement stmt = null;   ResultSet rs = null;   try {    //    // Create a Statement instance that we can use for    // 'normal' result sets assuming you have a    // Connection 'conn' to a MySQL database already    // available    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,                                java.sql.ResultSet.CONCUR_UPDATABLE);    //    // Issue the DDL queries for the table for this example    //    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");    stmt.executeUpdate(            "CREATE TABLE autoIncTutorial ("            + "priKey INT NOT NULL AUTO_INCREMENT, "            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");    //    // Insert one row that will generate an AUTO INCREMENT    // key in the 'priKey' field    //    stmt.executeUpdate(            "INSERT INTO autoIncTutorial (dataField) "            + "values ('Can I Get the Auto Increment Field?')",            Statement.RETURN_GENERATED_KEYS);    //    // Example of using Statement.getGeneratedKeys()    // to retrieve the value of an auto-increment    // value    //    int autoIncKeyFromApi = -1;    rs = stmt.getGeneratedKeys();    if (rs.next()) {        autoIncKeyFromApi = rs.getInt(1);    } else {        // throw an exception from here    }    rs.close();    rs = null;    System.out.println("Key returned from getGeneratedKeys():"        + autoIncKeyFromApi);} finally {    if (rs != null) {        try {            rs.close();        } catch (SQLException ex) {            // ignore        }    }    if (stmt != null) {        try {            stmt.close();        } catch (SQLException ex) {            // ignore        }    }}

Пример 21.9. Connector/J: Получение AUTO_INCREMENT столбец valuesusing SELECT LAST_INSERT_ID()

   Statement stmt = null;   ResultSet rs = null;   try {    //    // Create a Statement instance that we can use for    // 'normal' result sets.    stmt = conn.createStatement();    //    // Issue the DDL queries for the table for this example    //    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");    stmt.executeUpdate(            "CREATE TABLE autoIncTutorial ("            + "priKey INT NOT NULL AUTO_INCREMENT, "            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");    //    // Insert one row that will generate an AUTO INCREMENT    // key in the 'priKey' field    //    stmt.executeUpdate(            "INSERT INTO autoIncTutorial (dataField) "            + "values ('Can I Get the Auto Increment Field?')");    //    // Use the MySQL LAST_INSERT_ID()    // function to do the same thing as getGeneratedKeys()    //    int autoIncKeyFromFunc = -1;    rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");    if (rs.next()) {        autoIncKeyFromFunc = rs.getInt(1);    } else {        // throw an exception from here    }    rs.close();    System.out.println("Key returned from " +                       "'SELECT LAST_INSERT_ID()': " +                       autoIncKeyFromFunc);} finally {    if (rs != null) {        try {            rs.close();        } catch (SQLException ex) {            // ignore        }    }    if (stmt != null) {        try {            stmt.close();        } catch (SQLException ex) {            // ignore        }    }}

Пример 21.10. Connector/J: Получение AUTO_INCREMENT столбец valuesin Updatable ResultSets

   Statement stmt = null;   ResultSet rs = null;   try {    //    // Create a Statement instance that we can use for    // 'normal' result sets as well as an 'updatable'    // one, assuming you have a Connection 'conn' to    // a MySQL database already available    //    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,                                java.sql.ResultSet.CONCUR_UPDATABLE);    //    // Issue the DDL queries for the table for this example    //    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");    stmt.executeUpdate(            "CREATE TABLE autoIncTutorial ("            + "priKey INT NOT NULL AUTO_INCREMENT, "            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");    //    // Example of retrieving an AUTO INCREMENT key    // from an updatable result set    //    rs = stmt.executeQuery("SELECT priKey, dataField "       + "FROM autoIncTutorial");    rs.moveToInsertRow();    rs.updateString("dataField", "AUTO INCREMENT here?");    rs.insertRow();    //    // the driver adds rows at the end    //    rs.last();    //    // We should now be on the row we just inserted    //    int autoIncKeyFromRS = rs.getInt("priKey");    rs.close();    rs = null;    System.out.println("Key returned for inserted row: "        + autoIncKeyFromRS);} finally {    if (rs != null) {        try {            rs.close();        } catch (SQLException ex) {            // ignore        }    }    if (stmt != null) {        try {            stmt.close();        } catch (SQLException ex) {            // ignore        }    }}

Выполнение предыдущего примера кода должно произвести следующий вывод:

Key returned from getGeneratedKeys(): 1Key returned from SELECT LAST_INSERT_ID(): 1Key returned for inserted row: 2

Время от времени это может быть хитро, чтобы использовать SELECT LAST_INSERT_ID() запрос, как, который значение функции является определяющим контекст к соединению. Так, если некоторый другой запрос происходит на том же самом соединении, значение перезаписывается. С другой стороны, getGeneratedKeys() метод является определяющим контекст Statement экземпляр, таким образом, это может использоваться, даже если другие запросы происходят на том же самом соединении, но не на том же самом Statement экземпляр.