JDBC讀取新插入Oracle數據庫Sequence值的5種方法

  1. /公共代碼:獲得數據庫鏈接  sql

  2. public Connection getConnection() throws Exception{  數據庫

  3.     Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();  數組

  4.     Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1 :1521:dbname""username""password");  安全

  5.     return conn;  併發

  6. }  oracle

  7.   

  8. //方法一  性能

  9. //先用select seq_t1.nextval as id from dual 取到新的sequence值。  spa

  10. //而後將最新的值經過變量傳遞給插入的語句:insert into t1(id) values(?)   .net

  11. //最後返回開始取到的sequence值。  對象

  12. //這種方法的優勢代碼簡單直觀,使用的人也最多,缺點是須要兩次sql交互,性能不佳。  

  13. public int insertDataReturnKeyByGetNextVal() throws Exception {  

  14.     Connection conn = getConnection();  

  15.     String vsql = "select seq_t1.nextval as id from dual";  

  16.     PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);  

  17.     ResultSet rs=pstmt.executeQuery();  

  18.     rs.next();  

  19.     int id=rs.getInt(1);  

  20.     rs.close();  

  21.     pstmt.close();  

  22.     vsql="insert into t1(id) values(?)";  

  23.     pstmt =(PreparedStatement)conn.prepareStatement(vsql);  

  24.     pstmt.setInt(1, id);  

  25.     pstmt.executeUpdate();  

  26.     System.out.print("id:"+id);  

  27.     return id;  

  28. }  

  29.   

  30. //方法二  

  31. //先用insert into t1(id) values(seq_t1.nextval)插入數據。  

  32. //而後使用select seq_t1.currval as id from dual返回剛纔插入的記錄生成的sequence值。  

  33. //注:seq_t1.currval表示取出當前會話的最後生成的sequence值,因爲是用會話隔離,只要保證兩個SQL使用同一個Connection便可,對於採用鏈接池應用須要將兩個SQL放在同一個事務內纔可保證併發安全。  

  34. //另外若是會話沒有生成過sequence值,使用seq_t1.currval語法會報錯。  

  35. //這種方法的優勢能夠在插入記錄後返回sequence,適合於數據插入業務邏輯很差改造的業務代碼,缺點是須要兩次sql交互,性能不佳,而且容易產生併發安全問題。  

  36. public int insertDataReturnKeyByGetCurrVal() throws Exception {  

  37.     Connection conn = getConnection();  

  38.     String vsql = "insert into t1(id) values(seq_t1.nextval)";  

  39.     PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);  

  40.     pstmt.executeUpdate();  

  41.     pstmt.close();  

  42.     vsql="select seq_t1.currval as id from dual";  

  43.     pstmt =(PreparedStatement)conn.prepareStatement(vsql);  

  44.     ResultSet rs=pstmt.executeQuery();  

  45.     rs.next();  

  46.     int id=rs.getInt(1);  

  47.     rs.close();  

  48.     pstmt.close();  

  49.     System.out.print("id:"+id);  

  50.     return id;  

  51. }  

  52.   

  53. //方法三  

  54. //採用pl/sql的returning into語法,能夠用CallableStatement對象設置registerOutParameter取得輸出變量的值。  

  55. //這種方法的優勢是隻要一次sql交互,性能較好,缺點是須要採用pl/sql語法,代碼不直觀,使用較少。  

  56. public int insertDataReturnKeyByPlsql() throws Exception {  

  57.     Connection conn = getConnection();  

  58.     String vsql = "begin insert into t1(id) values(seq_t1.nextval) returning id into :1;end;";  

  59.     CallableStatement cstmt =(CallableStatement)conn.prepareCall ( vsql);   

  60.     cstmt.registerOutParameter(1, Types.BIGINT);  

  61.     cstmt.execute();  

  62.     int id=cstmt.getInt(1);  

  63.     System.out.print("id:"+id);  

  64.     cstmt.close();  

  65.     return id;  

  66. }  

  67.   

  68. //方法四  

  69. //採用PreparedStatement的getGeneratedKeys方法  

  70. //conn.prepareStatement的第二個參數能夠設置GeneratedKeys的字段名列表,變量類型是一個字符串數組  

  71. //注:對Oracle數據庫這裏不能像其它數據庫那樣用prepareStatement(vsql,Statement.RETURN_GENERATED_KEYS)方法,這種語法是用來取自增類型的數據。  

  72. //Oracle沒有自增類型,所有采用的是sequence實現,若是傳Statement.RETURN_GENERATED_KEYS則返回的是新插入記錄的ROWID,並非咱們相要的sequence值。  

  73. //這種方法的優勢是性能良好,只要一次sql交互,實際上內部也是將sql轉換成oracle的returning into的語法,缺點是隻有Oracle10g才支持,使用較少。  

  74. public int insertDataReturnKeyByGeneratedKeys() throws Exception {  

  75.     Connection conn = getConnection();  

  76.     String vsql = "insert into t1(id) values(seq_t1.nextval)";  

  77.     PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql,new String[]{"ID"});  

  78.     pstmt.executeUpdate();  

  79.     ResultSet rs=pstmt.getGeneratedKeys();  

  80.     rs.next();  

  81.     int id=rs.getInt(1);  

  82.     rs.close();  

  83.     pstmt.close();  

  84.     System.out.print("id:"+id);  

  85.     return id;  

  86. }  

  87.   

  88. //方法五  

  89. //和方法三相似,採用oracle特有的returning into語法,設置輸出參數,可是不一樣的地方是採用OraclePreparedStatement對象,由於jdbc規範裏標準的PreparedStatement對象是不能設置輸出類型參數。  

  90. //最後用getReturnResultSet取到新插入的sequence值,  

  91. //這種方法的優勢是性能最好,由於只要一次sql交互,oracle9i也支持,缺點是隻能使用Oracle jdbc特有的OraclePreparedStatement對象。  

  92. public int insertDataReturnKeyByReturnInto() throws Exception {  

  93.     Connection conn = getConnection();  

  94.     String vsql = "insert into t1(id) values(seq_t1.nextval) returning id into :1";  

  95.     OraclePreparedStatement pstmt =(OraclePreparedStatement)conn.prepareStatement(vsql);  

  96.     pstmt.registerReturnParameter(1, Types.BIGINT);  

  97.     pstmt.executeUpdate();  

  98.     ResultSet rs=pstmt.getReturnResultSet();  

  99.     rs.next();  

  100.     int id=rs.getInt(1);  

  101.     rs.close();  

  102.     pstmt.close();  

  103.     System.out.print("id:"+id);  

  104.     return id;  

  105. }  

  1. SQL> create table T1  

  2.   2  (  

  3.   3    ID NUMBER  

  4.   4  );  

  5.    

  6. Table created  

  7. SQL> create sequence SEQ_T1;  

  8.    

  9. Sequence created  

相關文章
相關標籤/搜索