Leo's Blog

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            13 隨筆 :: 3 文章 :: 18 評(píng)論 :: 0 Trackbacks

          最近寫(xiě)程序已經(jīng)很少直接用JDBC了,一直都是用ibaits, Hibernate等來(lái)招呼,因?yàn)楝F(xiàn)在的集成框架已經(jīng)很穩(wěn)定了。不過(guò)對(duì)JDBC的直接使用還是不可以忽略的,JDBC3.0提供的n多的新特征還是要熟悉了解的,以前學(xué)jdbc的時(shí)候就是上網(wǎng)找些demo和介紹來(lái)學(xué),使用很單一,對(duì)JDBC3.0的好多新的特征都忽略了,比如下面一個(gè)例子:

          Statement stmt = con.createStatement();
          ResultSet rs = stmt.executeQuery("SELECT * FROM user WHERE username='aa'");
          stmt.executeUpdate("UPDATE user SET lastdatetime=now() where username='aa'");

          這是一個(gè)用戶登錄時(shí),經(jīng)常用到的代碼,先是根據(jù)用戶名aa查找該用戶的詳細(xì)信息,然后再更新該用戶的最后登錄時(shí)間(lastdatetime)。這這個(gè)里面,我們用了兩個(gè)sql語(yǔ)句,這個(gè)是我一直用的方法,但是如果用JDBC2.0給我們提供的便利,我們只要寫(xiě)一條sql就夠了,其他的都交給jdbc,看下面的代碼:

          Statement stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
          ResultSet rs2 = stmt.executeQuery("SELECT * FROM user WHERE username='aa'");
          rs2.next();
          rs2.updateDate("lastdatetime", new Date(Calendar.getInstance().getTimeInMillis()));
          rs2.updateRow();

          這里面最主要的特征就是ResultSet.TYPE_FORWARD_ONLY和ResultSet.CONCUR_UPDATABLE,通過(guò)初始化Statement時(shí)傳不同的參數(shù),可以對(duì)ResultSet進(jìn)行不用的錯(cuò)作限制。con.createStatement的時(shí)候,有三種可以掉用的函數(shù):

          1、createStatement();
          2、createStatement(int resultSetType, int resultSetConcurrency)
          3、createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)

          其中resultSetType可選值是:
          ?? 1、ResultSet.TYPE_FORWARD_ONLY? 在ResultSet中只能先前移動(dòng)游標(biāo),
          ?? 2、ResultSet.TYPE_SCROLL_INSENSITIVE 在ResultSet中可以隨心所欲的先前向后移動(dòng)游標(biāo),
          ?? 3、ResultSet.TYPE_SCROLL_SENSITIVE 在ResultSet中可以隨心所欲的先前向后移動(dòng)游標(biāo),同時(shí)ResultSet的值有所改變的時(shí)候,他可以得到改變后的最新的值
          其中resultSetConcurrency可選值是:
          ?? 1、ResultSet.CONCUR_READ_ONLY? 在ResultSet中的數(shù)據(jù)記錄是只讀的,可以修改
          ?? 2、ResultSet.CONCUR_UPDATABLE? 在ResultSet中的數(shù)據(jù)記錄可以任意修改,然后更新會(huì)數(shù)據(jù)庫(kù)
          其中resultSetHoldability可選值是:
          ?? 1、ResultSet.HOLD_CURSORS_OVER_COMMIT 表示修改提交時(shí),不關(guān)閉ResultSet的游標(biāo)
          ?? 2、ResultSet.CLOSE_CURSORS_AT_COMMIT? 表示修改提交時(shí),關(guān)閉ResultSet的游標(biāo)

          對(duì)于查詢操作第一種初始化方法createStatement(),相當(dāng)于第二種方法的createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY),第三種方法的createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT)

          下面寫(xiě)一段demo的代碼,我把一些特征函數(shù)都用出來(lái),但是只是用來(lái)查考和說(shuō)明名靈活性的。

          ?Statement stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
          ?ResultSet rs2 = stmt.executeQuery("SELECT * FROM user");
          ?rs2.next();
          ?rs2.updateDate("lastdatetime", new Date(Calendar.getInstance().getTimeInMillis()));
          ?rs2.updateRow();
          ?rs2.afterLast();
          ?while(rs2.previous()){ /**....*/ }
          ?rs.beforeFirst();
          ?while(rs2.next()){? /**....*/ }
          ?rs.last();
          ?rs.first();
          ?rs.absolute(5);?//游標(biāo)移動(dòng)到第5條
          ?rs.absolute(-1);? //游標(biāo)移動(dòng)到最后一條
          ?rs.relative(-5);? //游標(biāo)向上移動(dòng)5條
          ?rs.relative(2);?? //游標(biāo)向下移動(dòng)2條
          ?rs.deleteRow();?//刪除當(dāng)前行
          ?rs.last();? //游標(biāo)移動(dòng)到最后
          ?rs.updateString("summary", "This is ..."); //設(shè)置更新的字段值
          ?rs.cancelRowUpdates();? //取消剛才輸入的更新
          ?rs.getRow(); //得到當(dāng)前行號(hào)
          ?rs.moveToInsertRow();? //游標(biāo)移動(dòng)到要新增的那條記錄上
          ?rs.updateInt("id", 1);
          ?rs.updateString(2, "my name");
          ?rs.insertRow(); //插入新記錄


          JDBC2.0提供的還有一個(gè)功能就是數(shù)據(jù)庫(kù)的批量操作

          ??con.setAutoCommit(false);
          ??Statement stmt3 = con.createStatement();
          ??stmt3.addBatch("insert .....");
          ??stmt3.addBatch("insert .....");
          ??int[] rows = stmt3.executeBatch();
          ??con.commit();

          但是有一點(diǎn)要注意,stmt3.executeBatch()他不會(huì)自動(dòng)給你回滾數(shù)據(jù)操作,當(dāng)你有5條update語(yǔ)句的時(shí)候,如果第三條發(fā)生錯(cuò)誤,那么將無(wú)法自動(dòng)回滾前兩條update語(yǔ)句的影響,所以一定要自己手工進(jìn)行事務(wù)管理。

          在您的事務(wù)中使用 Savepoint
          JDBC3.0中最令人興奮的附加特點(diǎn)就是 Savepoint 了。有時(shí)候需要的是對(duì)事務(wù)多一點(diǎn)的控制,而不是在當(dāng)前的事務(wù)中簡(jiǎn)單地對(duì)每一個(gè)改變進(jìn)行回滾。在JDBC3.0下,您就可以通過(guò) Savepoint 獲得這種控制。Savepoint 接口允許您將事務(wù)分割為各個(gè)邏輯斷點(diǎn),以控制有多少事務(wù)需要回滾??聪旅娴拇a:

          conn.setAutoCommit(false);
          conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
          Statement stmt = conn.createStatement();
          int rows = stmt.executeUpdate( "INSERT INTO authors (first_name, last_name) valueS(′Lewis′, ′Carroll′)");
          Savepoint svpt = conn.setSavepoint("NewAuthor");
          try{
          ?rows = stmt.executeUpdate( "UPDATE authors set type = ′fiction′ WHERE last_name = ′Carroll′");
          }catch(Exception e){
          ?conn.rollback(svpt);
          ?rows = stmt.executeUpdate( " update .......... other sql ");
          }
          conn.commit();

          上面代碼顯示,當(dāng)UPDATE authors失敗的時(shí)候,系統(tǒng)事務(wù)回滾UPDATE authors的sql的影響,而INSERT INTO authors的sql仍然有效


          檢索自動(dòng)產(chǎn)生的關(guān)鍵字
          為了解決對(duì)獲取自動(dòng)產(chǎn)生的或自動(dòng)增加的關(guān)鍵字的值的需求,JDBC 3.0現(xiàn)在將獲取這種值變得很輕松。要確定任何所產(chǎn)生的關(guān)鍵字的值,只要簡(jiǎn)單地在語(yǔ)句的 execute() 方法中指定一個(gè)可選的標(biāo)記,Statement.RETURN_GENERATED_KEYS和Statement.NO_GENERATED_KEYS。在執(zhí)行這條語(yǔ)句后,所產(chǎn)生的關(guān)鍵字的值就會(huì)通過(guò)從 Statement 的實(shí)例方法 getGeneratedKeys() 來(lái)檢索 ResultSet 而獲得。ResultSet 包含了每個(gè)所產(chǎn)生的關(guān)鍵字的列??聪旅娲a:

          Statement stmt = conn.createStatement();
          stmt.executeUpdate("INSERT INTO authors (first_name, last_name) valueS (′George′, ′Orwell′)", Statement.RETURN_GENERATED_KEYS);
          ResultSet rs = stmt.getGeneratedKeys();
          if ( rs.next() ) {
          ?int key = rs.getInt();
          }

          ?參考資料: http://java.sun.com/j2se/1.5.0/docs/api/java/sql/package-summary.html

          posted on 2006-05-08 10:49 Leo 閱讀(1549) 評(píng)論(2)  編輯  收藏 所屬分類(lèi): 技術(shù)隨文

          評(píng)論

          # re: JDBC2/3.0的特征點(diǎn)滴 2006-05-17 10:03 ztroma
          很不錯(cuò),謝謝.但是,我有個(gè)疑問(wèn):
          rs.absolute(5); //游標(biāo)移動(dòng)到第5條
          rs.absolute(-1); //游標(biāo)移動(dòng)到最后一條
          rs.relative(-5); //游標(biāo)向上移動(dòng)5條
          rs.relative(2); //游標(biāo)向下移動(dòng)2條
          rs.deleteRow(); //刪除當(dāng)前行
          rs.last(); //游標(biāo)移動(dòng)到最后
          這幾行中,為什么rs.absolute(-1);和rs.last();的作用一樣呢?它們兩者的用法有什么區(qū)別呢?  回復(fù)  更多評(píng)論
            

          # re: JDBC2/3.0的特征點(diǎn)滴 2006-06-21 13:31 anyang
          蹭分,走人!  回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 上思县| 永善县| 密山市| 克拉玛依市| 伊金霍洛旗| 武义县| 阿图什市| 靖安县| 铅山县| 桑日县| 青浦区| 海丰县| 荆州市| 犍为县| 仁寿县| 谷城县| 漳州市| 扎赉特旗| 万载县| 兰溪市| 哈尔滨市| 怀仁县| 馆陶县| 东乌| 玉山县| 彰武县| 广宁县| 河津市| 乐昌市| 共和县| 嘉定区| 开封县| 马关县| 贵南县| 喀什市| 上栗县| 宿州市| 东明县| 潮州市| 吴川市| 高安市|