自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JDBC數(shù)據(jù)庫(kù)連接池執(zhí)行DDL和SQLJ存儲(chǔ)過(guò)程

開(kāi)發(fā) 后端
如何利用Java的數(shù)據(jù)庫(kù)連接池JDBC執(zhí)行DDL和SQLJ存儲(chǔ)過(guò)程的方法?本文將探討針對(duì)執(zhí)行DDL和SQLJ存儲(chǔ)過(guò)程數(shù)據(jù)庫(kù)腳本文件引出的依賴數(shù)據(jù)庫(kù)環(huán)境和難以控制輸出的兩大缺點(diǎn)用JDBC執(zhí)行DDL和SQLJ存儲(chǔ)過(guò)程的方法。

我們?cè)?jīng)介紹Java四大連接池中的JDBC(Java Data Base Connectivity,Java 數(shù)據(jù)庫(kù)連接池)是一種用于執(zhí)行 SQL 語(yǔ)句的 Java API,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪問(wèn)接口,它由一組用 Java 語(yǔ)言編寫的類和接口組成。JDBC 為數(shù)據(jù)庫(kù)應(yīng)用開(kāi)發(fā)人員、數(shù)據(jù)庫(kù)前臺(tái)工具開(kāi)發(fā)人員提供了一個(gè)標(biāo)準(zhǔn)的 API,據(jù)此可以構(gòu)建更高級(jí)的工具和接口,使數(shù)據(jù)庫(kù)開(kāi)發(fā)人員能夠用純 Java API 編寫數(shù)據(jù)庫(kù)應(yīng)用程序。

DDL(Data Definition Language)是指數(shù)據(jù)定義語(yǔ)句用于定義和管理 SQL 模式、基本表、視圖、索引和存儲(chǔ)過(guò)程等數(shù)據(jù)庫(kù)中的對(duì)象。

SQLJ 由一系列定義了 SQL 與 Java 之間相互作用的子句和程序擴(kuò)充組成。SQLJ 是在 Java 編程語(yǔ)言中靜態(tài)嵌入式 SQL。本文研究的 SQLJ 存儲(chǔ)過(guò)程特指 DB2 數(shù)據(jù)庫(kù)提供的內(nèi)嵌 SQLJ 存儲(chǔ)過(guò)程,例如 SQLJ.DB2_INSTALL_JAR 存儲(chǔ)過(guò)程,它用于創(chuàng)建一個(gè)新定義的 JAR 文件到特定的數(shù)據(jù)庫(kù)。

本文在系統(tǒng)分析利用數(shù)據(jù)庫(kù)腳本文件執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程缺點(diǎn)的基礎(chǔ)上,提出并詳細(xì)介紹了利用 Java JDBC 執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的方法。

方法提出的背景

在 Java 與數(shù)據(jù)庫(kù)交互編程過(guò)程中,經(jīng)常遇到這樣的場(chǎng)景:需要執(zhí)行大量的 DDL 語(yǔ)句和 SQLJ 存儲(chǔ)過(guò)程,并且這些語(yǔ)句之間有著較強(qiáng)的依賴關(guān)系。下面是一個(gè)這樣的例子,SQL 語(yǔ)句中既有多條 DDL 又有對(duì) DB2 內(nèi)嵌 SQLJ 存儲(chǔ)過(guò)程的調(diào)用。

清單 1. DDL 和 SQLJ 存儲(chǔ)過(guò)程語(yǔ)句示例

  1. -- -- connect to the &database   
  2. connect to &database user &user using &password;   
  3. -- -- install Stored Procedure   
  4. DROP PROCEDURE DB2TOOL.CALLDB2ADVIS;   
  5. CALL SQLJ.REMOVE_JAR ('DB2TOOL.CALLDB2ADVIS');   
  6. CALL SQLJ.REFRESH_CLASSES();   
  7. CALL SQLJ.INSTALL_JAR('file:/home/luwsp.jar', 'DB2TOOL.CALLDB2ADVIS');------------- ①  
  8. CALL SQLJ.REFRESH_CLASSES();   
  9. -- -- create Stored Procedure   
  10. CREATE PROCEDURE DB2TOOL.CALLDB2ADVIS ( INOUT major_version INTEGER,   
  11.          INOUT minor_version INTEGER,   
  12.          IN requested_locale VARCHAR(33),   
  13.          IN xml_input BLOB(32M),   
  14.          IN xml_filter BLOB(4K),   
  15.          OUT xml_output BLOB(4K),   
  16.          OUT xml_message BLOB(64K) )   
  17. DYNAMIC RESULT SETS 3   
  18. NOT DETERMINISTIC   
  19. LANGUAGE Java   
  20. EXTERNAL NAME 'DB2TOOL.CALLDB2ADVIS:com.ibm.datatools.ia.luw.CALLDB2ADVIS.cALLDB2ADVIS'  
  21.  FENCED   
  22.  THREADSAFE   
  23.  PARAMETER STYLE JAVA;      --------------------------------------------------------- ②  
  24. -- -- grant the execution privilege to public       
  25. GRANT EXECUTE ON PROCEDURE DB2TOOL.CALLDB2ADVIS TO PUBLIC WITH GRANT OPTION;   
  26. connect reset;   
  27. terminate;   
  28.  

