日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JDBC 學(xué)習(xí)筆記

 滄海一聲笑! 2009-05-13
JDBC:
    |-- 數(shù)據(jù)庫互聯(lián)。
    |-- 由SUN公司所制定的用來訪問數(shù)據(jù)庫的規(guī)范。
    |-- 數(shù)據(jù)庫數(shù)據(jù) <= 交互 => 應(yīng)用程序。


JDBC包含主要兩個部分:
    |-- part 1.由SUN公司制定的規(guī)范接口
        |-- java.sql    -->  核心包
        |-- javax.sql  -->  擴(kuò)展包
    |-- part 2.由數(shù)據(jù)庫廠商所提供的數(shù)據(jù)庫驅(qū)動程序,它們實(shí)現(xiàn)了part 1部分。

JDBC的驅(qū)動程序包含以下四種類型:
    |-- 第一代驅(qū)動(JDBC - ODBC Bridge)
        |-- 首先把JDBC的調(diào)用轉(zhuǎn)換成ODBC的調(diào)用,再用ODBC與具體的數(shù)據(jù)庫系統(tǒng)通信。
    |-- 第二代驅(qū)動 (Native - API party - Java driver 本地API部分Java驅(qū)動)
        |-- Conrerts JDBC calls into calls on the native client API of a specific RODMS.
        |-- 缺點(diǎn):不同的數(shù)據(jù)庫需要安裝不同的客戶端(每臺電腦都要裝)。
    |-- 第三代驅(qū)動 (JDBC - net pure Java driver 網(wǎng)絡(luò)純Java驅(qū)動)
        |-- 提供網(wǎng)絡(luò)節(jié)點(diǎn),通過網(wǎng)絡(luò)節(jié)點(diǎn)訪問數(shù)據(jù)庫。
        |-- Translates JDBC calls into a DBMS independent net protocol, which is then translated 
            to a DBMS protocol by a server.
    |-- 第四代驅(qū)動 (Native protocol pure Java driver 本地協(xié)議純Java驅(qū)動)
        |-- Conrerts JDBC calls directly into the network protocol used by DBMS.

JDBC核心API
java.sql
|--    Driver    [Interface]    所有驅(qū)動必需實(shí)現(xiàn)的接口

|--    DriverManager    [Class]    用來管理一組數(shù)據(jù)庫的驅(qū)動

|--    Connection    [Interface]    與數(shù)據(jù)庫的一個連接對象

|--    Statement    [Interface]    用于執(zhí)行一個靜態(tài)的SQL語句,并返回它所生成的結(jié)果對象
    |--    PreparedStatement    [Interface]    表示預(yù)編譯SQL語句對象(動態(tài))
        |--    CallableStatement    [interface]    表示用來調(diào)用存儲過程對象

|--    ResultSet    [Interface]    存放查詢結(jié)果集的對象

|--    Type    [Class]    

|--    Blob    [Interface]    二進(jìn)制大對象

|--    Clob    [Interface]    字符大對象

|--    SQLException    [Class]    數(shù)據(jù)庫最底層異常(已檢測異常)
    |--    SQLWarning    [Class]    警告

|--    DatabaseMetaData    [Class]    基本數(shù)據(jù)的元數(shù)據(jù)

|--    ResultSetMetaDate    [Class]    結(jié)果集的元數(shù)據(jù)


 編寫JDBC程序步驟
step1:注冊驅(qū)動程序    [也就是把驅(qū)動加載到JVM中]
    1.Class.forName("驅(qū)動類的全限定名");
        如:Class.forName("oracle.jdbc.driver.OracleDriver");
                Class.forName("com.mysql.jdbc.Driver");
    2.使用new操作符來創(chuàng)建驅(qū)動類對象
        如:Driver d = new oracle.jdbc.driver.OracleDriver();
                //DriverManager.registerDriver(d);
    3.使用系統(tǒng)屬性-Djava.drivers來指定驅(qū)動類
        如:-Djava.drivers = com.mysql.jdbc.Driver;
step2:獲取數(shù)據(jù)庫連接    [Connection]
    如:
    String url = "主協(xié)議:此協(xié)議:thin:@ip地址:端口號:數(shù)據(jù)庫實(shí)例名";
    String user = "XXX";
    String pwd = "XXX";
    Connection con = DriverManager.getConnection(url,user,pwd);
step3:創(chuàng)建執(zhí)行的SQL的環(huán)境    [也就是創(chuàng)建Statement]
    如:Statement stm = con.createStatement();
step4:執(zhí)行SQL語句
    如:String sql = "select ..........";
            ResultSet rs = stm.executeQuary(sql);
step5:如果是select語句,則處理結(jié)果集    [ResultSet]
    如:while(rs.next()){
                rs.getXXX系列的方法();
            }
step6:釋放資源    [close]
    如:if(con != null) con.close();
            if(stm != null) stm.close();
            if(rs != null) rs.close();

 

