小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

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


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

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

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

|--    DriverManager    [Class]    用來(lái)管理一組數(shù)據(jù)庫(kù)的驅(qū)動(dòng)

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

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

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

|--    Type    [Class]    

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

|--    Clob    [Interface]    字符大對(duì)象

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

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

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


 編寫(xiě)JDBC程序步驟
step1:注冊(cè)驅(qū)動(dòng)程序    [也就是把驅(qū)動(dòng)加載到JVM中]
    1.Class.forName("驅(qū)動(dòng)類(lèi)的全限定名");
        如:Class.forName("oracle.jdbc.driver.OracleDriver");
                Class.forName("com.mysql.jdbc.Driver");
    2.使用new操作符來(lái)創(chuàng)建驅(qū)動(dòng)類(lèi)對(duì)象
        如:Driver d = new oracle.jdbc.driver.OracleDriver();
                //DriverManager.registerDriver(d);
    3.使用系統(tǒng)屬性-Djava.drivers來(lái)指定驅(qū)動(dòng)類(lèi)
        如:-Djava.drivers = com.mysql.jdbc.Driver;
step2:獲取數(shù)據(jù)庫(kù)連接    [Connection]
    如:
    String url = "主協(xié)議:此協(xié)議:thin:@ip地址:端口號(hào):數(shù)據(jù)庫(kù)實(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語(yǔ)句
    如:String sql = "select ..........";
            ResultSet rs = stm.executeQuary(sql);
step5:如果是select語(yǔ)句,則處理結(jié)果集    [ResultSet]
    如:while(rs.next()){
                rs.getXXX系列的方法();
            }
step6:釋放資源    [close]
    如:if(con != null) con.close();
            if(stm != null) stm.close();
            if(rs != null) rs.close();

 

下面就簡(jiǎn)單的分析一下JDBC的這六個(gè)步驟:
1.獲取連接Connection對(duì)象分析
      a.獲取數(shù)據(jù)庫(kù)的三大要素
            |-- URL:不同的數(shù)據(jù)庫(kù)系統(tǒng)的URL不相同,但是至少有如下的內(nèi)容:
                            主協(xié)議:次協(xié)議:HOST(主機(jī)):PORT(端口):SID(庫(kù)名)
            |-- USER:用戶名
            |-- PASSWORD:密碼
      b.DriverManager獲取連接的原理:
 1//驅(qū)動(dòng)管理器類(lèi)
 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ū)動(dòng),并且一次與給定的URL進(jìn)行匹配,如果成功則返回當(dāng)前驅(qū)動(dòng)的Connection對(duì)象*/
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/*到此都沒(méi)有返回,說(shuō)明沒(méi)有匹配成功,則拋出SQLException異常*/
26    throw new SQLException("no suitable driver");
27  }

28}
2. Statement 調(diào)用靜態(tài)SQL
    PreparedStatement 來(lái)執(zhí)行動(dòng)態(tài)SQL,可以為SQL動(dòng)態(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ù))來(lái)傳參數(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用來(lái)調(diào)用存儲(chǔ)過(guò)程[procedure]
1String sql = "{call insert_user(?,?)}"
2CallableStatement cstm = con.prepareCall(sql);
3//綁定參數(shù)
4cstm.setString(1,"user");
5cstm.setString(2,"password");
6//執(zhí)行過(guò)程,此返回值表示受影響的記錄條數(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語(yǔ)句
 9    ResultSet rs = stm.getResultSet();
10  }
else{
11    //為假,表示執(zhí)行非select語(yǔ)句
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          對(duì)底層數(shù)據(jù)庫(kù)異常的封裝,它是一個(gè)已檢查異常。所以應(yīng)用程序必須對(duì)它做處理。
        .getErrorCode();                獲取特定于數(shù)據(jù)庫(kù)供應(yīng)商的錯(cuò)誤代碼。
    java.sql.SQLWaring extends SQLExecption         提供關(guān)于數(shù)據(jù)庫(kù)訪問(wèn)警告信息的異常。

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

8}

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

例:
//利用元數(shù)據(jù)打印出結(jié)果集
public void executeSQL(String sqlcommand){
 Connection con 
= null;
 Statement stm 
= null;
 ResultSet rs 
= null;
 
try{
  
//這里的ConnectionFactory是寫(xiě)的一個(gè)連接工廠,這里就不做介紹了。
  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)情況下是自動(dòng)提交的,每執(zhí)行一次SQL命令,就提交commit一次。[AutoCommit]
如:
轉(zhuǎn)帳(){
    ...
    update t_account1 set balance = balance-100;
    update t_account2 set balance = balance+100;
    ...
}
如何讓以上兩句SQL語(yǔ)句,一起執(zhí)行,一起失敗。所以就需要把他們放在一個(gè)事務(wù)中。
如:
轉(zhuǎn)帳(){
    ...
    con.setAutoCommit(false);//關(guān)閉自動(dòng)事務(wù)提交
    update t_account1 set balance = balance-100;
    update t_account2 set balance = balance+100;
    如果以上兩句都成功,則:
    con.commit();//提交事務(wù)
    如果以上任意一個(gè)失敗,則:
    con.rollback();//事務(wù)回滾
}

獲取主鍵方式(主鍵值生成策略)
主鍵值不應(yīng)該由UI界面來(lái)收集,而應(yīng)該由應(yīng)用程序自動(dòng)生成,常見(jiàn)的策略如下:
a. max(id)方法
    select max(id) from table_name;
    此方法當(dāng)有多線程并發(fā)時(shí),就會(huì)產(chǎn)生問(wèn)題。
b. sequence 序列
    select sequence.nextval from dual;
    此方法只適用支持序列的數(shù)據(jù)庫(kù)產(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自動(dòng)維護(hù)
5    select next_id from id_table for update;
6    update id_table set next_id = next_id+1;
7    commit;

并發(fā)控制:多個(gè)事務(wù)同時(shí)操作同一個(gè)對(duì)象
有三種并發(fā)情況,如下:
1、臟讀                Dirty reads                讀到其他事務(wù)沒(méi)有提交的數(shù)據(jù)。注:Oracle不支持
2、不可重復(fù)讀    Repeatable reads     同一個(gè)事務(wù)在兩個(gè)不同的時(shí)刻讀取不同結(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ù)讀問(wèn)題:
讓T1在查詢語(yǔ)句中加入for update子句,從而把選定的記錄加上排他鎖;那么T1事務(wù)完成之前,其他事務(wù)是不能來(lái)獲取鎖資源的。
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
解決幻影讀問(wèn)題:
鎖表:lock table table_name in mode;

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

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

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多