1. 程式人生 > >JDBC原理和連線池技術

JDBC原理和連線池技術

JDBC原理: Java Datebase Connectivity:java訪問資料庫的解決方案
.希望用相同的方式訪問不同的資料庫,以實現與具體資料庫無關的java操作頁面
.JDBC定義了一套標準介面,即訪問資料庫通用的API,不同的資料庫廠商根據各自的
資料庫的特點去實現這些介面
具體實現是由資料庫廠商去實現的.

JDBC介面以及資料庫廠商實現
.DriverManager        ---驅動管理
.Connection            ---連線介面

.Statement
.PreparaedStatement ---語句物件介面

.ResultSet            ---結果集介面

JDBC原理:
1.JDBC定義介面
2.資料庫廠商實現介面
3.程式設計師呼叫介面,實際呼叫的是底層資料庫廠商的實現部分

JDBC的工作過程:
-載入驅動,建立連線
-建立語句物件
-執行SQL語句
-處理結果集
-關閉連線

ResultSet:
查詢的結果存放在ResultSet物件的一系列行中
.ResultSet物件的初始位置在行首
.ResultSet.next()方法用來在行間進行移動
.ResultSet.getXXXX()方法來取得欄位的內容.

JDBC基礎程式設計(寫配置檔案,封裝)
通過連線工具類獲取連線
.在工程中,編寫一個訪問資料庫的工具類,此後所有訪問資料庫的操作,都從工具類中
獲取連線
.兩種方式:
-直接把資料配置寫在工具類中
-把資料庫配置寫在一個properties屬性檔案中,工具類讀取屬性檔案,逐行獲取資料庫
連線引數(建議使用第二種)

通過屬性檔案維護連線屬性
#驅動類名
jdbc.driver = oracle.jdbc.OracleDriver
#連線字串
jdbc.url = jdbc:oracle:thin:@localhost:1521:xe
#訪問資料的使用者名稱
jdbc.user = wuya
#訪問資料密碼
jdbc.password = orcl;

在properties屬性檔案#符號表示註釋

從類路徑中載入屬性檔案
String path = "檔案的url";

properties.load(DBUtility.getClassLoader().getResourceAsStream(path));

連線的關閉:
public static void closeConnection(Connection conn){
    if(conn!=null){
    try{
        conn.close();
    }catch(SQLException e){
        e.printStackTrace();
    }
        
}
}

1.建立屬性db.properties,在該檔案中以鍵值對的形式來儲存連線資料庫的相關資訊
    通過屬性檔案維護連線屬性
    #驅動類名
    jdbc.driver = oracle.jdbc.OracleDriver
    #連線字串
    jdbc.url = jdbc:oracle:thin:@localhost:1521:xe
    #訪問資料的使用者名稱
    jdbc.user = wuya
    #訪問資料密碼
    jdbc.password = orcl;

這樣做的目的是當需要修改連線資料時,只需要修改檔案集合,降低了連線資料庫的資訊
與使用類之間的耦合

2.建立DBUtility類,使用static塊,初始化連線資料資訊

static{
try{
//載入配置檔案
    properties.load(DBUtility.getClassLoader().getResourceAsStream(path));
    driver = properties.getProperty("jdbc.driver");
    url = properties.getProperty("jdbc.url");
    user = properties.getProperty("jdbc.user");
    password = properties.getProperty("jdbc.password");
    }catch(SQLException e){
    e.printStackTrac();
}
}


連線池技術
直接使用JDBC訪問資料庫時要面臨的問題:
1.每一次資料操作請求都需要建立資料庫連線,開啟連線,存取數和關閉資料連線步驟,
而建立連線和開啟資料庫連線是一件即耗費資源又費時的操作,如果頻繁發生這種資料庫
操作,勢必使得系統性能下降
2.連線物件代表著資料庫系統的連線程序,是有限的資源,如果系統的使用使用者非常多,
有可能超出資料庫伺服器的承受極限,造成系統崩潰

資料庫連線池是解決上述問題的最常用的方法.所謂連線池,是可以建立並持有資料庫
連線的元件.連線池可以預先建立並封裝一些連線物件並將其快取起來,並需要使用連線
物件時可以向連線池"借"一個,用完歸還到連線池中

連線池的主要作用:
1.連線池物件的建立和釋放
2.伺服器啟動時,建立指定數量的資料庫連線
3.為使用者請求提供可用連線,如果沒有空閒連線,且連線數沒有超出最大值,建立一個新的
資料庫連線
4.將使用者不在使用的連線標識為可用的,等待其他使用者請求
5.當空閒的連線數過多時,釋放連線物件

連線池元件都需要實現JDBC規範中的javax.sql.DataSource介面
DataSource介面中定義了獲取連線的方法getConnection方法

常用的連線池元件:
DBCP,C3P0,proxool等

以Apach的DBCP元件為例實現資料庫連線池

方案:
1.導包
commons-dbcp-1.2.2.jar
commons-pool-1.3.jar

2.重構db.properties
2.1初始化連線
dataSource.initialSize = 10
2.2最大空閒連線
dataSource.maxIdle = 20
2.3最小空閒連線
dataSource.minIdle = 5
2.4最大的連線數量
dataSource.maxActive = 50
超時回收時間(超時等待時間以毫秒為單位)
dataSource.maxWait = 1000

3.建立ConnectionSource

4.使用ConnectionSource類獲取連線物件
conn.close()
並不一定真的關閉物件,有可能是歸還到連線池中


sql Injection簡介:
select * from t_emp where name='' and salary = 'a' or 'b' = 'b';
此SQL語句的where條件永遠成立.
這種現象稱為sql注入

對於JDBC而言,sql注入攻擊只對Statement有效,,對於PreparedStatement無效.
因為PreparedStatement不允許在插入引數時改變SQL語句的邏輯結構

使用預編譯的語句物件,使用者傳入的任何資料不會和原SQL語句發生匹配關係,無需
對輸入的資料做過濾

如果使用者將"or 1=1"傳入賦值給佔位符,SQL語句將無法執行.