在上面的 SQL 語(yǔ)句中,語(yǔ)句之間的依賴性很強(qiáng)。例如,如果語(yǔ)句①不能正確執(zhí)行,直接影響到語(yǔ)句②的執(zhí)行,因?yàn)樗鼈冎按嬖谥藐P(guān)系。針對(duì)這種情況的 Java 數(shù)據(jù)庫(kù)交互編程,通常采用將這些語(yǔ)句封裝成一個(gè)數(shù)據(jù)庫(kù) SQL 腳本文件去執(zhí)行,主要執(zhí)行過(guò)程如下:

◆準(zhǔn)備數(shù)據(jù)庫(kù)腳本文件的執(zhí)行環(huán)境,主要是對(duì)一些環(huán)境變量的設(shè)置;

◆運(yùn)行數(shù)據(jù)庫(kù)腳本文件,把輸出結(jié)果定向到特定的文件;

◆Java 程序系統(tǒng)的分析數(shù)據(jù)庫(kù)腳本文件的輸出結(jié)果,得到每一條 SQL 的運(yùn)行狀況;

◆清除數(shù)據(jù)庫(kù)腳本文件的執(zhí)行環(huán)境,還原到初始狀態(tài)。

這種運(yùn)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的方法,存在著以下幾個(gè)缺點(diǎn):

◆依賴數(shù)據(jù)庫(kù)環(huán)境。需要在過(guò)程的開(kāi)始階段,對(duì)腳本文件的執(zhí)行環(huán)境進(jìn)行初始化,在腳本文件運(yùn)行結(jié)束后,必須對(duì)環(huán)境進(jìn)行清除;

◆難以對(duì)執(zhí)行過(guò)程進(jìn)行控制。例如在清單 1 中的 SQL 語(yǔ)句執(zhí)行過(guò)程中,如果語(yǔ)句①執(zhí)行失敗,腳本文件不會(huì)終止運(yùn)行并把錯(cuò)誤信息發(fā)送給 Java 程序,而會(huì)繼續(xù)執(zhí)行下一條 SQL 語(yǔ)句,這時(shí)可以確定語(yǔ)句②必定執(zhí)行失敗,但是腳本文件還是強(qiáng)制執(zhí)行語(yǔ)句②;

◆腳本文件的輸出結(jié)果難以處理。由于 SQL 語(yǔ)句在不同的數(shù)據(jù)庫(kù)環(huán)境下,輸出結(jié)果的格式信息有所變化,這就極大的影響了 Java 程序讀取輸出結(jié)果的準(zhǔn)確性,難以精確的定位到出現(xiàn)問(wèn)題的 SQL 語(yǔ)句;

本文針對(duì)執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程數(shù)據(jù)庫(kù)腳本文件引出的這些缺點(diǎn),提出了利用 Java JDBC 執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的方法。方法的一些簡(jiǎn)單示例代碼如下。

清單 2. 簡(jiǎn)單的示例代碼

  1. Driver dbDriver=(Driver)Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();  
  2.         String url="jdbc:db2://"+host+":"+port+"/"+database+"";  
  3.         Properties p = new Properties();  
  4.         p.put("user", username);  
  5.         p.put("password",password);  
  6.         conndbDriver.connect(url,p);  
  7.     try{   
  8.         stat=conn.createStatement();   
  9.         stat.executeUpdate(“DROP PROCEDURE DB2TOOL.CALLDB2ADVIS”);  
  10.         stmt = conn.prepareCall(“CALL SQLJ.REFRESH_CLASSES()”);  
  11.         stmt.execute();                       
  12.     }  
  13.     catch(SQLException e){  
  14.         System.out.println(e.getMessage());  
  15.     }  
  16.         stat.close();  
  17.         stmt.close();  
  18.         conn.close();  
  19.  

