1. 程式人生 > >JDBC入門筆記1.md

JDBC入門筆記1.md

JDBC的常用類和介面

DriverManager :資料庫驅動管理類。這個類的作用:

​ 1)註冊驅動; ​ 2)建立java程式碼和資料庫之間的連線,即獲取Connection介面;

Connection: 是一個介面, 建立資料庫連線的一個介面。

​ 作用:建立資料庫和java程式碼之間的連線。

Statement(介面)、PreparedStatement(介面)

​ 作用:(解決安全隱患問題,比如sql注入的問題)

CallbackStatement(操作儲存過程):

​ 作用:資料庫操作,向資料庫傳送sql語句。

ResultSet(介面): 結果集。

​ 作用:Statement 傳送sql語句,得到的結果 封裝在 ResultSet 中。

JDBC-API詳解

1) DriverManager 驅動管理類介紹

DriverManager驅動管理類的作用:

​ Jdbc程式中的DriverManager用於載入驅動,並建立與資料庫的連結。 ​ 使用DriverManager類的靜態方法可以註冊資料庫驅動, ​ 這個靜態方法是:registerDriver(),如下所示:

	static void		registerDriver(Driver driver)		向 DriverManager 註冊給定驅動程式

// 註冊驅動程式碼 這裡的new Driver()的類Driver就是來自mysql資料庫。 ​

 DriverManager.
registerDriver(new Driver());
注意:在實際開發中並不推薦採用registerDriver方法註冊驅動。 原因:
雖然 DriverManager.registerDriver(new com.mysql.jdbc.Driver())方法可以註冊驅動,
但會使資料庫驅動註冊兩次。
Drive.class原始碼中有如下static靜態程式碼塊:
當我們在建立Driver類的物件時就會載入靜態程式碼塊中的程式碼。
這時我們就會很明顯發現,靜態程式碼塊中的程式碼與我們之前自已寫的註冊驅動 的方式重複了。
針對上面的註冊驅動重複的問題,我們可以思考:我們只需要執行Driver.class中靜態程式碼塊
中的程式碼就行了。那麼我們如何做才能讓靜態程式碼塊執行呢?
當類載入到記憶體中的時候,靜態程式碼塊就會執行。
所以我們只需要讓Driver.class載入到記憶體中就可以達到我們的目的了。

想要讓Driver.class類載入到記憶體中,並給類進行初始化,可以使用反射技術。

所以註冊驅動的方式最終使用如下程式碼:
	Class.forName("com.mysql.jdbc.Driver");

說明:上述這種方式可以在載入驅動類的時候,會自動執行靜態程式碼塊static中的內容。 ​ 也就相當於實現了資料庫驅動的註冊。

2) Connection詳解

URL介紹:指定一個具體的資料庫

使用DriverManager類中的getConnection(url,user,password)方法和mysql資料庫建立連線。 ​ url :連線到具體的資料庫的地址。 ​ user : 資料庫使用者名稱。 ​ password : 資料庫密碼。 舉例: Connection con = DriverManager.getConnection ​ (“jdbc:mysql://localhost:資料庫埠/資料庫名”, “root”, “123”); 作用:URL用於標識資料庫的位置,程式設計師通過URL地址告訴JDBC程式連線哪個資料庫。 語法格式:jdbc:mysql:// localhost:3306/資料庫名 上述地址的簡寫形式:jdbc:mysql:///資料庫名 等價於 jdbc:mysql://localhost:3306/資料庫名 簡寫要求:必須是本地資料庫,即ip位置必須是localhost或者 127.0.0.1 ​ 而埠號必須是3306.不建議使用簡寫方式. 屬性:useUnicode=true&characterEncoding=utf8(很少使用) 是否使用Unicode字符集,如果本引數值設定為true,表示是。 解決問題:如果是java程式碼操作資料庫時發生中文亂碼問題,我們可以按照如下格式來解決。 舉例: ​ jdbc: mysql://localhost:3306/資料庫名?useUnicode=true&characterEncoding=utf8

獲取資料庫連線Connction的方法: ​ Connection con = DriverManager.getConnection(url, user, password); ​ url:連線到某一個具體的資料庫的地址。 ​ user:資料庫的使用者名稱。 ​ password:資料庫使用者名稱對應的密碼。

注意:獲取連線時匯入的包是java.sql.Connection;

​ Jdbc程式中的Connection,它用於代表資料庫的連結, ​ Connection是資料庫程式設計中最重要的一個物件, ​ 客戶端與資料庫所有互動都是通過connection物件完成的.

Connection常用方法:

createStatement():建立向資料庫傳送sql的statement物件; Statement conn.createStatement() 該物件可以將SQL傳送給資料庫進行執行 ; PreparedStatement conn.preparedStatement(sql) 對SQL語句進行預編譯,防止SQL注入;

3) Statement 詳解

當我們得到向資料庫傳送sql的statement物件之後, 我們就可以將sql語句傳送給資料庫,讓資料庫執行sql語句了。 目標:向資料庫傳送sql,獲得執行結果。

3.1 executeQuery(sql)
Statement介面中的方法:

​ 如果傳送的是select語句,那麼我們必須使用 Statement介面中的方法executeQuery(sql)將 sql語句傳送給資料庫執行。 ​ 當然了,我們執行了select語句,我們必須得知道select語句執行的查詢結果, ​ executeQuery(sql)返回值就是select語句的查詢結果。返回值型別為ResultSet型別。 用於向資料庫傳送 select 語句,返回ResultSet 結果集物件. ​ 例: ​ String sql = “select * from user”; ​ ResultSet rs = st.executeQuery(sql);

3.2 executeUpdate(sql)
Statement介面中的方法:

