明月松間照 清泉石上流


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

          java store procedure 的使用(DB2)

          Posted on 2006-12-15 15:30 兵臨城下 閱讀(1285) 評論(1)  編輯  收藏 所屬分類: Java EE
          突然被要求寫一個測試程序,測試java存儲過程和sql的執行效率,以前沒寫過存儲過程,啃了一段時間,記錄如下:
          使用的數據庫為DB2,首先在db2中建立一個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來調用它:
          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 {
          ????
          ????//存儲過程調用
          ????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 調用
          ????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;
          ?}
          }

          運行此servlet就可成功調用存儲過程。
          其中有個注意點,就是大小寫的問題,剛開始時建存儲過程是這樣CREATEPROCEDURE SQLTest(IN tables VARCHAR(200),IN num INTEGER) ,java class也用的是SQLTest,但是在調存儲過程時會抱錯,說找不到SQLTEST.procedureTest方法,原來數據庫在創建存儲過程時,即使你使用SQLTest,但也會被執行為SQLTEST,所以只有都改成大寫。

          但有點意外的是,通過這個測試出來的數據,存儲過程既然比sql跑得慢,不知道為什么,難道程序有問題?請大家看一下



          評論

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

          2006-12-21 20:37 by 兵臨城下
          經過測試才知道,并不是procedure比sql慢,而是SELECT * FROM table這樣短的sql語句不能顯示出procedure的性能,如果sql語句加長,procedure的性能就顯示出來了。
          原理上看:普通的sql語句,每個sql都要到DB端進行編譯,而procedure只要傳入參數就可,減少了編譯量,所以在頻繁使用基本相同的sql語句,或sql語句較長時,應該考驗適用procedure
          主站蜘蛛池模板: 惠水县| 东明县| 龙里县| 潼南县| 红河县| 金门县| 萝北县| 沐川县| 昭苏县| 改则县| 浙江省| 五指山市| 顺义区| 竹溪县| 永平县| 安新县| 玉田县| 赤城县| 防城港市| 安多县| 桑植县| 宜昌市| 新平| 上思县| 湖北省| 徐闻县| 沈阳市| 夹江县| 衢州市| 滦南县| 舞钢市| 彰化县| 田林县| 昌图县| 河池市| 洛扎县| 贡觉县| 哈巴河县| 平顶山市| 康定县| 榆中县|