通過(guò)上面的示例代碼,可以了解到利用 Java JDBC 執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的基本步驟:

◆建立數(shù)據(jù)庫(kù)連接;

◆根據(jù)需要?jiǎng)?chuàng)建合適的 Java JDBC Statement 對(duì)象;

◆根據(jù) SQL 語(yǔ)句選擇合適的執(zhí)行方法。

在實(shí)際的 Java 與數(shù)據(jù)庫(kù)交互編程的環(huán)境中,總結(jié)分析這種方法具有下列優(yōu)點(diǎn):

◆容易與 Java 程序進(jìn)行交互??梢垣@取每一條 SQL 語(yǔ)句的執(zhí)行情況,通知 Java 程序選擇運(yùn)行對(duì)應(yīng)的處理邏輯;

◆不依賴數(shù)據(jù)庫(kù)環(huán)境。完全脫離了數(shù)據(jù)庫(kù)環(huán)境的限制,能對(duì)本地或遠(yuǎn)程的數(shù)據(jù)庫(kù)進(jìn)行高效的數(shù)據(jù)操作。

◆能精確的獲取每條 SQL 語(yǔ)句的執(zhí)行狀態(tài)。如果某一條 SQL 語(yǔ)句運(yùn)行失敗,Java 程序能及時(shí)的捕獲到對(duì)應(yīng)的異常信息。

由于 Java JDBC 是通過(guò) Statement 對(duì)象來(lái)執(zhí)行 SQL 語(yǔ)句的,所以它是執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的入口,下面將詳細(xì)介紹 JDBC 包含的幾種 Statement 對(duì)象。

執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的入口:Java JDBC Statement

Java JDBC Statement 對(duì)象用于將 SQL 語(yǔ)句發(fā)送到數(shù)據(jù)庫(kù)中。實(shí)際上有三種 Statement 對(duì)象,它們都作為在給定連接上執(zhí)行 SQL 語(yǔ)句的包容器:Statement、PreparedStatement 和 CallableStatement。它們都專用于發(fā)送特定類型的 SQL 語(yǔ)句。三種 Statement 對(duì)象的關(guān)系如圖 1 所示。

圖 1. 三種 Statement 對(duì)象關(guān)系 
圖 1. 三種 Statement 對(duì)象關(guān)系

Statement 對(duì)象用于執(zhí)行不帶參數(shù)的靜態(tài) SQL 語(yǔ)句,提供了執(zhí)行語(yǔ)句和獲取結(jié)果的基本方法。它的 execute(String sql) 和 executeUpdate(String sql) 方法支持執(zhí)行 DDL 語(yǔ)句。示例代碼如下。

清單 3. Statement 對(duì)象的示例代碼

  1. Statement stat=conn.createStatement();   
  2. stat.executeUpdate(“DROP PROCEDURE DB2TOOL.CALLDB2ADVIS”);   
  3. stat.execute(“DROP FUNCTION DB2TOOL.DEMO_LIC”);   
  4. stat.close();   
  5.  

PreparedStatement 對(duì)象用于執(zhí)行帶或不帶 IN 參數(shù)的預(yù)編譯 SQL 語(yǔ)句,它從 Statement 繼承而來(lái),添加了處理輸入?yún)?shù)的方法,有防止 SQL 注入的功能,還有較好的執(zhí)行效率。它的 execute() 和 executeUpdate() 方法支持執(zhí)行 DDL 語(yǔ)句。使用示例代碼如下。

清單 4. PreparedStatement 對(duì)象的示例代碼

  1. PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES   
  2. SET SALARY = ? WHERE ID = ?");   
  3.     pstmt.setBigDecimal(1, 153833.00);   
  4.     pstmt.setInt(2, 110592);   
  5.     pstmt.executeUpdate();   
  6.     pstmt.close();   
  7.  

CallableStatement 對(duì)象用于執(zhí)行對(duì)數(shù)據(jù)庫(kù)已有存儲(chǔ)過(guò)程的調(diào)用,它從 PreparedStatement 繼承而來(lái),添加了處理輸出參數(shù)的方法。它的 execute() 和 executeUpdate() 方法支持執(zhí)行 DDL 語(yǔ)句。使用示例代碼如下。

清單 5. CallableStatement 對(duì)象的示例代碼

  1. CallableStatement cstm = connection.prepareCall("CALL SQLJ.REMOVE_JAR(?)");  
  2.     cstmt.setString(1, “test”);  
  3.     cstmt.execute();  
  4.     cstmt.close();  
  5.  

