經過DriverManager
的Connection
,咱們得到了與數據庫鏈接以後,咱們就要與數據庫進行交互了,用Java語言與數據庫進行交互就須要用到JDBC的Statement
,CallableStatement
,PreparedStatement
首先這些都是接口!不能由他們直接建立對象。這三個有不少的共同點。html
PreparedStatement 繼承了Statement接口,至關於擴展了一些功能。java
這三個在使用以前都須要Connection
建立他們的對象。
雖然都是由Connection對象來調用方法來建立,可是他們的方法仍是不同的。mysql
如下 conn
表明着數據庫的鏈接sql
conn.createStatement()
數據庫
值得注意的是,這個方法不接受任何參數。oracle
conn.preparedStatement(SQL)
yii
這個SQL是預編譯的語句,用?
,來佔位。例如:函數
String SQL = "Update Employees SET age = ? WHERE id = ?";
這個?
之後是經過setXXX()
方法來進行輸入的。若是忘記綁定,就會輸出SQLException。
例如:setString(1,"0880");
其中第一個參數是要填充的位置,從1開始,第二個是填充的值。code
Callable對象用於執行對數據庫存儲過程的調用
關於存儲過程的相關信息,在另外一篇文章中,雖然沒有徹底理解,可是仍是有必定的認識的。
如下代碼片斷顯示瞭如何建立一個CallableStatement
對象。htm
CallableStatement cstmt = null; try { String strSQL - "{call getEmpName (?,?)}"; cstmt = conn.prepareCall(strSQL); ... } catch (SQLException e) { ... } finally { ... }
這其中,strSQL
表明的是存儲過程,帶有兩個參數佔位符。CallableStatement
對象和PreparedStatement
對象同樣,在執行語句以前,必須將值綁定到全部參數,不然將跑出一個SQLException
異常。
看一下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;
能夠發現這裏面有三個參數類型,IN
和OUT
和INOUT
首先PreparedStatement對象只是用IN
參數
Callable可使用上面三個參數類型。
更加詳細的:
IN:建立SQL語句時其參數值是未知的,使用setXXX()方法將值綁定到IN參數。
OUT:由SQL語句返回的參數值,可使用getXXX()方法從OUT參數中檢索值。
INOUT:提供輸入和輸出的參數。使用setXXX()
方法綁定變量並使用getXXX()方法檢索值。
見了上面的三個類型。
【實例】使用CallableStatement的示例。
確保在EMP
數據庫中建立了getEmpName()存儲過程,可使用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 ;
查詢emp數據庫的全部存儲過程,以下語句:
mysql> select `name` from mysql.proc where db = 'emp' and `type` = 'PROCEDURE'; +------------+ | name | +------------+ | getEmpName | +------------+ 1 row in set (0.00 sec)
而後再編寫JDBC代碼:
//1. 導包 import java.sql.*; public class JDBCCallableStatement{ //數據庫驅動和URL static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/EMP"; //數據庫用戶名和密碼 static final String USER = "root"; static final String PASD = "123456"; public static void main(String[] args){ //建立兩個對象 Connnection、和 CallableStatement Connection conn = null; CallableStatement stmt = null; //註冊驅動(注意跑出錯誤) try{ Class.forName(JDBC_DRIVER); System.out.println("鏈接數據庫中。。。"); //打開鏈接 conn = DriverManager.getConnection(DB_URL,USER,PASS); //建立statement對象 String sql = "{call getEmpName(?,?)}"; stmt = conn.prepareCall(sql); //先綁定IN參數,而後綁定OUT參數 int empID = 102; stmt.setInt(1,empID);//將ID設置成102 //由於第二個參數是OUT,因此用register它。 stmt.registerOutParameter(2,java.sql,Types.VARCHAR); //使用excute方法去存儲過程 System.out.println("Executing stored procedure"); stmt.execute();//由於在存儲過程當中有相應的sql語句,因此至關於給存儲過程傳入參數後就不須要在爲stmt傳入參數了。 //執行完畢後,亞歐使用getXXX方法,接收employee name String empName = stmt.getString(2); System.out.println("Emp Name with ID:" + empID+ "is " + empName); //關閉鏈接。 stmt.close(); conn.close(); }catch (SQLException se){ //se.printStackTrace(); }catch (Exception e){ e.printStackTrace(); }finally{ //最後關閉資源 try{ if(stmt!=null) stmt.close(); }catch(SQLException se2){ }//什麼都作不了 try{ if(conn!=null) conn.close(); }catch(SQLException se){ se.printStackTrace(); } } System.out.println("GoodBye!"); } }
通過這個就很明瞭了。
建完以上的Statement對象、CallableStatement對象、PreparedStatement對象。咱們就須要經過他們執行Sql語句,和數據庫進行交互了!!!
這三個大致是相同的。
三個方法:boolean execute (String SQL)
: 若是能夠檢索到ResultSet對象,則返回一個布爾值true; 不然返回false。使用此方法執行SQLDDL語句或須要使用真正的動態SQL,可以使用於執行建立數據庫,建立表的SQL語句等等。
int executeUpdate (String SQL)
: 返回受SQL語句執行影響的行數。使用此方法執行預期會影響多行的SQL語句,例如:INSERT,UPDATE或DELETE語句。
ResultSet executeQuery(String SQL)
:返回一個ResultSet對象。 當您但願得到結果集時,請使用此方法,就像使用SELECT語句同樣。
因爲PreparedStatement對象,在建立對象的過程當中就已經傳入了sql語句,並經過SetXXX()方法傳入了參數。因此Statemetn
的三個方法對PreparedStatement
都適用,而且都沒有參數。execute()
executeQuery()
executeUpdate()
暫時還不清楚,不過筆者認爲,應該是使用excute()
就能夠了。
使用close()
函數,便可。