????? 把以前學(xué)習(xí)的東西寫(xiě)出來(lái),以便在以后的學(xué)習(xí)和工作中可以用到!這里我主要是把自己關(guān)于數(shù)據(jù)庫(kù)學(xué)習(xí)的一些東西給寫(xiě)出來(lái)。
????? JDBC提供一套訪問(wèn)關(guān)系數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)庫(kù)。通過(guò)JDBC API,我們可以使用完全相同的Java語(yǔ)法訪問(wèn)各式各樣的SQL數(shù)據(jù)庫(kù)。正式來(lái)將JDBC不是一個(gè)首字母的縮寫(xiě)詞,因此,它不代表任何事情。”Java Database Connectivity”通常是該名稱(chēng)的完整形式。
通常查詢數(shù)據(jù)庫(kù)可以用7個(gè)標(biāo)準(zhǔn)步驟來(lái)說(shuō)明:
(1).載入JDBC驅(qū)動(dòng)程序
如果要載入驅(qū)動(dòng)程序,只需要在Class.forName方法中指定數(shù)據(jù)庫(kù)驅(qū)動(dòng)類(lèi)名。這樣做就自動(dòng)創(chuàng)建驅(qū)動(dòng)程序的實(shí)例,并注冊(cè)到JDBC驅(qū)動(dòng)程序管理器。(注:ForName方法返回給定名稱(chēng)的類(lèi)的對(duì)象,調(diào)用該對(duì)象相當(dāng)于調(diào)用Class.forName)
(2)定義連接URL(connection URL)
在JDBC中,連接URL指定服務(wù)器的主機(jī)名,端口以及希望與之建立連接的數(shù)據(jù)庫(kù)名
(3)建立連接
有了連接URL,用戶名和密碼,就可以建立到數(shù)據(jù)庫(kù)的網(wǎng)絡(luò)連接。連接建立之后,就可以執(zhí)行數(shù)據(jù)庫(kù)的查詢,直到連接為止
(4)創(chuàng)建Statement對(duì)象
創(chuàng)建Statement才能向數(shù)據(jù)庫(kù)發(fā)送查詢和命令
(5)執(zhí)行查詢或更新
有了Statement對(duì)象后,就可以用execute,executeQuery,executeUpdate或executeBatch方法發(fā)送SQL語(yǔ)句到數(shù)據(jù)庫(kù)
(6)結(jié)果處理
數(shù)據(jù)庫(kù)執(zhí)行查詢完畢之后,返回一個(gè)ResultSet。ResultSet表示一系列的行和列,可以調(diào)用next和各種getXXX方法對(duì)這些行和列進(jìn)行處理。
(7)關(guān)閉連接
這點(diǎn)比較重要,一定要記得關(guān)閉連接,釋放與數(shù)據(jù)庫(kù)的資源。這樣可以提高效率。
裝載JDBC驅(qū)動(dòng)程序
因?yàn)樵谘b載JDBC驅(qū)動(dòng)程序用的是顯示的Class.forName所以一定要寫(xiě)在try{}catch{}塊中。由于可能會(huì)發(fā)生ClassNotFoundException所以應(yīng)當(dāng)捕獲這個(gè)異常. Example:
Try
{
Class.forName(“connect.microsoft.MicrosoftDriver”);
Class.forName(“oracle.jdbc.driver.OracleDriver”);
Class.forName(“com.sybase.jdbc.SybDriver”);
}
Catch(ClassNotFoundException e)
{
?out.println(e.getMessage());
}
我們?cè)诓渴鸬臅r(shí)候應(yīng)當(dāng)注意是把JDBC的驅(qū)動(dòng)程序JAR文件部署到install_dir/common/lib也可以部署到WEB-INF/lib目錄中。
建立連接
在建立實(shí)際連接的時(shí)候,需要將URL,數(shù)據(jù)庫(kù)名字和用戶名都傳給DriverManager類(lèi)的getConnection方法,由于getConnection有可能會(huì)產(chǎn)生異常因此我們應(yīng)該把這些代碼寫(xiě)在try{}catch{}中. Eg:
String URL=”jdbc:oracle:thin:@”+host+”:”+port+”:”+dbName;
String UID=”Database user name”;
String PWD=”Database password”;
Try
{
Conection con=DriverManager.getConnection(URL,UID,PWD);
}
Catch(SQLException e)
{
? e.getMessage();
}
Conection類(lèi)還包括其他的一些用法!如下:
prepareStatement
創(chuàng)建預(yù)編譯查詢,提交給數(shù)據(jù)庫(kù)
prepareCall
訪問(wèn)數(shù)據(jù)庫(kù)中的存儲(chǔ)過(guò)程。
Rollbach/commit
控制事務(wù)管理
Close
關(guān)閉連接
isClosed
確定連接是否超時(shí)或被顯示關(guān)閉
建立連接過(guò)程,一個(gè)可選部分是使用getDataMeta方法查找數(shù)據(jù)庫(kù)的相關(guān)信息,這個(gè)方法返回DatabaseMetaData對(duì)象,該對(duì)象擁有相應(yīng)的方法,可以得出數(shù)據(jù)庫(kù)自身的名稱(chēng)和版本(getDatabaseProductName,getDatabaseProductVersion),或者 JDBC驅(qū)動(dòng)程序的名稱(chēng)和版本(getDriverName,getDrvierVersion).例如:
DatabaseMetaData dbMetaData=connection.getDataMeta();
String productName=
dbMetaDate.getDatabaseProductName();
System.out.println(“Database:”+productName);
String produtcVersion=
?? dbMetaDate.getDatabseProductVersion();
System.out.println(“Version:”+productVersion);
創(chuàng)建Statement對(duì)象
Statement對(duì)象用來(lái)向數(shù)據(jù)庫(kù)發(fā)送查詢和命令。它由Conection的createStatement()方法創(chuàng)建:
Statement stmt=connection.createStatement();
執(zhí)行查詢或更新
有了Statement對(duì)象后,就可以用它的executeQuery方法發(fā)送SQL查詢,executeQuery返回ResultSet類(lèi)型對(duì)象。Eg:
String sql=”select * from emp”;
ResultSet rs=stmt.execute?Query(sql);
Statement的其他的用法:
executeQuery
執(zhí)行SQL查詢并在ResultSet中返回?cái)?shù)據(jù).ResultSet可能為空,但不會(huì)為NULL。
executeUpdate
用于UPDATE,INSERT或DELETE命令。返回受影響的行數(shù),可以為0,它還提供對(duì)DDL(Data Definition Language)命令的支持,例如CREATE TABLE,DROP TABLE和ALTER TABLE。
executeBatch
將一組命令作為一個(gè)單元執(zhí)行,返回一個(gè)數(shù)組,其中存儲(chǔ)每個(gè)計(jì)數(shù)的更新計(jì)數(shù)。addBatch可以向批量執(zhí)行的命令中添加命令。
setQueryTimeout
指定驅(qū)動(dòng)程序在拋出SQLException異常之前,等待處理結(jié)果的時(shí)間。
getMaxRows/setMaxRows
確定ResultSet可容納的最大行數(shù)。超過(guò)的行將會(huì)在不給出任何警告的情況下丟棄。默認(rèn)值為0,表示沒(méi)有限制。
結(jié)果處理
結(jié)果處理最簡(jiǎn)單的方式就是用ResultSet的Next方法在表中移動(dòng),每次一行。(注:ResultSet中行的第一列索引為1,而非0).建議在訪問(wèn) ResultSet的列時(shí)不要使用索引,而使用列名。使用這種方式在表的結(jié)構(gòu)發(fā)生改變時(shí),與ResultSet交互的代碼不容易出錯(cuò)誤。
ResultSet的一些方法集:
Next/previous
將ResultSet中的游標(biāo)分別移動(dòng)到下一行。
Relative/absolute
Relative方法將游標(biāo)相應(yīng)的地移動(dòng)特定數(shù)目行,或正或負(fù)(向前或向后)。Absolute方法將游標(biāo)移動(dòng)到指定的行號(hào)。如果絕對(duì)值是負(fù)數(shù),那么游標(biāo)將相對(duì)于ResultSet的結(jié)尾進(jìn)行定位(JDBC2.0)。
getXxx
返回Xxx Java類(lèi)型(參見(jiàn)java.sql.Types)的值,這個(gè)值來(lái)自于列名或索引指定的列。如果列的值為SQL的NULL值,那么則返回0或NULL。
wasNull
檢查上面的getXxx讀到的是否為SQL的NULL值。如果列的類(lèi)型為基本類(lèi)型(int,float等),且數(shù)據(jù)庫(kù)中的值為0,那么這項(xiàng)檢查就很重要。由于數(shù)據(jù)庫(kù)的NULL返回0,所以0和數(shù)據(jù)庫(kù)的NULL不能區(qū)分開(kāi)來(lái)。如果列的類(lèi)型為對(duì)象(String,Date等),可以簡(jiǎn)單的將返回值與NULL比較。
findColumn
返回ResultSet中與指定列名對(duì)應(yīng)的索引。
getRow
返回當(dāng)前的行號(hào),第一行從1開(kāi)始。
getMetaData
返回描述ResultSet的ResultSetMetaData對(duì)象。ResultSetMetaData給出列的數(shù)目和名稱(chēng)。
getMetaData方法尤為有用。僅僅有ResultSet的情況下我們必須知道列的名稱(chēng),數(shù)目和類(lèi)型才能正確的對(duì)表進(jìn)行處理。ResultSetMetaData的方法集:
getColumnCount
返回ResultSet中列的數(shù)目。
getColumnName
返回列在數(shù)據(jù)庫(kù)中的名稱(chēng).
getColumnType
返回列的SQL類(lèi)型,對(duì)應(yīng)于java.sql.Types中的項(xiàng)。
isReadOnly
表示數(shù)據(jù)是否為只讀。
isSerachable
表明給列是否可以用在WHERE字句中。
isNullable
表明該列是否可以存儲(chǔ)NULL。
(注J: ResultSet和ResultSetMetaData沒(méi)有直接提供方法返回查詢所返回的行數(shù),然而,在JDBC2.0中,可以用last將游標(biāo)定位于ResultSet最后一行,然后調(diào)用getRow獲取當(dāng)前的行號(hào)。)
關(guān)閉連接
顯示的關(guān)閉連接:
connection.close();
可以參考以下以下的例子:
import java.sql.*; import java.io.*; /** * <p>Title: JDBC連接數(shù)據(jù)庫(kù)</p> * <p>Description: 本實(shí)例演示如何使用JDBC連接Oracle數(shù)據(jù)庫(kù),并演示添加數(shù)據(jù)和查詢數(shù)據(jù)。</p> */publicclass JDBCConn{private String url="";//數(shù)據(jù)庫(kù)連接字符串private String username="";//數(shù)據(jù)庫(kù)用戶名private String password="";//數(shù)據(jù)庫(kù)密碼 ? /** *<br>方法說(shuō)明:獲得數(shù)據(jù)連接 *<br>輸入?yún)?shù): *<br>返回類(lèi)型:Connection 連接對(duì)象 */public Connection conn(){try{ ??//第一步:加載JDBC驅(qū)動(dòng) Class.forName("oracle.jdbc.driver.OracleDriver"); //第二步:創(chuàng)建數(shù)據(jù)庫(kù)連接 Connection con =DriverManager.getConnection(url, username, password); return con; }catch(ClassNotFoundException cnf){ ??System.out.println("driver not find:"+cnf); ??returnnull; }catch(SQLException sqle){ ??System.out.println("can't connection db:"+sqle); ??returnnull; } ??catch (Exception e) { System.out.println("Failed to load JDBC/ODBC driver."); returnnull; }}/** *<br>方法說(shuō)明:執(zhí)行查詢SQL語(yǔ)句 *<br>輸入?yún)?shù):Connection con 數(shù)據(jù)庫(kù)連接 *<br>輸入?yún)?shù):String sql 要執(zhí)行的SQL語(yǔ)句 *<br>返回類(lèi)型:void */publicvoid query(Connection con, String sql){try{if(con==null){thrownew Exception("database connection can't use!"); }if(sql==null) thrownew Exception("check your parameter: 'sql'! don't input null!"); //第三步:獲取Staetment對(duì)象 Statement stmt = con.createStatement(); //第四步:執(zhí)行數(shù)據(jù)庫(kù)操作(查詢操作) ResultSet rs = stmt.executeQuery(sql); //第五步:處理結(jié)果集 ?? ResultSetMetaData rmeta = rs.getMetaData(); ?? //獲得數(shù)據(jù)字段個(gè)數(shù)int numColumns = rmeta.getColumnCount(); while(rs.next()) ?? { ?? for(int i = 0;i< numColumns;i++) ?? { ????String sTemp = rs.getString(i+1); ????System.out.print(sTemp+" "); ?? } ?? System.out.println(""); ?? }}catch(Exception e){ System.out.println("query error:"+e); }}/** *<br>方法說(shuō)明:執(zhí)行插入、更新、刪除等沒(méi)有返回結(jié)果集的SQL語(yǔ)句 *<br>輸入?yún)?shù):Connection con 數(shù)據(jù)庫(kù)連接 *<br>輸入?yún)?shù):String sql 要執(zhí)行的SQL語(yǔ)句 *<br>返回類(lèi)型:void */publicvoid execute(Connection con, String sql){try{if(con==null) return; //第三步:獲取Statement對(duì)象 ?? Statement stmt = con.createStatement(); //第四步:執(zhí)行數(shù)據(jù)庫(kù)操作(更新操作) ?? stmt.executeUpdate(sql); ?? System.out.println("update executed successly"); }catch(Exception e){ System.out.println("execute error: sql = "+sql); System.out.println(e); }//end try catch}//end execute/** *<br>方法說(shuō)明:實(shí)例演示 *<br>輸入?yún)?shù):無(wú) *<br>返回類(lèi)型:void */publicvoid demo(){ String sSQL=""; BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in)); try{ System.out.println("please input update SQL string"); sSQL=stdin.readLine();//獲取命令行輸入(更新字符串) Connection conn = conn();//執(zhí)行自定義連接方法(獲取數(shù)據(jù)庫(kù)連接對(duì)象) execute(conn,sSQL);//執(zhí)行自定義更新方法 String sql = "select * from TBL_USER"; query(conn,sql);//執(zhí)行自定義查詢方法(查詢并處理結(jié)果集)//第六步:關(guān)閉數(shù)據(jù)庫(kù)連接 conn.close(); }catch(SQLException se){ System.out.println(se); }catch(Exception e){ System.out.println(e); } ? }/** *<br>方法說(shuō)明:主方法 *<br>輸入?yún)?shù):String[] args 命令行參數(shù)(包括:數(shù)據(jù)庫(kù)連接URL, *<br>用戶名,密碼) *<br>返回類(lèi)型:void */publicstaticvoid main(String[] arg){if(arg.length!=3){ System.out.println("use: java JDBCConn url username password"); return; } JDBCConn oc = new JDBCConn(); oc.url = arg[0]; oc.username=arg[1]; oc.password=arg[2]; oc.demo(); }}