qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          Java執(zhí)行sql語(yǔ)句并獲取指定返回值

           當(dāng)我們插入一條數(shù)據(jù)的時(shí)候,我們很多時(shí)候都想立刻獲取當(dāng)前插入的主鍵值返回以做它用。我們通常的做法有如下幾種:

            1、先 select max(id) +1 ,然后將+1后的值作為主鍵插入數(shù)據(jù)庫(kù)

            2、使用特定數(shù)據(jù)庫(kù)的 auto_increment 特性,在插入數(shù)據(jù)完成后,使用 select max(id) 獲取主鍵值;

            3、對(duì)于Oracle,使用 sequence 獲取值。

            對(duì)于以上3種方法都無(wú)法絕對(duì)保證在高并發(fā)情況下的操作的原子性。

            現(xiàn)記錄以下幾種獲取數(shù)據(jù)庫(kù)主鍵值方法:

            1、數(shù)據(jù)庫(kù)原生支持的sql方法:

            SQLServer:

          INSERT INTO table_name (.....) VALUES(......)  SELECT @@IDENTITY AS aliasname;

            上面的語(yǔ)句相當(dāng)于查詢語(yǔ)句,從結(jié)果集中使用 getXXX(aliasname) 方法獲取主鍵值。

            Oracle:

          INSERT INTO table_name(......) VALUES(......) RETURNING[primaryKey INTO]:aliasname;

            也是相當(dāng)于查詢語(yǔ)句,從結(jié)果集中使用 getXXX(aliasname) 方法獲取主鍵值。

            2、java.sql.Statement 返回鍵獲取:

            a: 使用JDBC 3.0提供的 getGeneratedKeys(推薦使用)

          Statement stmt = ... ;

          stmt.executeUpdate("INSERT INTO table_name(......) VALUES(......)", Statement.RETURN_GENERATED_KEYS);

          ResultSet rs = stmt.getGeneratedKeys();

          int keyValue = -1;

          if (rs.next()) {

              keyValue = rs.getInt(1);

          }

            b:使用特定數(shù)據(jù)庫(kù)特有的SQL

          Statement stmt = ... ;

          stmt.executeUpdate("INSERT INTO table_name(......) VALUES(......)", Statement.RETURN_GENERATED_KEYS);

          ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");

          int keyValue = -1;

          if (rs.next()) {

              keyValue = rs.getInt(1);

          }

            那么現(xiàn)在我就一個(gè)例子來(lái)看一下原生的sql怎么能得到執(zhí)行的返回結(jié)果

            項(xiàng)目背景:數(shù)據(jù)庫(kù)是oracle數(shù)據(jù)庫(kù),id生成規(guī)則是通過(guò)觸發(fā)器插入數(shù)據(jù)的時(shí)候自動(dòng)增長(zhǎng),所以在插入數(shù)據(jù)的時(shí)候在sql中就不需要指明id值。但是另外一張表需要引用這個(gè)id值作為外鍵,那么就必須獲得被引用的這個(gè)表的ID,為了避免并發(fā)問(wèn)題,我們只能在插入前面那張表的時(shí)候就獲得他的ID,所以我使用了下面的方法來(lái)處理。

          Connection con = DBConnector.getconecttion(); // 取得一個(gè)數(shù)據(jù)庫(kù)連接
          CallableStatement cst = null;
          con.setAutoCommit(false);
          String insertSql = "begin insert into TABLE (field_0,field_1) values (value_0,value_1) returning id into ?;end; ";
          try {
           cst = con.prepareCall(insertSql); //執(zhí)行存儲(chǔ)過(guò)程
           cst.registerOutParameter(1, Types.INTEGER); //為存儲(chǔ)過(guò)程設(shè)定返回值
           int count = cst.executeUpdate(); //得到預(yù)編譯語(yǔ)句更新記錄或刪除操作的結(jié)果
           int id = cst.getInt(1); //得到返回值
             
           System.out.println("成功執(zhí)行了:" + count + "條數(shù)據(jù),其ID值:" + id);
          } catch (SQLException e1) {
           con.rollback();
           con.setAutoCommit(true);
          }finally{
           con.commit();
           con.close();
          }

          posted on 2012-06-08 09:40 順其自然EVO 閱讀(821) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2012年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 天水市| 龙州县| 昌黎县| 樟树市| 双鸭山市| 上蔡县| 岑巩县| 叶城县| 延庆县| 奉贤区| 诸暨市| 绥宁县| 乐平市| 济宁市| 登封市| 汶上县| 嘉兴市| 邮箱| 湘西| 黎平县| 石台县| 双城市| 洛扎县| 肇源县| 波密县| 盱眙县| 龙里县| 依安县| 涟源市| 松桃| 永吉县| 永顺县| 隆子县| 江华| 呼和浩特市| 漳州市| 古田县| 桐柏县| 定结县| 广州市| 内乡县|