下面就簡單的分析一下JDBC的這六個步驟:
1.獲取連接Connection對象分析
      a.獲取數(shù)據(jù)庫的三大要素
            |-- URL:不同的數(shù)據(jù)庫系統(tǒng)的URL不相同,但是至少有如下的內(nèi)容:
                            主協(xié)議:次協(xié)議:HOST(主機(jī)):PORT(端口):SID(庫名)
            |-- USER:用戶名
            |-- PASSWORD:密碼
      b.DriverManager獲取連接的原理:
 1//驅(qū)動管理器類
 2class DriverManager{
 3  static Vector<Driver> drivers = new Vector<Driver>();
 4  public static void registerDriver(Driver d){
 5    driver.add(d);
 6  }

 7/**獲取連接的方法*/
 8  public static Connection getConnection(String url,String user,String pwd) throws SQLException{
 9    Properties info = new Properties();
10    info.setProperty("user",user);
11    info.setProperty("password",pwd);
12    return getConnection(url,info);
13  }

14  public static Connection getConnection(String url,Properties info)throws SQLException{
15/*迭代多由的驅(qū)動,并且一次與給定的URL進(jìn)行匹配,如果成功則返回當(dāng)前驅(qū)動的Connection對象*/
16    Iterator<Driver> iter = drivers.iterator();
17    while(iter.hasNext()){
18      Driver d = iter.next();
19      if(匹配(url,d)){
20        return d.connect(url,info);
21      }
else{
22        continue;
23      }

24    }

25/*到此都沒有返回,說明沒有匹配成功,則拋出SQLException異常*/
26    throw new SQLException("no suitable driver");
27  }

28}
2. Statement 調(diào)用靜態(tài)SQL
    PreparedStatement 來執(zhí)行動態(tài)SQL,可以為SQL動態(tài)綁定參數(shù)。
    如:同構(gòu)SQL,SQL內(nèi)容一樣參數(shù)不同。
 1select id,first_name from s_emp
 2where dept_id = ? and name like ?;
 3
 4insert into t_user values(?,?,?,?);
 5-- 上面的這些情況就可以用setXXX的方法(綁定參數(shù))來傳參數(shù)。
 6-- 例:
 7Connection con = ConnectionFactory.getConnection();
 8String sql = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
 9PreparedStatement pstm = con.PreparedStatement(sql);
10//綁定參數(shù)
11pstm.setInt(1,XXX);
12pstm.setString(2,XXX);
13. . . 
3.CallableStatement用來調(diào)用存儲過程[procedure]
1String sql = "{call insert_user(?,?)}"
2CallableStatement cstm = con.prepareCall(sql);
3//綁定參數(shù)
4cstm.setString(1,"user");
5cstm.setString(2,"password");
6//執(zhí)行過程,此返回值表示受影響的記錄條數(shù)
7int res = cstm.executeUpdate();
8
4.執(zhí)行SQL
 1statement:
 2  
 3  executeQuery(selectSQL);   =>  ResultSet
 4  executeUpdate(dmlSQL);     =>  int
 5  execute(arbiSQL);          =>  boolean
 6  
 7  if(stm.execute(sql)){
 8    //為真,表示執(zhí)行select語句
 9    ResultSet rs = stm.getResultSet();
10  }
else{
11    //為假,表示執(zhí)行非select語句
12    int res = stm.getUpdateCount();
13  }
5.處理結(jié)果集
1ResultSet rs:
2    rs.next();   =>  boolean用于判斷結(jié)果集中是否還有可讀取的元素。
3     rs.getXXX();  get系列方法,用于讀去結(jié)果集中的元素。
6.釋放資源
1Connection.close();
2Statement.close();
3ResultSet.close();

 

[JDBC Advanced Topics]異常處理、元數(shù)據(jù)以及事務(wù)。
1、異常 Exception
    java.sql.SQLException          對底層數(shù)據(jù)庫異常的封裝,它是一個已檢查異常。所以應(yīng)用程序必須對它做處理。
        .getErrorCode();                獲取特定于數(shù)據(jù)庫供應(yīng)商的錯誤代碼。
    java.sql.SQLWaring extends SQLExecption         提供關(guān)于數(shù)據(jù)庫訪問警告信息的異常。

例:
1try{
2//此處省略
3}
 catch(SQLException e){
4      while(e != null){
5          e.printStackTrace();
6          e = e.getNextExecption();
7      }

8}

2、元數(shù)據(jù):用來描述其他數(shù)據(jù)的數(shù)據(jù)
JDBC中的元數(shù)據(jù):
ResultSetMetaDate: 結(jié)果集元數(shù)據(jù),它用來描述結(jié)果集本身。
ResultSet.getMetaDate(); 獲取當(dāng)前結(jié)果集的元數(shù)據(jù)。
DatabaseMetaDate: 數(shù)據(jù)庫元數(shù)據(jù),用來描述數(shù)據(jù)庫本身。
Connection.getMetaDate(); 獲取當(dāng)前數(shù)據(jù)庫的元數(shù)據(jù)。

