1、描述:JDBC作為一種中間件,以實現(xiàn)Java應(yīng)用程序與數(shù)據(jù)庫之間的接口功能。JDBC API把java命令轉(zhuǎn)換為通用SQLY語句,提交此查詢給JDBC Driver,由JDBC Driver把查詢轉(zhuǎn)換為特定數(shù)據(jù)庫所能理解的形式。JDBC Driver也檢索SQL查詢的結(jié)果,并把它轉(zhuǎn)換為可為Java應(yīng)用使用的等價的JDPC API類與對象。JDBC實際上包含了一組類與接口,這些編程接口定義在Java API的java.sql程序包和javax.sql程序包中。
2、
§Driver接口:每一個數(shù)據(jù)庫驅(qū)動程序都必須實現(xiàn)Driver接口。在編寫程序需要連接數(shù)據(jù)庫時,需要裝載由數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫驅(qū)動程序。裝載方法:Class.forname("相應(yīng)驅(qū)動程序");
§DriverManager類:JDBC的管理層,作用于用戶和驅(qū)動程序之間。DriverManager類跟蹤可用的驅(qū)動程序,并在數(shù)據(jù)庫和相應(yīng)程序之間建立連接,同時也處理諸如驅(qū)動程序登錄時間控制及登錄和跟蹤信息的顯示等事務(wù)。DriverManager類激發(fā)getConnection()方法時,DriverManager類首先從它已經(jīng)加載的驅(qū)動程序連接池中找一個可以接受該數(shù)據(jù)庫的URL的驅(qū)動程序,然后請求驅(qū)動程序使用相關(guān)的數(shù)據(jù)庫URL去連接數(shù)據(jù)庫。
§Connection接口:在加載的Driver和數(shù)據(jù)庫之間建立連接,必須創(chuàng)建一個Connection class的實例,其中包括數(shù)據(jù)庫的基本信息。連接過程包括執(zhí)行SQL語句和返回SQL語句的結(jié)果,一個應(yīng)用程序可以同時連接多個數(shù)據(jù)庫,但一般在開發(fā)過程中只有一個。DriverManager的getConnection()方法將建立在JDBC URL中定義的數(shù)據(jù)庫的Connection連接上,如:Connection conn=DriverManager.getConnection(url,user,password);
§Statement接口:Statement是提供在基層上運行SQL語句的,Connection接口提供了生成Statement的方法,如:Statement stmt=conn.createStatement();。Statement接口定義了三種執(zhí)行SQL語句的方法來處理返回不同結(jié)果的SQL命令:
executeQuery()方法執(zhí)行DML中的查詢語句,并返回ResultSet接口對象。
executeUpdate()方法一般執(zhí)行數(shù)據(jù)更新語句,返回值為所影響的行數(shù)。也可以執(zhí)行DDL語句,此時不返回任何內(nèi)容。
execute()方法通常用來執(zhí)行返回多個值的SQL語句,如果SQL返回ResultSet接口對象,則execute()方法返回boolean值true;如果SQL語句返回的是更新行數(shù),則execute()方法返回false。
§ResultSet接口:Result是包含查詢結(jié)果的結(jié)果集,該接口把查詢出來的結(jié)果作了封裝,能過ResultSet.next()方法可以把當(dāng)前指針向下移動,進行讀取,列從1開始編號。為了獲得最大的可移植性,應(yīng)該按從左到右的順序讀取每行中的結(jié)果集列,而且每列只能讀取一次。當(dāng)把起始指針指向結(jié)果集的最后一條記錄時,就可以通過此方法把查詢結(jié)果倒序輸出。
§PreparedStatement接口:用于實現(xiàn)發(fā)送帶參數(shù)的預(yù)編譯SQL語句到數(shù)據(jù)庫并返回執(zhí)行結(jié)果的功能,這在循環(huán)中重復(fù)執(zhí)行某條語句時非常有效。PreparedStatement接口對象可以為作為IN參數(shù)的變量設(shè)置占位符“?”,這些參數(shù)用setX方法進行設(shè)置。設(shè)置IN參數(shù)的setX方法必須指定與定義的輸入?yún)?shù)的SQL數(shù)據(jù)類型兼容的類型。
§CallableStatement接口用于實現(xiàn)調(diào)用數(shù)據(jù)庫存儲過程的功能。
§DatabaseMetaData接口可獲得數(shù)據(jù)庫的特定信息,其對象生成方式:
DatabaseMetaData dmd=conn.getMetaData();
§ResultSetMetaData接口可用于獲取關(guān)于ResultSet對象中列的類型和屬性信息。
§ParameterMetaData接口可用于獲取關(guān)于PreparedStatement對象中參數(shù)的類型和屬性信息。
3、JDBC直接連接Oracle數(shù)據(jù)庫
(1)加載及注冊驅(qū)動程序:
Class.forName("oracle.dbc.driver.OracleDriver").newInstance();
加載驅(qū)動程序后,一般會建立一個Driver對象,并經(jīng)由調(diào)用DriverManager.registerDriver()來自動注冊此對象。
附:導(dǎo)入驅(qū)動程序的方式,如果使用eclipse開發(fā)工具,在你的項目上單擊右鍵,選擇properties,打開屬性對話框,從“Java Build Path”選項中選擇“Libraries”選項卡,單擊“Add External JARs”找到文件classes12.jar或ojdbc14.jar,將其導(dǎo)入。如果你僅僅使用控制臺調(diào)試程序,可以把兩個文件中的一個解壓,找到oracle文件夾,復(fù)制到你含裝載驅(qū)動程序語句的類所在的目錄即可。這兩個文件均在...\jdbc\lib目錄下,個目錄是oracle安裝目錄,根據(jù)你的情況尋找,如D:\oracle\ora92\jdbc\lib。
(2)建立連接:
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="scott";
String password="tiger";
Connection conn=DriverManager.getConnection(url,user,password);
jdbc url 的標(biāo)準(zhǔn)語法如下:::
protocol:主要通訊協(xié)議
subprotocol:次要的通訊協(xié)議,其驅(qū)動的名稱
data source identifier:數(shù)據(jù)來源
如例子: "jdbc:oracle:thin"是通訊協(xié)議,@后"為有效的主機地址,然后是端口號,默認(rèn)的是:1521,然后是你的數(shù)據(jù)源 。也可以采用如下連接方式:
connection con= drivermanager.getconnection("jdbc:oracle:thin:user/password@localhost:1521:wzz");
(3)發(fā)送并執(zhí)行sql語句:
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
(4) 清理工作
例子:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Test


