?? day01.txt
字號:
JDBC_day01 langna 2007-9-6 星期四
王海格老師 haige_wang@tarena.com.cn
課程大概:
基礎(chǔ)語法
2.0擴展
程序設(shè)計
一、第一章 基本概念
1、JDBC是什么?能做什么?
JDBC是java訪問數(shù)據(jù)庫的基本接口(底層接口);包括 j2se, j2ee
高級的框架或手段 Hibernate,EJB 也是基于jdbc的。
JDBC的功能:
1)可以連接數(shù)據(jù)庫;(服務器) 提供java到數(shù)據(jù)庫的連接;
2)通過SQL命令來操作數(shù)據(jù)庫;JDBC 借助于標準查詢語言對數(shù)據(jù)庫進行增刪改查;
3)JDBC提供對結(jié)果集的封裝和處理;
4)支持事務的操作;
2、JDBC產(chǎn)生的背景和基本結(jié)構(gòu)(工作原理):
1)背景:
JDBC應該算是企業(yè)的特性,但是放在j2se文檔里;
JDBC應該算是java最早的企業(yè)級的應用;但是當時還沒有j2ee,就放在j2se里了;
因為作為通用的語言必須具有訪問數(shù)據(jù)庫的能力,所以在java推出時就有了JDBC;
2)原理:
JDBC仿照ODBC寫的;ODBC用類C(C,C++)語言寫的;
兩層結(jié)構(gòu):
一層是面向java程序員;
一層是面向驅(qū)動程序/driver開發(fā)人員:
3)什么是驅(qū)動程序?
驅(qū)動程序就是將 接口的一致性,實現(xiàn)的多樣性 結(jié)合起來;
例 :
顯卡的驅(qū)動,主板上有一個顯卡的插槽(公共接口,針腳排列);
操作系統(tǒng)來調(diào)用顯卡時,只需通過驅(qū)動程序來操作那塊顯卡;
各個廠商的顯卡是不同的,但是驅(qū)動程序都實現(xiàn)了這個接口;
JDBC是插槽,數(shù)據(jù)庫就是顯卡;
驅(qū)動程序代表實現(xiàn);特點是多樣性;不同的驅(qū)動就是將JDBC和不同的數(shù)據(jù)庫結(jié)合起來;
JDBC是一套規(guī)范/協(xié)議;物理上是JAVA接口集;突出的特點是一致性;
4) 協(xié)議:
體現(xiàn)的是sun公司(java程序員)和數(shù)據(jù)庫廠商(驅(qū)動的開發(fā)者)的協(xié)議;
是調(diào)用者和實現(xiàn)者的協(xié)議;前者是按照規(guī)范去調(diào)用;后者是按照規(guī)范實現(xiàn);
sun公司定義規(guī)范;java程序員寫代碼調(diào)用,數(shù)據(jù)庫廠商實現(xiàn)規(guī)范;
為什么JDBC具有一致性?
接口就是實現(xiàn)者和調(diào)用者之間的協(xié)議,保證一致性;接口不能修改原來的定義,只能增加;
5) 總結(jié):
JDBC是一個由java接口組成的接口集,代表了實現(xiàn)者(數(shù)據(jù)庫廠商)和調(diào)用者(java程序員)之間的協(xié)議;
只能讓操作看起來一致,并沒有實現(xiàn);真正去工作的是驅(qū)動;
接口例子:
螺釘、螺母,有工業(yè)規(guī)范規(guī)定的,也是接口;
遙控器,使用者和實現(xiàn)者的分離;實現(xiàn)者工作比使用者相對復雜;
程序、驅(qū)動、jdbc接口一起才能有效的工作;
人、電視、遙控器 一起才是看電視;
3、JDBC Driver的四種類型:(不管是哪個廠商的,按照歷史發(fā)展順序)
1) JDBC-ODBC橋 驅(qū)動:
由ODBC驅(qū)動提供JDBC訪問;
每年都有很多計算機語言誕生,但是不久就滅亡了;
剛開始,數(shù)據(jù)庫廠商也不是很看好java這門語言;不是很想寫驅(qū)動;
但是j2se中有jdbc的規(guī)范;必須得實現(xiàn),sun公司很巧妙的利用了ODBC(c 訪問數(shù)據(jù)庫的驅(qū)動),
當時ODBC所有的數(shù)據(jù)庫都能訪問;將JDBC翻譯成了ODBC;
應用程序--> JDBC--> 橋--> ODBC-->數(shù)據(jù)庫
安全性不是很好(java的安全性建立在jvm上), 效率也不高(翻譯);
2) 本地API 部分java驅(qū)動:
部分Java driver把JDBC調(diào)用轉(zhuǎn)化成本地的客戶端API
如果代碼調(diào)用了windows的系統(tǒng)調(diào)用,就是windows本地調(diào)用;
應用程序--> JDBC -->JVM/OS --> 數(shù)據(jù)庫
速度還可以,但是不是純java的;
3) JDBC-net :純java驅(qū)動;
純的Java driver,將JDBC調(diào)用轉(zhuǎn)入DBMS,與網(wǎng)絡(luò)協(xié)議無關(guān)。然后通過服務器將調(diào)用轉(zhuǎn)為DBMS協(xié)議。
沒有直接訪問數(shù)據(jù)庫,訪問了中間服務器;
應用程序--> JDBC--> 驅(qū)動--> 訪問中間服務器--> 數(shù)據(jù)庫
本地協(xié)議,數(shù)據(jù)庫服務器的應用層協(xié)議;
中間協(xié)議,中間服務器的協(xié)議;
安全性還可以,但是協(xié)議,網(wǎng)絡(luò)造成了效率的降低;
4) 純 java 本地協(xié)議:
純的java driver,將JDBC調(diào)用直接轉(zhuǎn)為DBMS使用的網(wǎng)絡(luò)協(xié)議
應用程序--> JDBC--> 驅(qū)動-(本地協(xié)議)-->數(shù)據(jù)庫(內(nèi)置對jvm的支持)
安全性沒有問題,效率也高了;數(shù)據(jù)庫廠商作出了努力;
現(xiàn)在我們用的就是這種驅(qū)動;
4、開發(fā)者接口的內(nèi)容:
驅(qū)動程序, 有很多類,但有一個主類,實現(xiàn)java.sql.Driver接口,手動加載這個類;
兩個包:java.sql.*;//主要接口包;
javax.sql.*;//擴展功能包;j2ee版
JDBC 貫穿課程,以后Hibernate, EJB,Spring 都要用;
Driver :接口,代表驅(qū)動程序;
DriverManager:工具類,輔助管理驅(qū)動程序的;并不是規(guī)范里的內(nèi)容;規(guī)范里只有接口;
Connection:接口,連接數(shù)據(jù)庫,代表和數(shù)據(jù)庫的物理連接;某種意義上代表數(shù)據(jù)庫本身;事務也由它代表;
Statement:接口,操作數(shù)據(jù)庫的對象,發(fā)送 sql語句
PreparedStatement:Statement子接口,預編譯Statement,開發(fā)中主要用這個;
CallableStatement:Statement子接口,調(diào)用數(shù)據(jù)庫的存儲過程,用的比較少;數(shù)據(jù)庫之間的存儲過程是不通用的;
ResultSet:接口,結(jié)果集,代表對數(shù)據(jù)庫的查詢結(jié)果,并且提供處理結(jié)果的方法;
DataBaseMetadata:接口,代表原數(shù)據(jù),數(shù)據(jù)庫原數(shù)據(jù)
ResultMetadata:接口,代表原數(shù)據(jù),結(jié)果集原數(shù)據(jù)
Types:類,輔助的類,代表JDBC類型,定義了很多整數(shù)類型的常量;是標準SQL類型的子集;
數(shù)據(jù)庫:例 :vachar=12,number=2
5、訪問數(shù)據(jù)庫:
0) 加載驅(qū)動; 反射的方法;
1) 連接數(shù)據(jù)庫;
2) 操作數(shù)據(jù)庫;
3) 返回結(jié)果集:ResultSet
4) 關(guān)閉數(shù)據(jù)庫連接;
Oracle的Driver的全名oracle.jdbc.driver.OracleDriver
mysql的Driver的全名com.mysql.jdbc.Driver
SQLServer的Driver的全名com.microsoft.jdbc.sqlserver.SQLServerDriver
Class.forName("oracle.jdbc.driver.OracleDriver");//Oracle的驅(qū)動,實現(xiàn)了Driver接口;
DriverManager.getConnection(url:String,username:String,passwd:String);
沒有用驅(qū)動直接去要連接,而是用了一個驅(qū)動管理員,是為了更靈活,以后會細講,這里先知道;
url:協(xié)議,ip地址,端口號; jdbc:oracle:thin:@192.168.0.201:tarena
Statement 從Connection 來的; stmt = con.createStatement();
例子:
public static void main(String[] args)
{
Connection con = null;// 接口不能直接new
Statement st = null;
ResultSet rs = null;
try
{
//1、 加載驅(qū)動;
Class.forName("oracle.jdbc.driver.OracleDriver");
//2、獲取連接;實現(xiàn)類在驅(qū)動程序里;
con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.201:1521:tarena",
"xjh0704", "xjh0704");
//3、操作數(shù)據(jù)庫;插入一條記錄
stmt = con.createStatement();
stmt.executeUpdate("insert into ln_student values(4,'langna','shanghai')");
}catch(Exception e){
e.printStackTrace();
}finally{
//4、關(guān)閉連接;判斷是否為空,然后關(guān)閉;
try{
if(con!=null) con.close();
}catch(SQLException ex){
ex.printStackTrace();
}
}
}
DriverManager 可以得到多個連接對象 Connection ,一個連接對象可以獲取Statement對象;
DriverManager --Driver--Connection--Statement --ResultSet
類比: 經(jīng)理 --工程師-- 連線-- -- 電話---- 電話記錄
二、第二章 基本語法
1、開發(fā)步驟:6步
1)加載驅(qū)動:
三種方法:
A.Class.forName(DriverName);
a.加載到內(nèi)存;
b.注冊到DriverManager;
public class OracleDriver implements Driver
{
//利用靜態(tài)代碼塊注冊驅(qū)動
static
{
DriverManager.riegisterDriver(new OracleDriver());
}
}
B.直接創(chuàng)建Driver實例
a. Driver driver=new oracle.jdbc.driver.OracleDriver();
b. DriverManager.riegisterDriver(driver);
這種寫的比較死,不提倡使用;
C.利用虛擬機的參數(shù)來設(shè)置環(huán)境變量;通過環(huán)境變量讓虛擬機去加載;
a. 運行時: -D 設(shè)置虛擬機參數(shù),要求虛擬機為你加載的驅(qū)動程序的名字;
jdbc.drivers 環(huán)境變量,是虛擬機的環(huán)境變量,不是操作系統(tǒng)的;
名字是事先定義好的,不能改變;多個參數(shù)用空格隔開;
java -Djdbc.drivers=oracle.jdbc.driver.OracleDriver FristJdbc(要運行的程序名) (程序參數(shù)/main方法參數(shù))
如果將Class.forName();去掉的話,會報異常:no suitable driver ;
2)建立連接
3)獲取Statement
4)操作數(shù)據(jù)庫
5)處理結(jié)果集,(可選)
6)釋放數(shù)據(jù)庫資源
實驗一:配置環(huán)境
簡單的數(shù)據(jù)庫連接
2、協(xié)議
總協(xié)議 子協(xié)議 ip地址 端口號 資源名稱
http://202.64.4.33:80/index.html
jdbc.oracle:thin:@192.168.0.20:1521:tarena
jdbc:mysql://127.0.0.1:3306/test
3、游標 :
String sql = "select * from ln_student";
rs = st.executeQuery(sql);
System.out.println("resultset "+rs);
while(rs.next())
{
System.out.print("id=" + rs.getInt(1));//也可以是字段名"id"
System.out.print(",name=" + rs.getString(2));
System.out.print(",address=" + rs.getString("address"));
System.out.println();
}
結(jié)果集,二維表;
指向記錄的指針:指向當前記錄;
游標剛開始放在結(jié)果集的第一條記錄的上邊;
rs.next();//如果有下一條記錄,返回true;否則返回false;游標向下移動一位
iterator 的 hasNext();和next(); 合二為一
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -