1.通過接口可以實現(xiàn)不相關(guān)的類的相同行為.
2.通過接口可以指明多個類需要實現(xiàn)的方法.
3.通過接口可以了解對象的交互方法而不需要了解對象所對應(yīng)的類藍(lán)本.
一個普通數(shù)據(jù)庫的連結(jié)過程為:
1.加載驅(qū)動程序.
2.通過DriverManager到得一個與數(shù)據(jù)庫連結(jié)的句柄.
3.通過連結(jié)句柄綁定要執(zhí)行的語句.
4.接收執(zhí)行結(jié)果.
5.可選的對結(jié)果的處理.
6.必要的關(guān)閉和數(shù)據(jù)庫的連結(jié).
Class.forName方法是先在內(nèi)存中溶解簽名為"org.gjt.mm.mysql.Driver"的Driver類,Driver類就會把相應(yīng)的實現(xiàn)類對應(yīng)到JDBC API的接口中.注冊驅(qū)動程序有多方法,Class.forName();是一種顯式地加載.當(dāng)一個驅(qū)動程序類被Classloader裝載后,在溶解的過程中,DriverManager會注冊這個驅(qū)動類的實例.這個調(diào)用是自動發(fā)生的,也就是說DriverManager.registerDriver()方法被自動調(diào)用了
在成功注冊驅(qū)動程序后,我們就可以用DriverManager的靜態(tài)方法getConnection來得到和數(shù)據(jù)庫連結(jié)的引用:
Connection conn = DriverManager.getConnection(url);
如果連結(jié)是成功的,則返回Connection對象conn,如果為null或拋出異常,則說明沒有
和數(shù)據(jù)庫建立連結(jié).
如果我們要對數(shù)據(jù)庫中的表進(jìn)行操作,要先緣故綁定一個語句:
Statement stmt = conn.createStatement();
然后利用這個語句來執(zhí)行操作.根本操作目的,可以有兩種結(jié)果返回,如果執(zhí)行的查詢
操作,返回為結(jié)果集ResultSet,如果執(zhí)行更新操作,則返回操作的記錄數(shù)int.
注意,SQL操作嚴(yán)格區(qū)分只有兩個,一種就是讀操作(查詢操作),另一種就是寫操作(更
新操作),所以,create,insert,update,drop,delete等對數(shù)據(jù)有改寫行為的操作都是更新操作.
關(guān)于Statement對象:
前面說過,Statement對象是用來綁定要執(zhí)行的操作的,在它上面有三種執(zhí)行方法:即用來執(zhí)行查詢操作的executeQuery(),用來執(zhí)行更新操作的executeUpdate()和用來執(zhí)行動態(tài)的未知的操作的execute().一個Statement對象同時只能有一個結(jié)果集在活動.這是寬容性的,就是說即使沒有調(diào)用ResultSet的close()方法,只要打開第二個結(jié)果集就隱含著對上一個結(jié)果集的關(guān)閉.所以如果你想同時對多個結(jié)果集操作,就要創(chuàng)建多個Statement對象,如果不需要同時操作,那么可以在一個Statement對象上須序操作多個結(jié)果集
Statement的兩個子類:
PreparedStatement:對于同一條語句的多次執(zhí)行,Statement每次都要把SQL語句發(fā)送給數(shù)據(jù)
庫,這樣做效率明顯不高,而如果數(shù)據(jù)庫支持預(yù)編譯,PreparedStatement可以先把要執(zhí)行的語句一次發(fā)
給它,然后每次執(zhí)行而不必發(fā)送相同的語句,效率當(dāng)然提高
PreparedStatement ps = conn.prepareStatement("select * from 表 where 字段=?");
ps.setString(1,參數(shù));
ResultSet rs = ps.executeQuery();
CallableStatement:是PreparedStatement的子類,它只是用來執(zhí)行存儲過程的.
CallableStatement sc = conn.prepareCall("{call query()}");
ResultSet rs = sc.executeQuery();
ResultSet對象實際維護(hù)的是一個二維指針,第一維是指向當(dāng)前行,最初它指向的是結(jié)果集的第一行之前,所以如果要訪問第一行,就要先next(),以后每一行都要先next()才能訪問,然后第二維的指針指向列,只要當(dāng)你去rs.getXXX(列)時,才通過Connection再去數(shù)據(jù)庫把真實的數(shù)據(jù)取出來,否則沒有什么機(jī)器能真的把要取的數(shù)據(jù)都放在內(nèi)存中.
如果有記錄又不知道是多少行,這時如果要對有記錄和沒有記錄進(jìn)行不同的處理,應(yīng)該用以下流程進(jìn)行判斷:
if(rs.next()){
//因為已經(jīng)先next()了,所經(jīng)對記錄應(yīng)該用do{}while();來處理
do{
int i = rs.getInt(1);
String a = rs.getString("a2");
}while(rs.next());
}
esle{
System.out.println("沒有取得符合條件的記錄!");
}
獲取結(jié)果集的信息:
大多數(shù)情況下編程人員對數(shù)據(jù)庫結(jié)構(gòu)是了解的,可以知道結(jié)果集中各列的情況,但有時并
不知道結(jié)果集中有哪些列,是什么類型.這時可以通過getMetaData()來獲取結(jié)果集的情況:
ResulSetMetaData rsmd = rs.getMetaData();
rsmd.getColumnCount()返回列的個數(shù).
getColumnLabel(int)返回該int所對應(yīng)的列的顯示標(biāo)題
getColumnName(int)返回該int所對應(yīng)的列的在數(shù)據(jù)庫中的名稱.
getColumnType(int)返回該int所對應(yīng)的列的在數(shù)據(jù)庫中的數(shù)據(jù)類型.
getColumnTypeName(int)返回該int所對應(yīng)的列的數(shù)據(jù)類型在數(shù)據(jù)源中的名稱.
isReadOnly(int)返回該int所對應(yīng)的列是否只讀.
isNullable(int)返回該int所對應(yīng)的列是否可以為空
posted @ 2005-10-21 16:57 大雄 閱讀(184) | 評論 (0) | 編輯 收藏