​ 當然除了向資料庫傳送select語句,我們有時還需要向資料庫傳送增(insert )刪( delete)改(update )語句, ​ 那麼這時候必須要使用Statement介面中的方法executeUpdate(sql), ​ 此方法用於向資料庫傳送非select語句。方法的返回值為int 型別引數, ​ 代表sql語句影響記錄行數。 舉例: ​ String sql = “update user set password=‘abcdef’”; ​ int sum = stmt.executeUpdate(sql); ​ 如果不加條件會修改資料庫所有資料,一共修改三條,因此返回值為3。 ​ 如果新增 where id = 1 就會修改1行記錄。 此時返回值為1。 總結: ​ executeQuery(sql) 執行select語句。 ​ executeUpdate(sql) 執行insert update delete 語句。

4) ResultSet 結果集

4.1 如何遍歷結果集

遍歷的原理: ​ 結果集其實就是一張表。那麼在java中怎麼遍歷這個表呢? ​ 首先,ResultSet結果集有一個游標,一開始這個游標處於資料表的第一行資料之前。 ​ 而我們可以通過ResultSet介面中的next()方法將游標下移。 ​ 如果說,游標所指向的當前行有資料的話,那麼會返回true, ​ 如果沒有值的話,那麼會返回false。 ​ 基於這樣一個情況,我們可以通過 while(rs.next())的方式對ResultSet做遍歷。 ​ 一直到游標所在行沒有資料的話,結束遍歷。 注意:根據資料庫內部列型別,選擇相應 getXXX方法來獲取資料。 ​ while( rs.next() ) ​ { ​ int ---- getInt() ​ varchar ---- getString() ​ date ----- getDate() ​ }

4.2 如何從結果集取出資料,並且轉化對應的資料型別

那麼會了如何遍歷結果集,我們需要解決的就是如何獲取結果集中的資料? ​ 需要注意的是:每一次迴圈遍歷我們獲取的是表中的一行資料。 我們獲取一行中的任何列中的值,可以通過如下的方法: ​ getXXX(列名/下標); ​ XXX指的是表中的列在java中對應資料型別. ​ 如果某一列是varchar,java中對應的就是String. ​ 如果某一列是int,java中對應的就是int. ​ 引數可以是列的名稱,可以是列所在的索引(索引從1開始). ​ 兩種方式說明如下所示: ​ 方式1: getInt(index 結果集中列索引) 注意:索引從1開始。 ​ getInt(1) – > 取出第一列的內容,轉成 整形 返回 ​ 方式2:getString(列名 或者 列的別名) ​ getString(“username”); – > 取出列名為 username 的內容,轉成 字串 返回。 //假如有表如下:

id username password
1 zhangsan 123

對於上圖中的一行資料,我要獲取username為zhangsan這列的值, 有如下2種寫法:

4.2.1) rs.getString(“username”); 通過列名獲取該列的值。
4.2.2) rs.getString(2); 通過username列所在的第二個位置獲取該列的值。

JDBC 程式設計步驟總結:(六步)

1) 註冊驅動

​ class.forName(“com.mysql.jdbc.Driver”); // JDBC4.0以後該步驟可以省略

2) 獲得資料庫連線

​ Connection conn =DriverManager.getConnection(url,user,password);

3) 建立向資料庫傳送sql的statement物件

​ Statement stmt = conn.CreateStatement();

4) 向資料庫傳送sql

​ ResultSet rs = stmt.executeQuery(sql); //select 語句 ​ int updateSum = stmt.executeUpdate(sql); // insert\update\delete 語句

5) 處理結果集

​ while(re.next()){ ​ rs.getString(列名 或 列的別名) ​ rs.getInt(別名) ​ }

6) 關閉資源

​ rs.close; ​ stmt.close; ​ conn.close;

JDBC工具類

在上面的學習過程中,我們發現我們有很多重複的操作。

那麼這樣一方面來說對我們開發帶來了不便,更多的時候是當我遇到如下的問題: 資料庫的使用者名稱發生了變化,這時候我們發現,我們需要修改每處獲取連線的使用者名稱引數。 這樣是對於我們後期的維護是非常繁瑣的。所以我們需要對jdbc操作資料庫的步驟的一些常用的方法抽出來,放到一個外部的工具類中。 ​

JDBC工具類JDBCUtils (Demo版本)

​ 例: ​ public class JDBCUtilsDemo { ​ static String url = null; ​ static String user = null; ​ static String password = null; ​ static { ​ try {

​ //通過properties物件讀取到外部配置的內容 ​ Properties prop = new Properties(); ​ FileInputStream is = new FileInputStream(“jdbc.properties”); ​ // 載入外部的配置檔案 ​ prop.load(is); ​ // 讀取外部配置檔案的內容 ​ url = prop.getProperty(“url”); ​ user = prop.getProperty(“user”); ​ password = prop.getProperty(“password”); ​ } catch (Exception e) { ​ e.printStackTrace(); ​ } ​ } ​ //獲得連線方法 ​ public static Connection getConnection() { ​ Connection conn = null; ​ try { ​ conn = DriverManager.getConnection(url, user, password); ​ } catch (SQLException e) { ​ e.printStackTrace(); ​ } ​ return conn; ​ } ​ //釋放資源方法 ​ public static void release(Connection conn, Statement st, ResultSet rs) { ​ try { ​ if (conn != null) { ​ conn.close(); ​ } ​ } catch (SQLException e) { ​ e.printStackTrace(); ​ } ​ try { ​ if (st != null) { ​ st.close(); ​ } ​ } catch (SQLException e) { ​ e.printStackTrace(); ​ } ​ try { ​ if (rs != null) { ​ rs.close(); ​ } ​ } catch (SQLException e) { ​ e.printStackTrace(); ​ } ​ } }