例:
//利用元數(shù)據(jù)打印出結(jié)果集
public void executeSQL(String sqlcommand){
 Connection con 
= null;
 Statement stm 
= null;
 ResultSet rs 
= null;
 
try{
  
//這里的ConnectionFactory是寫的一個連接工廠,這里就不做介紹了。
  con = ConnectionFactory.getConnection();
  stm 
= con.createStatement();
  
boolean flag = stm.execute(sqlcommand);
  
if(flag){
   rs 
= stm.getResultSet();
   ResultSetMetaDate rsmd 
= rs.getMetaDate();
   
int columns = rsmd.getColumnCount();
   
for(int i=1;i<columns;i++){
    String columnName 
= rsmd.getColumnLabel(i);
    System.out.print(columnName
+"\t");
   }

   System.out.println();
   
while(rs.next()){
    
for(int i=1;i<columns;i++){
     Object content 
= rs.getObject(i);
     System.out.print(content
+"\t");
    }

    System.out.print();
   }
else{
    
int results = stm.getUpdateCount();
    System.out.println(results
+" resultes was update ");
   }

  }

 }
catch(SQLExecption e){
    
//此處省略若干
 }

}

3、DML的操作 [JDBC的事務(wù)] 以事務(wù)為單位
JDBC事務(wù):
定義:一組相關(guān)的操作,不可分割,一起成功,一起失敗。
相關(guān)操作:
Connection:
    commit(); JDBC事務(wù)提交
    rollback(); JDBC事務(wù)回滾
JDBC的事務(wù)默認(rèn)情況下是自動提交的,每執(zhí)行一次SQL命令,就提交commit一次。[AutoCommit]
如:
轉(zhuǎn)帳(){
    ...
    update t_account1 set balance = balance-100;
    update t_account2 set balance = balance+100;
    ...
}
如何讓以上兩句SQL語句,一起執(zhí)行,一起失敗。所以就需要把他們放在一個事務(wù)中。
如:
轉(zhuǎn)帳(){
    ...
    con.setAutoCommit(false);//關(guān)閉自動事務(wù)提交
    update t_account1 set balance = balance-100;
    update t_account2 set balance = balance+100;
    如果以上兩句都成功,則:
    con.commit();//提交事務(wù)
    如果以上任意一個失敗,則:
    con.rollback();//事務(wù)回滾
}

獲取主鍵方式(主鍵值生成策略)
主鍵值不應(yīng)該由UI界面來收集,而應(yīng)該由應(yīng)用程序自動生成,常見的策略如下:
a. max(id)方法
    select max(id) from table_name;
    此方法當(dāng)有多線程并發(fā)時,就會產(chǎn)生問題。
b. sequence 序列
    select sequence.nextval from dual;
    此方法只適用支持序列的數(shù)據(jù)庫產(chǎn)品,所以不是很通用。
c. 維護(hù)單行單列得表
1    create table id_table(next_id number not null);
2    insert into id_table next_id values(1);
3    commit;
4    --使用以下SQL自動維護(hù)
5    select next_id from id_table for update;
6    update id_table set next_id = next_id+1;
7    commit;

并發(fā)控制:多個事務(wù)同時操作同一個對象
有三種并發(fā)情況,如下:
1、臟讀                Dirty reads                讀到其他事務(wù)沒有提交的數(shù)據(jù)。注:Oracle不支持
2、不可重復(fù)讀    Repeatable reads     同一個事務(wù)在兩個不同的時刻讀取不同結(jié)果
如:
1T1:select score from t_score where id= 48;
2T2:update t_score set score = score+10 where id = 48;
3T1:select score from t_score where id= 48;
解決重復(fù)讀問題:
讓T1在查詢語句中加入for update子句,從而把選定的記錄加上排他鎖;那么T1事務(wù)完成之前,其他事務(wù)是不能來獲取鎖資源的。
3、幻影讀            Phanton reads          記錄數(shù)量變化,而不是行記錄的列值
1T1:elcet count(*from t_class where classname = '******';
2T2:nsert into t_class values(.);
3    commit();
4T1:selcet count(*from t_class where classname = '******';
5
解決幻影讀問題:
鎖表:lock table table_name in mode;

事務(wù)隔離級別:SUN在JDBC規(guī)范中制定了5個級別,分別用來滿足不同的并發(fā)性。
Connection:
0        .TRANSACTION_NONE                                無
1        .TRANSACTION_READ_UNCOMMITED     可以臟讀
2        .TRANSACTION_READ_COMMITED           不可以臟讀
4        .TRANSACTION_REPEATABLE                    不可以重復(fù)讀
8        .TRANSACTION_SERIALIZABLE                  為每個事務(wù)都開辟一個空間
事務(wù)的隔離界別設(shè)置得越高,則并發(fā)性能越差
注:不同數(shù)據(jù)庫,對隔離級別的支持也是不一樣的。
如:oracle就不支持0和1兩種。

如何設(shè)置隔離級別?
如:con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITED);
這個也是默認(rèn)事務(wù)隔離級別。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多