詳解Java的JDBC API的存儲進程與SQL本義語法的應用。本站提示廣大學習愛好者:(詳解Java的JDBC API的存儲進程與SQL本義語法的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解Java的JDBC API的存儲進程與SQL本義語法的應用正文
正如一個Connection對象創立Statement和PreparedStatement對象,它也發明了CallableStatement對象這將被用來履行挪用數據庫存儲進程。
創立CallableStatement對象:
假定,須要履行以下Oracle存儲進程:
CREATE OR REPLACE PROCEDURE getEmpName (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS BEGIN SELECT first INTO EMP_FIRST FROM Employees WHERE ID = EMP_ID; END;
留意: 下面曾經寫過Oracle存儲進程,但我們正在應用MySQL數據庫,寫雷同的存儲進程關於MySQL以下,以EMP數據庫中創立它:
DELIMITER $$ DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$ CREATE PROCEDURE `EMP`.`getEmpName` (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255)) BEGIN SELECT first INTO EMP_FIRST FROM Employees WHERE ID = EMP_ID; END $$ DELIMITER ;
三品種型的參數有:IN,OUT和INOUT。PreparedStatement對象只應用IN參數。 CallableStatement對象可使用一切的三個。
這裡是每一個界說:
上面的代碼片斷顯示了若何應用該Connection.prepareCall()辦法實例化基於上述存儲進程CallableStatement對象:
CallableStatement cstmt = null; try { String SQL = "{call getEmpName (?, ?)}"; cstmt = conn.prepareCall (SQL); . . . } catch (SQLException e) { . . . } finally { . . . }
String變量的SQL表現存儲進程,應用參數占位符。
應用CallableStatement對象是應用PreparedStatement對象。必需將值綁定到一切的參數履行該語句之前,不然將收到一個SQLException。
假如有IN參數,只需依照實用於PreparedStatement對象雷同的規矩和技能;應用對應於要綁定Java數據類型的setXXX()辦法。
當應用OUT和INOUT參數就必需采取額定CallableStatement辦法的registerOutParameter()。registerOutParameter()辦法JDBC數據類型綁定到數據類型的存儲進程前往。
一旦挪用存儲進程,用getXXX()辦法的輸入參數檢索值。這類辦法投射SQL類型的值檢索到Java數據類型。
封閉CallableStatement 對象:
正如封閉其他Statement對象,出於異樣的緣由,也應當封閉CallableStatement對象。
close()辦法簡略的挪用將完成這項任務。假如封閉了Connection對象起首它會封閉CallableStatement對象為好。但是,應當一直明白封閉的CallableStatement對象,以確保准確的消除。
CallableStatement cstmt = null; try { String SQL = "{call getEmpName (?, ?)}"; cstmt = conn.prepareCall (SQL); . . . } catch (SQLException e) { . . . } finally { cstmt.close(); }
PS:CallableStatement對象實例
上面是應用CallableStatement連同以下getEmpName()的MySQL存儲進程的例子:
請肯定曾經在EMP數據庫中創立該存儲進程。可使用MySQL查詢閱讀器來完成它。
DELIMITER $$ DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$ CREATE PROCEDURE `EMP`.`getEmpName` (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255)) BEGIN SELECT first INTO EMP_FIRST FROM Employees WHERE ID = EMP_ID; END $$ DELIMITER ;
基於對情況和數據庫裝置在後面的章節中停止,這個典范程式碼已被寫入。
復制上面的例子中JDBCExample.java,編譯並運轉,以下所示:
//STEP 1. Import required packages import java.sql.*; public class JDBCExample { // JDBC driver name and database URL static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/EMP"; // Database credentials static final String USER = "username"; static final String PASS = "password"; public static void main(String[] args) { Connection conn = null; CallableStatement stmt = null; try{ //STEP 2: Register JDBC driver Class.forName("com.mysql.jdbc.Driver"); //STEP 3: Open a connection System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL,USER,PASS); //STEP 4: Execute a query System.out.println("Creating statement..."); String sql = "{call getEmpName (?, ?)}"; stmt = conn.prepareCall(sql); //Bind IN parameter first, then bind OUT parameter int empID = 102; stmt.setInt(1, empID); // This would set ID as 102 // Because second parameter is OUT so register it stmt.registerOutParameter(2, java.sql.Types.VARCHAR); //Use execute method to run stored procedure. System.out.println("Executing stored procedure..." ); stmt.execute(); //Retrieve employee name with getXXX method String empName = stmt.getString(2); System.out.println("Emp Name with ID:" + empID + " is " + empName); stmt.close(); conn.close(); }catch(SQLException se){ //Handle errors for JDBC se.printStackTrace(); }catch(Exception e){ //Handle errors for Class.forName e.printStackTrace(); }finally{ //finally block used to close resources try{ if(stmt!=null) stmt.close(); }catch(SQLException se2){ }// nothing we can do try{ if(conn!=null) conn.close(); }catch(SQLException se){ se.printStackTrace(); }//end finally try }//end try System.out.println("Goodbye!"); }//end main }//end JDBCExample
如今編譯下面的例子以下:
C:>javac JDBCExample.java
當運轉JDBCExample,它會發生以下成果:
C:>java JDBCExample
Connecting to database... Creating statement... Executing stored procedure... Emp Name with ID:102 is Zaid Goodbye!
JDBC的SQL本義語法:
本義語法使可以或許應用經由過程應用尺度的JDBC辦法和屬性,沒法應用數據庫的某些特征的靈巧性。
普通的SQL本義語法格局以下:
{keyword 'parameters'}
這裡有以下這些,會發明異常有效的,而如許做的JDBC編程的本義序列:
d, t, ts 症結字:
他們贊助肯定日期,時光和時光戳記文字。如所知,沒有兩個數據庫治理體系是基於時光和日期的方法雷同。此本義語法告知驅動法式出現在目的數據庫的格局,日期或時光。完成例子:
{d 'yyyy-mm-dd'}
個中yyyy=年,mm =月,DD =日。應用這類語法 {d '2009-09-03'}是2009年3月9日。
上面是一個簡略的例子解釋若何拔出日期表:
//Create a Statement object stmt = conn.createStatement(); //Insert data ==> ID, First Name, Last Name, DOB String sql="INSERT INTO STUDENTS VALUES" + "(100,'Zara','Ali', {d '2001-12-16'})"; stmt.executeUpdate(sql);
異樣,可使用以下兩種語法之一,不管是 t 或 ts:
{t 'hh:mm:ss'}
個中hh=小時,mm=分,ss=秒。應用此語法 {t '13:30:29'}是下晝1點三非常29秒.
{ts 'yyyy-mm-dd hh:mm:ss'}
這是上述兩種語法 'd' 和 't' 來表現時光戳聯合語法。
escape 症結字:
該症結字標識LIKE子句中應用的本義字符。有效應用SQL通配符%,個中婚配零個或多個字符時。例如:
String sql = "SELECT symbol FROM MathSymbols WHERE symbol LIKE '\%' {escape ''}"; stmt.execute(sql);
假如應用反斜槓字符()作為本義字符,還必需應用兩個反斜槓字符在Java字符串字面,由於反斜槓也是一個Java本義字符。
fn 症結字:
此症結字代表在DBMS中應用標量函數。例如,可使用SQL length函數盤算GE字符串的長度:
{fn length('Hello World')}
這將前往11,字符串 'Hello World'的長度。.
call 症結字:
此症結字是用來挪用存儲進程。例如,關於一個存儲進程,須要一個IN參數,請應用以下語法:
{call my_procedure(?)};
關於一個存儲進程,須要一個IN參數並前往一個OUT參數,應用上面的語法:
{? = call my_procedure(?)};
oj 症結字:
此症結字用來表現內部聯接。其語法以下:
{oj outer-join}
外銜接表={LEFT| RIGHT| FULL}外銜接{表|外銜接}的搜刮前提。例如:
String sql = "SELECT Employees FROM {oj ThisTable RIGHT OUTER JOIN ThatTable on id = '100'}"; stmt.execute(sql);