java挿入表記録後に自己増加のidを得る(2つの方法コードを添付)
テキスト
http://www.sthelse.com/2010/07/java-to-insert-in-the-main-table-record-id-from-the-table-for-the-main-table-as-a-foreign-key.html#comment-2264
MySQLでは、aut_を使用します。incrementタイプのidフィールドを表のメインキーとして使用し、他の表の外部キーとして使用して、「主従表構造」を形成します。これはデータベースデザインによく使われています。しかし、具体的にIDを生成する時、私達の操作手順は主にメインテーブルに記録を挿入し、自動的に生成されたidを取得し、それをもとにテーブルからの記録を挿入します。
この中には、メインテーブルの記録を挿入した後、どのように対応するIDを取得するかが難しいです。通常のやり方は、「select max from tableaname」を通じて行われますが、このようなやり方は合併を考慮しなければならないことは明らかです。事務中にメインテーブルにX錠をかける必要があります。max(id)の値を取ってからロックを解除します。このようなやり方が必要なステップが多く、面倒で、合併性もよくないです。もっと簡単な方法がありますか?
答えの一つは、select LASTINSERT_ID()によって操作されています。一見、select max(id)に似ていますが、実際にはスレッドが安全です。つまり、データベースに具体的に接続されています。以下の実験で説明します。
1、接続1にAテーブルに記録を挿入し、Aテーブルにはautouincrementタイプのフィールドが含まれています。
2、接続2でAテーブルにもう一つのレコードを挿入します。
3、結果:コネクション1でselect LASTuINSERT_ID()を実行した結果とコネクション2でselect LASTuINSERT_uID()を実行した結果は違っています。2つの接続でselect max(id)を実行した結果は同じです。実はMSSQLでSCOPEEIDENTY()とIDENTUEOUTEOUTTY(ここでは同じです。あるIDENTITYフィールドに挿入された現在のセッションの値が得られ、IDENTUCURRENT()を使用すると、あるIDENTITYフィールドに挿入された最大値が得られ、異なるセッションを区別しない。
注:select lastuinsertuid()を使用する場合は、複数のレコードを一度に挿入すると、最初に挿入したID値だけが得られますので、注意してください。
もちろん、他の便利な方法も使えます。JDBCに記録を追加した後、APIを使って新たに追加記録されたメインキーの値を獲得します。
この実装はSttementのgetGeneratodKeys方法を使用して、Sttementが記録を追加した時に、直接getGenerated Keys方法を呼び出して新たな追加記録を得ることができるkey。
テスト手順は以下の通りです。
プログラム運転結果:記録を生成するkeyは:9
データベースのレコード:
なお、executeUpdate方法を実行する場合は、生成keyに戻るオプションを指定します。
==============================================================================================================
2つの方法のjavaコード
http://www.sthelse.com/2010/07/java-to-insert-in-the-main-table-record-id-from-the-table-for-the-main-table-as-a-foreign-key.html#comment-2264
MySQLでは、aut_を使用します。incrementタイプのidフィールドを表のメインキーとして使用し、他の表の外部キーとして使用して、「主従表構造」を形成します。これはデータベースデザインによく使われています。しかし、具体的にIDを生成する時、私達の操作手順は主にメインテーブルに記録を挿入し、自動的に生成されたidを取得し、それをもとにテーブルからの記録を挿入します。
この中には、メインテーブルの記録を挿入した後、どのように対応するIDを取得するかが難しいです。通常のやり方は、「select max from tableaname」を通じて行われますが、このようなやり方は合併を考慮しなければならないことは明らかです。事務中にメインテーブルにX錠をかける必要があります。max(id)の値を取ってからロックを解除します。このようなやり方が必要なステップが多く、面倒で、合併性もよくないです。もっと簡単な方法がありますか?
答えの一つは、select LASTINSERT_ID()によって操作されています。一見、select max(id)に似ていますが、実際にはスレッドが安全です。つまり、データベースに具体的に接続されています。以下の実験で説明します。
1、接続1にAテーブルに記録を挿入し、Aテーブルにはautouincrementタイプのフィールドが含まれています。
2、接続2でAテーブルにもう一つのレコードを挿入します。
3、結果:コネクション1でselect LASTuINSERT_ID()を実行した結果とコネクション2でselect LASTuINSERT_uID()を実行した結果は違っています。2つの接続でselect max(id)を実行した結果は同じです。実はMSSQLでSCOPEEIDENTY()とIDENTUEOUTEOUTTY(ここでは同じです。あるIDENTITYフィールドに挿入された現在のセッションの値が得られ、IDENTUCURRENT()を使用すると、あるIDENTITYフィールドに挿入された最大値が得られ、異なるセッションを区別しない。
注:select lastuinsertuid()を使用する場合は、複数のレコードを一度に挿入すると、最初に挿入したID値だけが得られますので、注意してください。
もちろん、他の便利な方法も使えます。JDBCに記録を追加した後、APIを使って新たに追加記録されたメインキーの値を獲得します。
この実装はSttementのgetGeneratodKeys方法を使用して、Sttementが記録を追加した時に、直接getGenerated Keys方法を呼び出して新たな追加記録を得ることができるkey。
テスト手順は以下の通りです。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class GetGenerateKey {
public static void main(String[] args) throws Exception {
create();
}
public static void create()throws Exception {
System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "");
Statement st = conn.createStatement();
String sql = "insert into user (name, birthday, money) values ('beck', '1949-10-01', 60)";
st.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = st.getGeneratedKeys();
if (rs.next()) {
int id = rs.getInt(1);
System.out.println (" key :" + id);
}
st.close();
conn.close();
}
}
プログラム運転結果:記録を生成するkeyは:9
データベースのレコード:
1
+----+----------+------------+-------+
2
| id | name | birthday | money |
3
+----+----------+------------+-------+
4
| 9 | beck | 1949-10-01 | 60 |
5
+----+----------+------------+-------+
まとめ:このAPI方法は、クエリーを再実行して新しい記録を得るためのkey値が得られないという利点を提供しています。仕事量とサーバの負担を軽減しています。なお、executeUpdate方法を実行する場合は、生成keyに戻るオプションを指定します。
==============================================================================================================
2つの方法のjavaコード
// id
PreparedStatement pstmt = conn.prepareStatement(sql.toString(),PreparedStatement.RETURN_GENERATED_KEYS);
for (int i = 0; i < pars.length; i++) {
pstmt.setObject(i+1, pars[i]);
}
pstmt.executeUpdate();
long autoIncKeyFromApi = -1;
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next()) {
autoIncKeyFromApi = rs.getInt(1);
}
return autoIncKeyFromApi;
qRunner.update(conn,sql.toString(),pars);
Long zsysqID = (Long) qRunner.query(conn, "SELECT LAST_INSERT_ID()", new ScalarHandler(1));