明月松間照 清泉石上流


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

          java store procedure 的使用(DB2)

          Posted on 2006-12-15 15:30 兵臨城下 閱讀(1283) 評(píng)論(1)  編輯  收藏 所屬分類: Java EE
          突然被要求寫(xiě)一個(gè)測(cè)試程序,測(cè)試java存儲(chǔ)過(guò)程和sql的執(zhí)行效率,以前沒(méi)寫(xiě)過(guò)存儲(chǔ)過(guò)程,啃了一段時(shí)間,記錄如下:
          使用的數(shù)據(jù)庫(kù)為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為方法名(詳見(jiàn)如下程序):
          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來(lái)調(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ǔ)過(guò)程調(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ǔ)過(guò)程。
          其中有個(gè)注意點(diǎn),就是大小寫(xiě)的問(wèn)題,剛開(kāi)始時(shí)建存儲(chǔ)過(guò)程是這樣CREATEPROCEDURE SQLTest(IN tables VARCHAR(200),IN num INTEGER) ,java class也用的是SQLTest,但是在調(diào)存儲(chǔ)過(guò)程時(shí)會(huì)抱錯(cuò),說(shuō)找不到SQLTEST.procedureTest方法,原來(lái)數(shù)據(jù)庫(kù)在創(chuàng)建存儲(chǔ)過(guò)程時(shí),即使你使用SQLTest,但也會(huì)被執(zhí)行為SQLTEST,所以只有都改成大寫(xiě)。

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



          評(píng)論

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

          2006-12-21 20:37 by 兵臨城下
          經(jīng)過(guò)測(cè)試才知道,并不是procedure比sql慢,而是SELECT * FROM table這樣短的sql語(yǔ)句不能顯示出procedure的性能,如果sql語(yǔ)句加長(zhǎng),procedure的性能就顯示出來(lái)了。
          原理上看:普通的sql語(yǔ)句,每個(gè)sql都要到DB端進(jìn)行編譯,而procedure只要傳入?yún)?shù)就可,減少了編譯量,所以在頻繁使用基本相同的sql語(yǔ)句,或sql語(yǔ)句較長(zhǎng)時(shí),應(yīng)該考驗(yàn)適用procedure
          主站蜘蛛池模板: 海盐县| 灵寿县| 上饶市| 巴彦淖尔市| 青阳县| 甘泉县| 开江县| 杂多县| 易门县| 射洪县| 洛宁县| 鸡西市| 揭西县| 河曲县| 思茅市| 辉南县| 锡林浩特市| 奎屯市| 吉安市| 宝坻区| 珠海市| 桓仁| 通州市| 凤冈县| 贵德县| 锦州市| 方城县| 乐至县| 永平县| 凤冈县| 南郑县| 教育| 西乌| 曲麻莱县| 伽师县| 迭部县| 和平县| 会昌县| 博客| 南岸区| 河间市|