{
public static void main(String[] args)

{
String sql="select * from emp";
try

{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="scott";
String password="tiger";
Connection conn=DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())

{
System.out.print(rs.getString(1)+" ");
System.out.print(rs.getString(2)+" ");
System.out.print(rs.getString(3)+" ");
System.out.print(rs.getString(4)+" ");
System.out.println();
}
rs.close();
}
catch (Exception e)

{
e.printStackTrace();
}
}
}
4 、一個JDBC 連接數(shù)據(jù)庫的綜合操作:對book表進行操作
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.Date;
public class OracleCon


{
private Connection conn=null;
private Statement stmt=null;
OracleCon()

{
try

{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="mxy";
String password="606606";
conn=DriverManager.getConnection(url,user,password);
}
catch (Exception e)

{
e.printStackTrace();
}
}
//查詢數(shù)據(jù)庫中的數(shù)據(jù)
public void selectDb(String sql)throws SQLException

{
stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while (rs.next())

{
for (int i = 1; i <=rs.getMetaData().getColumnCount(); i++)

{
System.out.print(rs.getString(i) + " ");
}
System.out.println();
}
}
//增、刪、改數(shù)據(jù)庫中的數(shù)據(jù)
public boolean updateDb(String sql)throws SQLException

{
boolean isOk=false;
stmt=conn.createStatement();
isOk=stmt.executeUpdate(sql)>0;
return isOk;
}
//使用PredparedStatement接口,進行預(yù)編譯,實現(xiàn)插入數(shù)據(jù)
public boolean psDb(String NO,String TITLE,String AUTHOR,
String PUBLISH,Date PUB_DATE,Double PRICE)throws SQLException

{
//如果insert into的字段與關(guān)鍵字重名,應(yīng)改為[NO],這里假定NO是關(guān)鍵字
String strUpdate="insert into book(NO,TITLE,AUTHOR," +
"PUBLISH,PUB_DATE,PRICE) values(?,?,?,?,?,?)";
PreparedStatement stat=conn.prepareStatement(strUpdate);
stat.setString(1, NO);
stat.setString(2,TITLE);
stat.setString(3,AUTHOR);
stat.setString(4,PUBLISH);
stat.setDate(5,PUB_DATE);
stat.setDouble(6,PRICE);
return stat.executeUpdate()>0?true:false;
}
//斷開和數(shù)據(jù)庫的連接
public void dbClose()

{
try

{
if(conn!=null)

{
conn.close();
conn=null;
}
}
catch(Exception e)

{
e.printStackTrace();
}
}
}

