javasqlin佔位符
PreparedStatementprep=conn.prepareStatement(sql);prep.executeQuery();
2. java如何獲得mysql存儲過程的返回值
7 - CallableStatement
本概述是從《JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference 》這本書中摘引來的。JavaSoft 目前正在准備這本書。這本書是一本教程,同時也是 JDBC 的重要參考手冊,它將作為 Java 系列的組成部份在 1997 年春季由 Addison-Wesley 出版公司出版。
7.1 概述
CallableStatement 對象為所有的 DBMS 提供了一種以標准形式調用已儲存過程的方法。已儲存過程儲存在資料庫中。對已儲存過程的調用是 CallableStatement 對象所含的內容。這種調用是用一種換碼語法來寫的,有兩種形式:一種形式帶結果參數,另一種形式不帶結果參數(有關換碼語法的信息,參見第 4 節「語句」)。結果參數是一種輸出 (OUT) 參數,是已儲存過程的返回值。兩種形式都可帶有數量可變的輸入(IN 參數)、輸出(OUT 參數)或輸入和輸出(INOUT 參數)的參數。問號將用作參數的佔位符。
在 JDBC 中調用已儲存過程的語法如下所示。注意,方括弧表示其間的內容是可選項;方括弧本身並不是語法的組成部份。
{call 過程名[(?, ?, ...)]}
返回結果參數的過程的語法為:
{? = call 過程名[(?, ?, ...)]}
不帶參數的已儲存過程的語法類似:
{call 過程名}
通常,創建 CallableStatement 對象的人應當知道所用的 DBMS 是支持已儲存過程的,並且知道這些過程都是些什麼。然而,如果需要檢查,多種 DatabaseMetaData 方法都可以提供這樣的信息。例如,如果 DBMS 支持已儲存過程的調用,則 supportsStoredProceres 方法將返回 true,而 getProceres 方法將返回對已儲存過程的描述。
CallableStatement 繼承 Statement 的方法(它們用於處理一般的 SQL 語句),還繼承了 PreparedStatement 的方法(它們用於處理 IN 參數)。CallableStatement 中定義的所有方法都用於處理 OUT 參數或 INOUT 參數的輸出部分:注冊 OUT 參數的 JDBC 類型(一般 SQL 類型)、從這些參數中檢索結果,或者檢查所返回的值是否為 JDBC NULL。
7.1.1 創建 CallableStatement 對象
CallableStatement 對象是用 Connection 方法 prepareCall 創建的。下例創建 CallableStatement 的實例,其中含有對已儲存過程 getTestData 調用。該過程有兩個變數,但不含結果參數:
CallableStatement cstmt = con.prepareCall(
"{call getTestData(?, ?)}");
其中 ? 佔位符為 IN、 OUT 還是 INOUT 參數,取決於已儲存過程 getTestData。
7.1.2 IN 和 OUT 參數
將 IN 參數傳給 CallableStatement 對象是通過 setXXX 方法完成的。該方法繼承自 PreparedStatement。所傳入參數的類型決定了所用的 setXXX 方法(例如,用 setFloat 來傳入 float 值等)。
如果已儲存過程返回 OUT 參數,則在執行 CallableStatement 對象以前必須先注冊每個 OUT 參數的 JDBC 類型(這是必需的,因為某些 DBMS 要求 JDBC 類型)。注冊 JDBC 類型是用 registerOutParameter 方法來完成的。語句執行完後,CallableStatement 的 getXXX 方法將取回參數值。正確的 getXXX 方法是為各參數所注冊的 JDBC 類型所對應的 Java 類型(從 JDBC 類型到 Java 類型的標准映射見 8.6.1 節中的表)。換言之, registerOutParameter 使用的是 JDBC 類型(因此它與資料庫返回的 JDBC 類型匹配),而 getXXX 將之轉換為 Java 類型。
作為示例,下述代碼先注冊 OUT 參數,執行由 cstmt 所調用的已儲存過程,然後檢索在 OUT 參數中返回的值。方法 getByte 從第一個 OUT 參數中取出一個 Java 位元組,而 getBigDecimal 從第二個 OUT 參數中取出一個 BigDecimal 對象(小數點後面帶三位數):
CallableStatement cstmt = con.prepareCall(
"{call getTestData(?, ?)}");
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3);
cstmt.executeQuery();
byte x = cstmt.getByte(1);
java.math.BigDecimal n = cstmt.getBigDecimal(2, 3);
CallableStatement 與 ResultSet 不同,它不提供用增量方式檢索大 OUT 值的特殊機制。
7.1.3 INOUT 參數
既支持輸入又接受輸出的參數(INOUT 參數)除了調用 registerOutParameter 方法外,還要求調用適當的 setXXX 方法(該方法是從 PreparedStatement 繼承來的)。setXXX 方法將參數值設置為輸入參數,而 registerOutParameter 方法將它的 JDBC 類型注冊為輸出參數。setXXX 方法提供一個 Java 值,而驅動程序先把這個值轉換為 JDBC 值,然後將它送到資料庫中。
這種 IN 值的 JDBC 類型和提供給 registerOutParameter 方法的 JDBC 類型應該相同。然後,要檢索輸出值,就要用對應的 getXXX 方法。例如,Java 類型為 byte 的參數應該使用方法 setByte 來賦輸入值。應該給 registerOutParameter 提供類型為 TINYINT 的 JDBC 類型,同時應使用 getByte 來檢索輸出值 (第 8 節「JDBC 和 Java 類型之間的映射」將給出詳細信息和類型映射表)。
下例假設有一個已儲存過程 reviseTotal,其唯一參數是 INOUT 參數。方法 setByte 把此參數設為 25,驅動程序將把它作為 JDBC TINYINT 類型送到資料庫中。接著,registerOutParameter 將該參數注冊為 JDBC TINYINT。執行完該已儲存過程後,將返回一個新的 JDBC TINYINT 值。方法 getByte 將把這個新值作為 Java byte 類型檢索。
CallableStatement cstmt = con.prepareCall(
"{call reviseTotal(?)}");
cstmt.setByte(1, 25);
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.executeUpdate();
byte x = cstmt.getByte(1);
7.1.4 先檢索結果,再檢索 OUT 參數
由於某些 DBMS 的限制,為了實現最大的可移植性,建議先檢索由執行 CallableStatement 對象所產生的結果,然後再用 CallableStatement.getXXX 方法來檢索 OUT 參數。
如果 CallableStatement 對象返回多個 ResultSet 對象(通過調用 execute 方法),在檢索 OUT 參數前應先檢索所有的結果。這種情況下,為確保對所有的結果都進行了訪問,必須對 Statement 方法 getResultSet、getUpdateCount 和 getMoreResults 進行調用,直到不再有結果為止。
檢索完所有的結果後,就可用 CallableStatement.getXXX 方法來檢索 OUT 參數中的值。
7.1.5 檢索作為 OUT 參數的 NULL 值
返回到 OUT 參數中的值可能會是 JDBC NULL。當出現這種情形時,將對 JDBC NULL 值進行轉換以使 getXXX 方法所返回的值為 null、0 或 false,這取決於 getXXX 方法類型。對於 ResultSet 對象,要知道 0 或 false 是否源於 JDBC NULL 的唯一方法,是用方法 wasNull 進行檢測。如果 getXXX 方法讀取的最後一個值是 JDBC NULL,則該方法返回 true,否則返回 flase。
3. 怎麼使用JAVA連接資料庫
1、載入驅動程序。
處理結果兩種情況:
1、執行更新返回的是本次操作影響到的記錄數。
2、執行查詢返回的結果是一個ResultSet對象。
ResultSet包含符合SQL語句中條件的所有行,並且它通過一套get方法提供了對這些 行中數據的訪問。
(3)javasqlin佔位符擴展閱讀:
Statement
要執行SQL語句,必須獲得java.sql.Statement實例,Statement實例分為以下3 種類型:
1、執行靜態SQL語句。通常通過Statement實例實現。
2、執行動態SQL語句。通常通過PreparedStatement實例實現。
3、執行資料庫存儲過程。通常通過CallableStatement實例實現。
4. (高分)急求連接資料庫的JAVA學生信息管理系統源代碼
資料庫連接(Connection)
資料庫連接
獲取資料庫連接有兩種方法,一種是通過驅動程序管理器DriverManager類,另一種則是使用DataSource介面。這兩種方法都提供了了一個getConnection方法,用戶可以在程序中對它們進行相應處理後調用這個方法來返回資料庫連接。
• DriverManager類
• DataSource介面
• Connection介面
• JDBC URL
jdbc:<subprotocol>:<subname>
• 驅動程序注冊方法
(1)調用Class.forName方法
(2)設置jdbc.drivers系統屬性
• DriverManager方法
DriverManager類中的所有方法都是靜態方法,所以使用DriverManager類的方法時,不必生成實例。
DriverManager
• getConnection方法
作用是用於獲取資料庫連接,原型如下:
public static Connection getConnection(String url)
throws SQLException;
public static Connection getConnection(String url, String user, String password)
throws SQLException;
public static Connection getConnection(String url, Properties info)
throws SQLException;
• 使用DriverManager的getConnetion方法
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection
("jdbc:odbc:sqlserver", "sa", "sa");
• 使用設置jdbc.drivers系統屬性的方法
java -Djdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver test.java
DataSource 介面
……
//從上下文中查找數據源,並獲取資料庫連接
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("sqlserver");
Connection conn = ds.getConnection();
//查詢資料庫中所有記錄
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM student");
……
Connection 介面
Connection介面代表了已經建立的資料庫連接,它是整個JDBC的核心內容。Connnection介面中的方法按照它們所實現的功能,可以分為三類:
• 生成資料庫語句
• 管理資料庫事務
• 獲取資料庫信息
生成資料庫語句
JDBC將資料庫語句分成三種類型 :
• 生成Statement 語句 :
Connection.createStatement()
• 生成PreparedStatement 語句 :
Connection. prepareStatement()
• 生成CallableStatement 語句 :
Connection. prepareCall ()
管理資料庫事務
• 默認情況下,JDBC將一條資料庫語句視為一個完整的事務。可以關掉默認事務管理:
public void setAutoCommit(Boolean autoCommit) throws SQLException;
將autoCommit的值設置為false,就關掉了自動事務管理模式
• 在執行完事務後,應提交事務:
public void commit() throws SQLException;
• 可以取消事務:
public void rollback() throws SQLException;
第二講 第四部分
資料庫語句
資料庫語句
JDBC資料庫語句共有三種類型:
• Statement:
Statement語句主要用於嵌入一般的SQL語句,包括查詢、更新、插入和刪除等等。
• PreparedStatement:
PreparedStatement語句稱為准備語句,它是將SQL語句中的某些參數暫不指定,而等到執行時在統一指定。
• CallableStatement:
CallableStatement用於執行資料庫的存儲過程。
Statement 語句
• executeQuery方法
• executeUpdate方法
• execute方法
• close方法
executeQuery方法
• executeQuery方法主要用於執行產生單個結果集的SQL查詢語句(QL),即SELECT語句。executeQuery方法的原型如下所示:
• public ResultSet executeQuery(String sql) throws SQLException;
executeUpdate方法
• executeUpdate方法主要用於執行 INSERT、UPDATE、DELETE語句,即SQL的數據操作語句(DML)
• executeUpdate方法也可以執行類似於CREATE TABLE和DROP TABLE語句的SQL數據定義語言(DDL)語句
• executeUpdate方法的返回值是一個整數,指示受影響的行數(即更新計數)。而對於CREATE TABLE 或 DROP TABLE等並不操作特定行的語句,executeUpdate的返回值總為零。
execute方法
execute方法用於執行:
• 返回多個結果集
• 多個更新計數
• 或二者組合的語句
execute方法
• 返回多個結果集:首先要調用getResultSet方法獲得第一個結果集,然後調用適當的getter方法獲取其中的值。要獲得第二個結果集,需要先調用getMoreResults方法,然後再調用getResultSet方法。
• 返回多個更新計數:首先要調用getUpdateCount方法獲得第一更新計數。然後調用getMoreResults,並再次調用getUpdateCount獲得後面的更新計數。
• 不知道返回內容:如果結果是ResultSet對象,則execute方法返回true;如果結果是int類型,則意味著結果是更新計數或執行的語句是DDL命令。
execute方法
為了說明如果處理execute方法返回的結果,下面舉一個代碼例子:
stmt.execute(query);
while (true) {
int row = stmt.getUpdateCount();
//如果是更新計數
if (row > 0) {
System.out.println("更新的行數是:" + row);
stmt.getMoreResults();
continue;
}
execute方法
//如果是DDL命令或0個更新
if (row == 0) {
System.out.println("沒有更新,或SQL語句是一條DDL語句!");
stmt.getMoreResults();
continue;
}
//如果是一個結果集
ResultSet rs = stmt.getResultSet;
if (rs != null) {
while (rs.next()) {
// 處理結果集
. . .
}
stmt.getMoreResults();
continue;
}
break;
}
PreparedStatement 語句
登錄一個網站或BBS時 :
• 使用Statement語句
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery
(「SELECT password FROM userinfo
WHERE id=userId");
• 使用PreparedStatement語句
PreparedStatement pstmt=conn.prepareStatement
(「SELECT password FROM userinfo
WHERE id=?");
pstmt.setString(1, userId);
PreparedStatement語句
• 常用的setter方法
public void setBoolean(int parameterIndex, boolean x) throws SQLException;
public void setByte(int parameterIndex, byte x) throws SQLException;
public void setShort(int parameterIndex, short x) throws SQLException;
public void setInt(int parameterIndex,int x) throws SQLException;
public void setLong(int parameterIndex, long x) throws SQLException;
public void setFloat(int parameterIndex, float x) throws SQLException;
public void setDouble(int parameterIndex, double x) throws SQLException;
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException;
public void setString(int parameterIndex, String x) throws SQLException;
public void setBytes(int parameterIndex, byte[] x) throws SQLException;
public void setDate(int parameterIndex, Date x) throws SQLException;
public void setTime(int parameterIndex, Time x) hrows SQLException;
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException;
PreparedStatement語句
• PreparedStatement介面是由Statement介面擴展而來的,重寫了executeQuery方法、executeUpdate方法和execute 方法
• public ResultSet executeQuery() throws SQLException
• public int executeUpdate() throws SQLException
• public boolean execute() throws SQLException
CallableStatement語句
• CallableStatement語句是由Connection介面的prepareCall方法創建的,創建時需要傳入字元串參數,參數的形式為:
• {call procere_name[(?, ?, ...)]}
• {? = call procere_name[(?, ?, ...)]}
• {call procere_name}
CallableStatement語句
• 其中的問號是參數佔位符,參數共有兩種:
• IN參數
• OUT參數
• IN參數使用setter方法來設置
• OUT參數則使用registerOutParameter方法來設置
CallableStatement 語句
CallableStatement cstmt = con.prepareCall
("{call getTestData(?, ?)}");
cstmt.registerOutParameter
(1, java.sql.Types.TINYINT);
cstmt.registerOutParameter
(2, java.sql.Types.DECIMAL, 3);
cstmt.executeQuery();
byte x = cstmt.getByte(1);
java.math.BigDecimal n =
cstmt.getBigDecimal(2, 3);
第二講 第五部分
結 果 集
結果集
• JDBC為了方便處理查詢結果,又專門定義了一個介面,這個介面就是ResultSet介面。ResultSet介面提供了可以訪問資料庫查詢結果的方法,通常稱這個介面所指向的對象為結果集。
• 有兩種方法得到結果集,一種是直接執行查詢語句,將結果存儲在結果集對象上;另一種是不存儲返回結果,而在需要時調用資料庫語句的getResultSet方法來返回結果集
結果集
• 結果集指針
由於返回的結果集可能包含多條數據記錄,因此ResultSet 介面提供了對結果集的所有數據記錄輪詢的方法。結果集自動維護了一個指向當前數據記錄的指針,初始時這個指針是指向第一行的前一個位置。 next 方法就是用於向前移動指針的
結果集
• 結果集屬性
默認情況下,結果集是一個不可更新集,並且結果集的指針也只能向前移動。也就是說,在得到了一個結果集之後,用戶只能按照從第一條記錄到最後一條記錄的順序依次向後讀取,而不能跳到任意條記錄上,也不能返回到前面的記錄。不僅如此,結果集的這種輪詢只能進行一次,而不能再將指針重置到初始位置進行多次輪詢
結果集
• 結果集屬性
類型
並發性
有效性
• 屬性的設置是在生成資料庫語句時通過向生成方法傳入相應的參數設定的,而當結果集已經返回時就不能夠再改變它的屬性了。
結果集生成Statement語句共有三種方法
public Statement createStatement() throws SQLException;
public Statement createStatement
(int resultSetType, int resultSetConcurrency)
throws SQLException;
public Statement createStatement
(int resultSetType, int resultSetConcurrency,
int resultSetHoldability)
throws SQLException;
結果集
• 生成PreparedStatement語句共有六種方法
public PreparedStatement prepareStatement(String sql) throws SQLException;
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException;
public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
throws SQLException;
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException;
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException;
public PreparedStatement prepareStatement(String sql. String[] columnNames)
throws SQLException;
結果集
• 生成CallableStatement語句共有三種方法
public CallableStatement prepareCall(String sql)
throws SQLException;
public CallableStatement prepareCall
(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException;
public CallableStatement prepareCall
(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException;
結果集
結果集類型
• 結果集的類型共有三種,TYPE_FORWARD_ONLY類型的結果集只能向前移動指針,而TYPE_SCROLL_INSENSITIVE類型和TYPE_SCROLL_SENSITIVE類型的結果集則可以任意移動指針。後兩種類型的區別在於,前者對來自其它處的修改不敏感(靜態),而後者則對於別人的修改敏感(動態視圖)。
結果集
結果集類型
• 對於可以任意移動指針的結果集,可以用來移動指針的方法包括:
• next 和previous :
• absolute 和relative :參數可正可負
• afterLast 、beforeFirst 、last 和first :
結果集
結果集並發性
• 結果集的並發性共有兩種,CONCUR_READ_ONLY的結果集是只讀而不可更新的;而CONCUR_UPDATABLE的結果集則是可以通過update方法進行更新的。
• ResultSet介面提供了一組update方法,用於更新結果集中的數據。這些方法與PreparedStatement介面中定義的setter方法一樣,也是與類型相對應的。所有的update方法都以update開頭 。
• 所有的update方法都有兩個參數,第一個參數用於指定更新的列,它可以是列名稱也可以是列的序號;第二個參數則表示將要更新列的值。
結果集
結果集並發性
• Statement stmt = conn.createStatement
• (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
• ResultSet rs = stmt.executeQuery("SELECT * FROM student " +
• "WHERE grade=2 AND math>60 AND physics>60 AND " +
• "chemistry>60 AND english>60 AND chinese>60");
• while(rs.next()){
• rs.updateString("grade", "3");
• rs.updateRow();
• }
結果集
結果集有效性
• 結果集的有效性是指在調用了Connection 介面的commit 方法後,結果集是否自動關閉。所以它只有兩個可選值,即HOLD_CURSORS_OVER_COMMIT 和CLOSE_CURSORS_AT_COMMIT 。前者表示調用commit 方法之後,結果集不關閉;而後者則表示關閉結果集。
結果結果集
• 結果集的getter方法
ResultSet介面還提供了一組getter方法,用於返回當前記錄的屬性值。它們都是以get開頭的,後接數據類型。比如,如果要返回一個float類型的列值,則應調用getFloat方法。每一種類型的getter方法都有兩種形式,它們的名稱相同而參數不同。這兩種形式的getter方法都只有一個參數,第一種形式的getter方法參數是String類型的,用於指定列的名稱;另外一種形式的getter方法參數則是int類型的,用於指定列的序號。