Java JDBC 執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程:實(shí)例演示

上一部分詳細(xì)介紹了 Java JDBC 的三種 Statement 對(duì)象,了解了它們之間的關(guān)系和特定的操作對(duì)象,為利用 Java JDBC 執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程奠定了理論基礎(chǔ)。下面的兩個(gè)程序?qū)嵗瑢⒊浞掷眠@三種 Statement 對(duì)象,展示這種方法的實(shí)現(xiàn)過(guò)程及其靈活性。

實(shí)例 1 演示利用 Java JDBC 執(zhí)行 DDL 的方法。需要執(zhí)行的 DDL 語(yǔ)句如下:

清單 6. DDL 語(yǔ)句示例

  1. DROP FUNCTION DB2TOOL.DEMO_LIC;   
  2. CREATE FUNCTION DB2TOOL.DEMO_LIC() RETURNS VARCHAR(8) LANGUAGE SQL CONTAINS SQL   
  3.     NO EXTERNAL ACTION DETERMINISTIC RETURN VARCHAR('DEMO_V10');   
  4. GRANT EXECUTE ON FUNCTION DB2TOOL.DEMO_LIC TO PUBLIC WITH GRANT OPTION;  
  5.  

清單 7. JDBC 執(zhí)行 DDL 代碼示例

  1. Driver dbDriver=(Driver)Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();  
  2.     String url="jdbc:db2://"+host+":"+port+"/"+database+"";  
  3.     Properties p = new Properties();  
  4.     p.put("user", username);  
  5.     p.put("password",password);  
  6.     conndbDriver.connect(url,p);  
  7.     try{  
  8.         Statement stat=conn.createStatement();  
  9.         stat.executeUpdate(“DROP FUNCTION DB2TOOL.DEMO_LIC”);  
  10.         PreparedStatement pstmt = conn.prepareStatement(  
  11.             "CREATE FUNCTION DB2TOOL.DEMO_LIC() RETURNS VARCHAR(8) LANGUAGE SQL   
  12.             CONTAINS SQL NO EXTERNAL ACTION DETERMINISTIC RETURN VARCHAR(?)");  
  13.         pstmt.setString(1,”DEMO_V10”);  
  14.         pstmt.execute();  
  15.         stat.execute(“GRANT EXECUTE ON FUNCTION DB2TOOL.DEMO_LIC TO   
  16.             PUBLIC WITH GRANT OPTION”);  
  17.     } catch(SQLException e){  
  18.         System.out.println(e.getMessage());  
  19.     }  
  20.     stat.close();  
  21.     pstmt.close();  
  22.     conn.close();  
  23.  

實(shí)例 2 演示利用 Java JDBC 執(zhí)行 SQLJ 存儲(chǔ)過(guò)程的方法。需要執(zhí)行的 SQLJ 語(yǔ)句如下:

清單 8. SQLJ 存儲(chǔ)過(guò)程語(yǔ)句示例

  1. CALL SQLJ.REMOVE_JAR ('DB2TOOL.CALLDB2ADVIS');   
  2. CALL SQLJ.REFRESH_CLASSES();   
  3. CALL SQLJ.INSTALL_JAR('file:/home/luwsp.jar', 'DB2TOOL.CALLDB2ADVIS');   
  4. CALL SQLJ.REFRESH_CLASSES();   
  5.  

由于 SQLJ.INSTALL_JAR 存儲(chǔ)過(guò)程僅支持在本地?cái)?shù)據(jù)庫(kù)創(chuàng)建一個(gè)新定義的 JAR 文件,所以在下面的 JDBC 執(zhí)行代碼中使用 SQLJ.DB2_INSTALL_JAR 代替它,擴(kuò)大它的使用范圍。

