servlet學習筆記之四
——數(shù)據(jù)庫訪問
1.JDBC-ODBC橋,其本身也是一個驅(qū)動,利用這個驅(qū)動,我們可以使用JDBC API 通過ODBC去訪問數(shù)據(jù)庫。這種橋機制實際上是把標準的JDBC 調(diào)用轉(zhuǎn)換成相應(yīng)的ODBC 調(diào)用,因此這種方式訪問數(shù)據(jù)庫效率是比較低。也有些數(shù)據(jù)庫沒有提供JDBC驅(qū)動,只有ODBC 驅(qū)動,比如訪問ms access數(shù)據(jù)庫就只能利用JDBC-ODBC 橋來訪問。
2.建立到數(shù)據(jù)庫的連接
DriverManager類的getConection()方法建立到數(shù)據(jù)庫的連接,返回一個Connection對象。在DriverManager類中提供了3個重載的getConnection()方法。
² public static Connection getConnection(String url)throws SQLException
給方法通過給出數(shù)據(jù)庫URL建立到數(shù)據(jù)庫的連接。比如:
Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection ("jdbc:odbc:test");
² public static Connection getConnection(String url,String user,String psw)throws SQLException
給方法取得數(shù)據(jù)庫連接必須給出用戶名和密碼。如:
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn = DriverManager.getConnection(urlname,user,pw);
² public static Connection getConnection(String url,Properties info)throws SQLException
其中info 鍵值對,一般需要給出用戶名和密碼。
3.訪問數(shù)據(jù)庫
數(shù)據(jù)庫連接被用于向數(shù)據(jù)庫服務(wù)器發(fā)送命令和SQL語句,在連接建立后,需要對數(shù)據(jù)庫進行訪問,執(zhí)行SQL語句。在java.sql包中給我們提供了3個接口:Statement,PreparedStatement ,CallableStatement.
Statement
調(diào)用Connection對象的creatStatement()方法創(chuàng)建一個Statement對象。Statement對象用于執(zhí)行靜態(tài)的SQL語句,返回執(zhí)行的結(jié)果。
Statement接口中定義了下列方法用于執(zhí)行SQL語句。
ResultSet executeQuery(String sql ) throws SQLException
該方法執(zhí)行sql語句,返回一個ResultSet對象。ResultSet對象用于查看執(zhí)行的結(jié)果。
int executeUpdate(String sql )throws SQLException
該方法執(zhí)行sql指定的insert、update或者delete語句。另外,該方法也可以用于執(zhí)行SQL DDL語句,例如:create table。
boolean execute(String sql)throws SQLException
感覺模糊,我覺得還是不用比較好。
連接數(shù)據(jù)庫中,getInitParameter(“url”);獲取的是web.xml的信息。
<Servlet>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mysql</param- value >
</init-param>
<init-param>
<param-name>user</param-name>
<param-value>javahe</param- value >
</init-param>
</Servlet>
PreparedStatement
我們在程序中傳遞的SQL語句在執(zhí)行前必須被預(yù)編譯,包括語句分析、代碼優(yōu)化等,然后才能被數(shù)據(jù)庫引擎執(zhí)行。如果重復(fù)執(zhí)行只有參數(shù)不同的SQL語句,是比較低效的。如果要用不同的參數(shù)來多次執(zhí)行同一個SQL語句,可以使用PreparedStatement的對象。PreparedStatement接口從Statement接口繼承而來,它的對象表示一條預(yù)編譯過的SQL語句。我們可以通過調(diào)用Connection對象的prepareStatement()方法而得到PreparedStatement對象。PreparedStatement對象所代表的SQL語句中的參數(shù)問號來表示,第一個參數(shù)從一開始。
eg:
String sql = "delete from " + m_objTable + " where " + m_objFldTagId + "=?";
PreparedStatement objStatement = m_objConnection.prepareStatement (sql);
objStatement.setInt (1, objSms.id);
objStatement. executeUpdate ();
CallableStatement
CallableStatement對象用于執(zhí)行sql存儲過程。CallableStatement接口從PreparedStatement接口繼承而來,我們可以通過調(diào)用Connection對象的prepareCall()方法來得到CallableStatement對象。在執(zhí)行存儲過程之前,凡是存儲過程中類型為OUT的參數(shù)必須被注冊,這可以通過CallableStatement對象的registerOutParameter()方法來完成。對于類型為IN類型的參數(shù),可以利用setXXX()方法來設(shè)置參數(shù)的值。
eg:
……
CallableStatement cstmt = conn.prepareCall(“call p_changesal(?,?)”);
cstmt.registerOutParameter(2,java.sql.Types.INTEGER);
cstmt.setInt(1,212212);
cstmt.execute();
int sal = cstmt.getInt(2);
元數(shù)據(jù)
在sql中,用于描述數(shù)據(jù)庫或者它的各個組成部分之一的數(shù)據(jù)稱為 元數(shù)據(jù)。
可以調(diào)用ResultSet 對象的getMetaData()方法來得到ResultSetMetaDate對象,該對象有獲取元數(shù)據(jù)的方法(詳細方法請查api)。
事務(wù)處理
事務(wù)處理保證所有的事務(wù)都作為一個工作單元來執(zhí)行,即使出現(xiàn)了硬件或者系統(tǒng)失靈,都不能改變這種執(zhí)行方式。當在一個事務(wù)中執(zhí)行多個操作時,要么所有的操作都被提交,要么整個事務(wù)回滾到最初的狀態(tài)。
當一個連接建立時,默認情況下是設(shè)置為自動提交事務(wù),這意味著每次執(zhí)行一個sql語句時,如果執(zhí)行成功,就會向數(shù)據(jù)庫自動提交,也就不能回滾了。為了將多個sql語句作為一個事務(wù)執(zhí)行,可以調(diào)用Connection對象的setAutoCommit()方法,傳入false來取消自動提交事務(wù),然后在所有的sql語句完成后,調(diào)用Connection對象的commit()方法來提交事務(wù),或者在執(zhí)行出錯時候調(diào)用Connection對象的rollback()方法來回滾事務(wù)。
至于可滾動和可更新的結(jié)果集。我這里不做總結(jié)。日后寫翻頁程序基本就了解了。
至于會話跟蹤,不多說。改天練習一個購物車程序。練習一個在線人數(shù)統(tǒng)計(無非就是在web服務(wù)端用了靜態(tài)Hash表存儲信息,每次用戶登錄就add進去)。
轉(zhuǎn)入JSP學習中。