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(); } } }