清單 9. JDBC 執(zhí)行 SQLJ 存儲(chǔ)過(guò)程代碼示例

  1. Driver dbDriver=(Driver)Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();  
  2. String url="jdbc:db2://"+host+":"+port+"/"+database+"";   
  3. Properties p = new Properties();   
  4. p.put("user", username);   
  5. p.put("password",password);   
  6. conndbDriver.connect(url,p);   
  7. CallableStatement cstmt = null;       
  8. try{   
  9.     cstmt = conn.prepareCall(“CALL SQLJ.REMOVE_JAR (?)”);   
  10.     cstmt.setString(1,”DB2TOOL.CALLDB2ADVIS”);   
  11.     cstmt.execute();       
  12.     cstmt = conn.prepareCall(“CALL SQLJ.REFRESH_CLASSES()”);   
  13.     cstmt.execute();   
  14.     File aFile = new File(“/home/luwsp.jar”);   
  15.     FileInputStream inputStream = new FileInputStream(aFile);  
  16.     cstmt = conn.prepareCall(“Call SQLJ.DB2_INSTALL_JAR(?,?,?)”);  
  17.     cstmt.setBinaryStream(1, inputStream, (int)aFile.length());  
  18.     cstmt.setString(2,”DB2TOOL.CALLDB2ADVIS”);   
  19.     cstmt.setInt(3, 0);   
  20.     cstmt.execute();                   
  21.     cstmt = conn.prepareCall(“CALL SQLJ.REFRESH_CLASSES()”);   
  22.     cstmt.execute();   
  23. } catch(SQLException e){   
  24.     System.out.println(e.getMessage());   
  25. }   
  26. cstmt.close();       
  27. conn.close();   
  28.  

上面的兩個(gè)實(shí)例詳細(xì)的展示了利用 Java JDBC 執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的方法,在執(zhí)行的過(guò)程中可以確定每一條 SQL 語(yǔ)句的執(zhí)行狀態(tài),例如三種 Statement 對(duì)應(yīng)的 execute(String sql) 和 execute() 方法能返回 boolean 類型的值,executeUpdate(String sql) 和 executeUpdate() 方法能返回 int 類型的值,可以根據(jù)這些返回值精確的確定每條 SQL 的執(zhí)行狀態(tài),另外也可以通過(guò)捕獲 SQLException 獲得執(zhí)行情況。這兩個(gè)實(shí)例充分體現(xiàn)了本文提出的方法具有靈活性、易于控制執(zhí)行過(guò)程、易于獲得 SQL 執(zhí)行狀態(tài)等優(yōu)點(diǎn)。

總結(jié)

本文主要介紹了利用 Java JDBC 執(zhí)行 DDL 和 SQLJ 存儲(chǔ)過(guò)程的方法,描述了方法提出的背景,詳細(xì)學(xué)習(xí)了 Java JDBC 中的三種 Statement 對(duì)象,最后通過(guò)兩個(gè)實(shí)例展現(xiàn)了方法實(shí)現(xiàn)的過(guò)程,進(jìn)一步證明了使用這種方法,可以使 Java 程序和 DDL,SQLJ 的交互操作變得非常靈活,提高 Java 編程的效率。
 

【編輯推薦】

  1. 幾個(gè)主流的Java連接池
  2. Java的JDBC數(shù)據(jù)庫(kù)連接池實(shí)現(xiàn)方法
  3. Tomcat5+MySQL JDBC連接池配置
  4. 基于JMX監(jiān)控下的JBoss數(shù)據(jù)庫(kù)連接池
  5. JBoss配置mysql數(shù)據(jù)庫(kù)連接池
責(zé)任編輯:佚名 來(lái)源: developerworks
相關(guān)推薦

2009-07-17 13:32:49

JDBC數(shù)據(jù)庫(kù)

2009-06-24 07:53:47

Hibernate數(shù)據(jù)

2010-10-26 16:15:33

連接Oracle數(shù)據(jù)庫(kù)

2010-03-18 15:09:15

python數(shù)據(jù)庫(kù)連接

2017-06-22 14:13:07

PythonMySQLpymysqlpool

2019-11-27 10:31:51

數(shù)據(jù)庫(kù)連接池內(nèi)存

2009-06-16 09:25:31

JBoss配置

2018-10-10 14:27:34

數(shù)據(jù)庫(kù)連接池MySQL

2021-08-12 06:52:01

.NET數(shù)據(jù)庫(kù)連接池

2020-04-30 14:38:51

數(shù)據(jù)庫(kù)連接池線程

2009-07-29 09:33:14

ASP.NET數(shù)據(jù)庫(kù)連

2018-01-03 14:32:32

2011-05-19 09:53:33

數(shù)據(jù)庫(kù)連接池

2025-01-16 10:30:49

2011-07-29 15:11:42

WeblogicOracle數(shù)據(jù)庫(kù)連接

2010-03-18 14:55:17

Python數(shù)據(jù)庫(kù)連接

2009-07-03 17:37:54

JSP數(shù)據(jù)庫(kù)

2009-01-15 09:02:27

JMXJBossJMX監(jiān)控

2009-06-15 13:46:00

netbeans設(shè)置數(shù)據(jù)庫(kù)連接池

2009-07-09 17:36:44

JDBC連接池配置
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)