明月松間照 清泉石上流


                                                  ——— 兵臨城下   貓科動(dòng)物
          posts - 70, comments - 137, trackbacks - 0, articles - 23
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          java store procedure 的使用(DB2)

          Posted on 2006-12-15 15:30 兵臨城下 閱讀(1283) 評論(1)  編輯  收藏 所屬分類: Java EE
          突然被要求寫一個(gè)測試程序,測試java存儲(chǔ)過程和sql的執(zhí)行效率,以前沒寫過存儲(chǔ)過程,啃了一段時(shí)間,記錄如下:
          使用的數(shù)據(jù)庫為DB2,首先在db2中建立一個(gè)procedure:
          CREATE PROCEDURE SQLTEST (IN tables VARCHAR(200),IN num INTEGER)
          SPECIFIC JDBC_SQLTEST
          DYNAMIC RESULT SETS 0
          DETERMINISTIC
          LANGUAGE JAVA
          PARAMETER STYLEJAVA
          NODBINFO
          FENCED
          THREADSAFE
          MODIFIES SQLDATA
          PROGRAM TYPE SUB
          EXTERNAL NAME'SQLTEST.procedureTest'

          其中SQLTEST為java 的calss名,procedureTest為方法名(詳見如下程序):
          import java.util.StringTokenizer;
          import java.sql.Connection;
          import java.sql.Statement;
          import java.sql.DriverManager;

          import javax.naming.Context;
          import javax.naming.InitialContext;
          import javax.sql.DataSource;

          public class SQLTEST {
          ?
          ?public static void procedureTest(String tables,int num) {
          ??try{
          ???Connection conn = DriverManager.getConnection("jdbc:default:connection");
          ???Statement stmt = conn.createStatement();
          ???StringTokenizer stk = new StringTokenizer(tables,",");
          ???while(stk.hasMoreTokens()) {
          ????String table = stk.nextToken();
          ????String sql = "SELECT * FROM " + table;
          ????for(int i=0;i<num;i++) {
          ?????stmt.executeQuery(sql);
          ?????
          ????}
          ???}
          ???stmt.close();
          ???conn.close();
          ??}catch(Exception e) {
          ???e.printStackTrace();
          ??}
          ?}
          }
          將此class編譯后拷貝到DB2安裝目錄的function目錄下。

          再用servlet來調(diào)用它:
          package com.test;
          import java.io.IOException;
          import java.util.StringTokenizer;
          import java.sql.*;
          import javax.sql.DataSource;
          import javax.naming.InitialContext;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          public class SQLServlet extends HttpServlet {
          ?public void doGet(HttpServletRequest req, HttpServletResponse resp)
          ??throws ServletException, IOException {
          ???doPost(req,resp);
          ?}
          ?public void doPost(HttpServletRequest req, HttpServletResponse resp)
          ??throws ServletException, IOException {
          ???CallableStatement callStmt = null;
          ???Connection conn = null;
          ???Statement stmt = null;
          ???String tables = "shgt_auth,shgt_master,trx_inbox";
          ???long start = 0;
          ???long end = 0;
          ???long lastTime = 0;
          ???int num = 100;
          ???try {
          ????
          ????//存儲(chǔ)過程調(diào)用
          ????conn = getConnection("CET","eximtrx","Standard00");
          ????String procName = "SQLTEST";
          ????String sql = "CALL " + procName + "(?,?)";
          ????callStmt = conn.prepareCall(sql);
          ????callStmt.setString(1,tables);
          ????callStmt.setInt(2,num);
          ????start = System.currentTimeMillis();
          ????callStmt.execute();
          ????end = System.currentTimeMillis();
          ????lastTime = end - start;
          ????System.out.println("###########java store procedure Last time : " + lastTime/1000? + "s" + lastTime%1000 + "ms");
          ????
          ????
          ????
          ????//SQL 調(diào)用
          ????conn = getConnection("CET","eximtrx","Standard00");
          ????stmt = conn.createStatement();
          ????StringTokenizer strTok = new StringTokenizer(tables,",");
          ????start = System.currentTimeMillis();
          ????while(strTok.hasMoreTokens()) {
          ?????String table = strTok.nextToken();
          ?????String sql2 = "select * from " + table;
          ?????for(int i=0;i<num;i++){
          ??????stmt.executeQuery(sql2);
          ?????}
          ????}
          ????end = System.currentTimeMillis();
          ????lastTime = end - start;
          ????System.out.println("###########SQL Last time : " + lastTime/1000? + "s" + lastTime%1000 + "ms");
          ???} catch (Exception e) {
          ????e.printStackTrace();
          ???}
          ?}
          ?private Connection getConnection(String ds, String user, String pwd)
          ? throws Exception {
          ?? Connection con = null;
          ?? InitialContext ctx = new InitialContext();
          ?? DataSource fDS = (DataSource)ctx.lookup(ds);
          ?? con = fDS.getConnection(user, pwd);
          ?? return con;
          ?}
          }

          運(yùn)行此servlet就可成功調(diào)用存儲(chǔ)過程。
          其中有個(gè)注意點(diǎn),就是大小寫的問題,剛開始時(shí)建存儲(chǔ)過程是這樣CREATEPROCEDURE SQLTest(IN tables VARCHAR(200),IN num INTEGER) ,java class也用的是SQLTest,但是在調(diào)存儲(chǔ)過程時(shí)會(huì)抱錯(cuò),說找不到SQLTEST.procedureTest方法,原來數(shù)據(jù)庫在創(chuàng)建存儲(chǔ)過程時(shí),即使你使用SQLTest,但也會(huì)被執(zhí)行為SQLTEST,所以只有都改成大寫。

          但有點(diǎn)意外的是,通過這個(gè)測試出來的數(shù)據(jù),存儲(chǔ)過程既然比sql跑得慢,不知道為什么,難道程序有問題?請大家看一下



          評論

          # re: java store procedure 的使用(DB2)  回復(fù)  更多評論   

          2006-12-21 20:37 by 兵臨城下
          經(jīng)過測試才知道,并不是procedure比sql慢,而是SELECT * FROM table這樣短的sql語句不能顯示出procedure的性能,如果sql語句加長,procedure的性能就顯示出來了。
          原理上看:普通的sql語句,每個(gè)sql都要到DB端進(jìn)行編譯,而procedure只要傳入?yún)?shù)就可,減少了編譯量,所以在頻繁使用基本相同的sql語句,或sql語句較長時(shí),應(yīng)該考驗(yàn)適用procedure
          主站蜘蛛池模板: 镇雄县| 苗栗市| 杭州市| 棋牌| 卢湾区| 遵义市| 中江县| 水富县| 年辖:市辖区| 信宜市| 武鸣县| 赣州市| 北川| 廉江市| 平谷区| 平邑县| 丹凤县| 东山县| 宜川县| 三门县| 乐昌市| 佛教| 木兰县| 铜梁县| 大厂| 崇明县| 衢州市| 丹江口市| 德江县| 长武县| 元阳县| 改则县| 昭觉县| 镇康县| 珠海市| 永春县| 霍州市| 通江县| 南召县| 庄河市| 内江市|