import java.sql.Date;

public class Test


{
public static void main(String[] args)

{
Date date=Date.valueOf("2007-09-01");
OracleCon dbCon=null;
try

{
dbCon=new OracleCon();
//查詢book表的信息
dbCon.selectDb("select * from book");
//往book表插入一條數(shù)據(jù)
dbCon.updateDb("insert into book values" +
"(100009,'完全自學(xué)java手冊','馬軍等','機械工業(yè)出版社'," +
"TO_DATE('20070901','yyyy-mm-dd'),49.00)");
//修改book表中的數(shù)據(jù)
dbCon.updateDb("update book set author='馬軍、王灝等' where no=100009");
//刪除book表中的數(shù)據(jù)
dbCon.updateDb("delete from book where NO=100009");
//發(fā)送帶參數(shù)的預(yù)編譯SQL語句向book插入一條數(shù)據(jù);
dbCon.psDb("100009","完全自學(xué)java手冊", "馬軍等", "機械工業(yè)出版社",
date,49.00);
//刪除book表中的數(shù)據(jù)
dbCon.updateDb("delete from book where NO=100009");
}
catch(Exception e)

{
e.printStackTrace();
}
finally

{
dbCon.dbClose();
dbCon=null;
}
}
}

5 、預(yù)處理與存儲過程
預(yù)處理就是先構(gòu)造好SQL語句,然后再發(fā)給SQL解釋器,第一次解釋的結(jié)果將會被保留下來,以后重新執(zhí)行預(yù)處理語句時,使用該解釋,運行速度會更快。存儲過程與預(yù)處理思想很相似,它是SQL語句和可選控制流語句的預(yù)處理集合,以一個名稱作一個單元處理,而不像預(yù)處理只有單個語句,這使得客戶端發(fā)送到數(shù)據(jù)庫的請求減少了,可以有效地減少網(wǎng)絡(luò)擁塞情況的發(fā)生。
CallableStatement接口用于實現(xiàn)調(diào)用數(shù)據(jù)庫存儲過程的功能。
例子:調(diào)試中~~
6、數(shù)據(jù)庫元數(shù)據(jù)操作
元數(shù)據(jù)是一種關(guān)于數(shù)據(jù)的數(shù)據(jù),用來描述數(shù)據(jù)庫的功能與配置,通常包括數(shù)據(jù)庫元數(shù)據(jù)、結(jié)果集元數(shù)據(jù)和參數(shù)元數(shù)據(jù)。下面是一個結(jié)果集元數(shù)據(jù)的例子:
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
public class Test


{
public static void main(String args[])

{
try

{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="mxy";
String password="606606";
Connection conn=DriverManager.getConnection(url,user,password);
Statement stat=conn.createStatement();
ResultSet rs=stat.executeQuery("select * from dept");
ResultSetMetaData rsmd=rs.getMetaData();
ArrayList<String> al=new ArrayList<String>();
for (int i=1;i<=rsmd.getColumnCount();i++)

{
al.add(rsmd.getColumnName(i));
}
for(int i=0;i<al.size();i++)

{
System.out.println(al.get(i));
}
conn.close();
}
catch(Exception err)

{
err.printStackTrace();
}
}
}