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

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接口,進(jìn)行預(yù)編譯,實(shí)現(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手冊(cè)','馬軍等','機(jī)械工業(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手冊(cè)", "馬軍等", "機(jī)械工業(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ù)處理與存儲(chǔ)過程
預(yù)處理就是先構(gòu)造好SQL語句,然后再發(fā)給SQL解釋器,第一次解釋的結(jié)果將會(huì)被保留下來,以后重新執(zhí)行預(yù)處理語句時(shí),使用該解釋,運(yùn)行速度會(huì)更快。存儲(chǔ)過程與預(yù)處理思想很相似,它是SQL語句和可選控制流語句的預(yù)處理集合,以一個(gè)名稱作一個(gè)單元處理,而不像預(yù)處理只有單個(gè)語句,這使得客戶端發(fā)送到數(shù)據(jù)庫的請(qǐng)求減少了,可以有效地減少網(wǎng)絡(luò)擁塞情況的發(fā)生。
CallableStatement接口用于實(shí)現(xiàn)調(diào)用數(shù)據(jù)庫存儲(chǔ)過程的功能。
例子:調(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ù)。下面是一個(gè)結(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();
}
}
}
2、
§Driver接口:每一個(gè)數(shù)據(jù)庫驅(qū)動(dòng)程序都必須實(shí)現(xiàn)Driver接口。在編寫程序需要連接數(shù)據(jù)庫時(shí),需要裝載由數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫驅(qū)動(dòng)程序。裝載方法:Class.forname("相應(yīng)驅(qū)動(dòng)程序");
§DriverManager類:JDBC的管理層,作用于用戶和驅(qū)動(dòng)程序之間。DriverManager類跟蹤可用的驅(qū)動(dòng)程序,并在數(shù)據(jù)庫和相應(yīng)程序之間建立連接,同時(shí)也處理諸如驅(qū)動(dòng)程序登錄時(shí)間控制及登錄和跟蹤信息的顯示等事務(wù)。DriverManager類激發(fā)getConnection()方法時(shí),DriverManager類首先從它已經(jīng)加載的驅(qū)動(dòng)程序連接池中找一個(gè)可以接受該數(shù)據(jù)庫的URL的驅(qū)動(dòng)程序,然后請(qǐng)求驅(qū)動(dòng)程序使用相關(guān)的數(shù)據(jù)庫URL去連接數(shù)據(jù)庫。
§Connection接口:在加載的Driver和數(shù)據(jù)庫之間建立連接,必須創(chuàng)建一個(gè)Connection class的實(shí)例,其中包括數(shù)據(jù)庫的基本信息。連接過程包括執(zhí)行SQL語句和返回SQL語句的結(jié)果,一個(gè)應(yīng)用程序可以同時(shí)連接多個(gè)數(shù)據(jù)庫,但一般在開發(fā)過程中只有一個(gè)。DriverManager的getConnection()方法將建立在JDBC URL中定義的數(shù)據(jù)庫的Connection連接上,如:Connection conn=DriverManager.getConnection(url,user,password);
§Statement接口:Statement是提供在基層上運(yùn)行SQL語句的,Connection接口提供了生成Statement的方法,如:Statement stmt=conn.createStatement();。Statement接口定義了三種執(zhí)行SQL語句的方法來處理返回不同結(jié)果的SQL命令:
executeQuery()方法執(zhí)行DML中的查詢語句,并返回ResultSet接口對(duì)象。
executeUpdate()方法一般執(zhí)行數(shù)據(jù)更新語句,返回值為所影響的行數(shù)。也可以執(zhí)行DDL語句,此時(shí)不返回任何內(nèi)容。
execute()方法通常用來執(zhí)行返回多個(gè)值的SQL語句,如果SQL返回ResultSet接口對(duì)象,則execute()方法返回boolean值true;如果SQL語句返回的是更新行數(shù),則execute()方法返回false。
§ResultSet接口:Result是包含查詢結(jié)果的結(jié)果集,該接口把查詢出來的結(jié)果作了封裝,能過ResultSet.next()方法可以把當(dāng)前指針向下移動(dòng),進(jìn)行讀取,列從1開始編號(hào)。為了獲得最大的可移植性,應(yīng)該按從左到右的順序讀取每行中的結(jié)果集列,而且每列只能讀取一次。當(dāng)把起始指針指向結(jié)果集的最后一條記錄時(shí),就可以通過此方法把查詢結(jié)果倒序輸出。
§PreparedStatement接口:用于實(shí)現(xiàn)發(fā)送帶參數(shù)的預(yù)編譯SQL語句到數(shù)據(jù)庫并返回執(zhí)行結(jié)果的功能,這在循環(huán)中重復(fù)執(zhí)行某條語句時(shí)非常有效。PreparedStatement接口對(duì)象可以為作為IN參數(shù)的變量設(shè)置占位符“?”,這些參數(shù)用setX方法進(jìn)行設(shè)置。設(shè)置IN參數(shù)的setX方法必須指定與定義的輸入?yún)?shù)的SQL數(shù)據(jù)類型兼容的類型。
§CallableStatement接口用于實(shí)現(xiàn)調(diào)用數(shù)據(jù)庫存儲(chǔ)過程的功能。
§DatabaseMetaData接口可獲得數(shù)據(jù)庫的特定信息,其對(duì)象生成方式:
DatabaseMetaData dmd=conn.getMetaData();
§ResultSetMetaData接口可用于獲取關(guān)于ResultSet對(duì)象中列的類型和屬性信息。
§ParameterMetaData接口可用于獲取關(guān)于PreparedStatement對(duì)象中參數(shù)的類型和屬性信息。
3、JDBC直接連接Oracle數(shù)據(jù)庫
(1)加載及注冊(cè)驅(qū)動(dòng)程序:

附:導(dǎo)入驅(qū)動(dòng)程序的方式,如果使用eclipse開發(fā)工具,在你的項(xiàng)目上單擊右鍵,選擇properties,打開屬性對(duì)話框,從“Java Build Path”選項(xiàng)中選擇“Libraries”選項(xiàng)卡,單擊“Add External JARs”找到文件classes12.jar或ojdbc14.jar,將其導(dǎo)入。如果你僅僅使用控制臺(tái)調(diào)試程序,可以把兩個(gè)文件中的一個(gè)解壓,找到oracle文件夾,復(fù)制到你含裝載驅(qū)動(dòng)程序語句的類所在的目錄即可。這兩個(gè)文件均在...\jdbc\lib目錄下,個(gè)目錄是oracle安裝目錄,根據(jù)你的情況尋找,如D:\oracle\ora92\jdbc\lib。
(2)建立連接:




protocol:主要通訊協(xié)議
subprotocol:次要的通訊協(xié)議,其驅(qū)動(dòng)的名稱
data source identifier:數(shù)據(jù)來源
如例子: "jdbc:oracle:thin"是通訊協(xié)議,@后"為有效的主機(jī)地址,然后是端口號(hào),默認(rèn)的是:1521,然后是你的數(shù)據(jù)源 。也可以采用如下連接方式:



例子:






























































































































































預(yù)處理就是先構(gòu)造好SQL語句,然后再發(fā)給SQL解釋器,第一次解釋的結(jié)果將會(huì)被保留下來,以后重新執(zhí)行預(yù)處理語句時(shí),使用該解釋,運(yùn)行速度會(huì)更快。存儲(chǔ)過程與預(yù)處理思想很相似,它是SQL語句和可選控制流語句的預(yù)處理集合,以一個(gè)名稱作一個(gè)單元處理,而不像預(yù)處理只有單個(gè)語句,這使得客戶端發(fā)送到數(shù)據(jù)庫的請(qǐng)求減少了,可以有效地減少網(wǎng)絡(luò)擁塞情況的發(fā)生。
CallableStatement接口用于實(shí)現(xiàn)調(diào)用數(shù)據(jù)庫存儲(chǔ)過程的功能。
例子:調(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ù)。下面是一個(gè)結(jié)果集元數(shù)據(jù)的例子:




































