MYSQL自己増メインキーを取得する【4つの方法】

14664 ワード

回転:http://blog.csdn.net/ultrani/article/details/9351573
作者はもう非常によく書いています.私はむだ話をしません.直接転載して収集します.
私たちは通常、アプリケーションでmysqlに対してinsert操作を行った後、挿入記録の自己増加キーを取得する必要があります.本論文では、java環境下の4つの方法について、insertを取得した後の記録の主なキーaut_を紹介します.incrementの値:
  • JDBC 2.0により提供されるinsertRow()方式
  • JDBC 3.0によって提供されるgetGeneratodKeys方式
  • SQL select LAST_を通じてINSERT_ID()関数
  • SQL@IDENTITY変数
  • を介して
    1. JDBC 2.0で提供するinsertRow方式
    jdbc 2.0以来、次のように実行できます.
    Statement stmt = null;
    ResultSet rs = null;
    try {
        stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,  //   Statement
                                    java.sql.ResultSet.CONCUR_UPDATABLE);
        stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
        stmt.executeUpdate(                                                //   demo 
                "CREATE TABLE autoIncTutorial ("
                + "priKey INT NOT NULL AUTO_INCREMENT, "
                + "dataField VARCHAR(64), PRIMARY KEY (priKey))");
        rs = stmt.executeQuery("SELECT priKey, dataField "                 //     
           + "FROM autoIncTutorial");
        rs.moveToInsertRow();                                              //          (       )
        rs.updateString("dataField", "AUTO INCREMENT here?");              //     
        rs.insertRow();                                                    //     
        rs.last();                                                         //          
        int autoIncKeyFromRS = rs.getInt("priKey");                        //           preKey
        rs.close();
        rs = null;
        System.out.println("Key returned for inserted row: "
            + autoIncKeyFromRS);
    }  finally {
        // rs,stmt close()  
    }
    利点:初期の一般的なアプローチ 
    短所:ResultSetを操作する必要があります.コードが長いです.
    2. JDBC 3.0により提供されたgetGenerate edKeys()方式
    Statement stmt = null;
    ResultSet rs = null;
    try {
        stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                    java.sql.ResultSet.CONCUR_UPDATABLE);  
        // ...
        //      (      demo )
        // ...
        stmt.executeUpdate(
                "INSERT INTO autoIncTutorial (dataField) "
                + "values ('Can I Get the Auto Increment Field?')",
                Statement.RETURN_GENERATED_KEYS);                      //            generatedKeys!
        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 { ... }
    この方法は2つのステップだけが必要です.
    1.executeUpdateで自動取得keyをアクティブにします.
    2.Sttementを呼び出すgetGeneranted Keys()インターフェース
    利点:
    1.操作が便利で、コードが簡潔である
    2.jdbc 3.0の基準
    3.効率がいいです.データベースに追加のアクセスがないからです.
     
    ここで補充します
    a.jdbc 3.0の前に、各jdbc driverの実現には自分で自己増加キーを取得するインターフェースがあります.mysql jdbc 2.0でのdriver org.gjt.mm.mysqlでは、getGeneratodKeys()関数がorg.gjt.mm.mysql.jdbc.Stement.getGenerantated Keys()で実現されます.このように直接引用すると、移植性に大きな影響があります.JDBC 3.0は標準のgetGeneratodKeysによってこの点をよく補いました.
    b.getGenerate edKeysについて、公式サイトではさらに詳細な説明があります.OracleJdbcガイド
    3. SQL select LAST_を通してINSERT_ID()
    Statement stmt = null;
    ResultSet rs = null;
    try {
        stmt = conn.createStatement();
        // ...
        //     
        // ...
        stmt.executeUpdate(
                "INSERT INTO autoIncTutorial (dataField) "
                + "values ('Can I Get the Auto Increment Field?')");
        int autoIncKeyFromFunc = -1;
        rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");             //         generatedKey
        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 {...}
    この方法は何も言いません.もう一回関数LASTを調べます.INSERT_ID()
    長所:簡単で便利
    短所:JDBC 3.0のgetGenerantedKeys()に対して、追加のデータベースクエリが必要です.
     
    追加:
    1.この関数は、mysql 5.5のマニュアルで定義されています.「returns a BIGINT(64-bit)value representing the first atomaticallally generant value succelly inserted for an AUTOka Column as.ext of the most Serecented」です.この文書ポイント
    2.この関数は、connection次元では「スレッドが安全」です.つまり、各mysql接続は独立してLASTを保存します.INSERT_ID()の結果、そして
    現在接続されている前回のinsert操作によってのみ更新されます.つまり2つの接続が同時にinsert文を実行するとき、それぞれのLAST_を呼び出します.INSERT_ID()は互いに上書きされません.栗を挙げます.Aをつないで表に入れてからLAST_を入れます.INSERT_ID()は100に戻り、Bを接続してテーブルを挿入した後、LAST_INSERT_ID()は101に戻るが、接続AはLAST_を繰り返し実行する.INSERT_ID()の場合は、101ではなく、常に100に戻ります.これはmysql接続数と実行結果を監視することによって検証できます.ここでは実験過程を詳しく説明しません.
    3.上記の点に基づいて、同じ接続を前提として同時にinsertを実行すれば、2回操作可能な戻り値が互いに上書きされます.ラストなのでINSERT_ID()の分離度は接続レベルです.これは、getGeneratoedKeys()は、getGeneranted Keys()がstatementレベルなので、より良いことができます.同じconnectionの複数のstatementは、getGeneratodikeys()は互いに上書きされない.
    4. SQL SELECT@IDENTITYを通じて
    この方式と
    ラスト.INSERT_ID()の効果は同じです.公式サイトの文書では、「This variable is a synonm for the lastert variable.It exists for comptibility with other database systems.You can read its value with SELECT@identity,and set using SEidentity.」  この文書ポイント
     
    重要な追加:
    SELECT LAST_でもINSERT_ID()はやはりSELECT@IDENTITYで、一つのinsert文に複数のレコードを挿入すると、いつも第一条の挿入記録のgenerantedKeyに戻ります.
    INSERT INTO t VALUES
        -> (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
    ラスト.INSERT_ID()は、@IDENTITYはいずれも'Mary'がいるあの記録のgenerantedKeyに戻ります.
    結び目
    だから、やはりJDBC 3が提供するgetGeneratodKeys関数でinsert記録の主キーを取得したほうがいいです.簡単であるのみならず、効率も高い.
     
    mybatisには、関連する設定があります. 
    <insert id="save" parameterType="MappedObject" useGeneratedKeys="true" keyProperty="id">
    </insert>
    mybatis文書を参照できます.sqlmap-xml
    参考資料
    http://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-last-insert-id.html
    http://www.onjava.com/pub/a/onjava/excerpt/javaentnut_2/index 2.html?page=3
    http://docs.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/statement.html#1000569
    http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-innsert-id
    http://nic.jlu.edu.cn/newcourse/dbxz/jdbc20.pdf
    http://www.enidc.com/help/newscontent/110507