Java 鏈接、操控數據庫總結(JDBC)

看到數據庫鏈接不禁得想起了大一末參加團隊考覈時的悲催經歷~~,還記得當初傻傻地按照書本的代碼打到 Eclipse 上,而後一運行就各類報錯。。。報錯後還傻傻地和書本的代碼一遍又一遍地進行覈對,發現無誤後,還特別糾結——代碼和書本同樣,怎麼就報錯了呢? 最後經過 Google 才得知要添加驅動包,就這樣好多個小時就白白浪費掉了 ~~ 當初連 JDBC 與 JDBC Driver 還沒區分好,往事不堪回首。。。html

大二末,抱着「本身被抗了,也坑坑師弟,讓他們體驗下爬坑的經歷」的心態,考覈師弟時故意沒發驅動包給他們,過後聽他們說就由於這坑了他們幾天的時間。。。java

大三末,輪到大二師弟考覈大一的師弟,而後大二的師弟和大一的說,「數據庫鏈接時,須要一個驅動包,大家本身去了解、下載,具體的就不說了,要學會解決問題。當年帶個人師兄也沒直接提供給我,還害我花了幾天的時間。因此今年我算好了,還提醒大家要注意。。。」,聽到這我背後不禁的一涼,這得有多大的怨氣。。。(^_^,這不怪我,叫了大家遇到解決不了的問題能夠問師兄,大家沒問而已,逃~~)mysql

好了,回憶結束~~。爲了懷念之前的「懵懂青春」,總結下 Java的數據庫鏈接以及 JDBC、JDBC Driver。sql

JDBC 與 JDBC Driver

首先要搞清楚的是,什麼是 JDBC,什麼是 JDBC Driver數據庫

  1. JDBC,JDBC 的全稱爲 Java Database Connectivity,它定義了一套訪問數據庫的 API。使用這些 API 你就可使用 Java 來操控數據庫,執行 selectupdatedeleteinsert 等經常使用的操做。(具體定義請看維基百科api

  2. JDBC Driver,JDBC Driver 就是 Java 與數據庫之間的一層軟件組件——驅動。就像咱們的鼠標驅動、鍵盤驅動等驅動,它擔任了一箇中間人、一名翻譯者。所以,要想使用 Java(JDBC API)來訪問操控數據庫,咱們還須要 JDBC Driver 來負責翻譯。(維基百科上有具體介紹)oracle

JDBC Driver

JDBC Driver 通常是由相應的數據庫提供的,好比 MySQL 提供了 Connector/J 驅動根據官方說明,Connector/J 屬於第 4 種類型的驅動。想了解更詳細、更多的驅動類型能夠參加維基百科)。函數

JDBC Driver 的安裝

JDBC Driver 的安裝很簡單,只須要去官網下載它提供的驅動,並把相應的 Jar 包(一般叫做 mysql-connector-java-version-bin.jar)放在 Java Classpath 下就 OK,若是你和我同樣是搞 J2EE 的,你也能夠直接把它放在 WEB-INF/lib 目錄下,或者用相似 Maven 之類的工具來添加。詳細請看 官方文檔工具

使用

JDBC Driver 的使用在 有不少例子,所以再也不累贅了。畢竟它只是一個驅動,咱們更多的是使用 JDBC API 調用這個驅動與數據庫打交道。更多的使用總結請看下部分。性能

JDBC API

JDBC 只是 Java 中定義的一些接口,它也屬於 JDK 的一部分,就像文件等普通接口同樣,咱們只須要調用它來完成目的就 OK 。既然是 API 咱們就要去看文檔熟悉它才能更好地使用它,這些類分別處於 java.sqljavax.sql

鏈接

要想使用 JDBC API 來操控數據庫,首先要連上數據庫。鏈接數據庫有兩種方法:

  • 使用 DriverManager 。第一次使用 DriverManager 來創建與數據庫的鏈接時,它會自動在 class path 中尋找並加載 JDBC 4.0 驅動。要注意的是,若是是 4.0 以前的版本,須要手動去加載。
  • 使用 DataSource 。根據官方推薦,咱們應該優先使用 DataSource 。相對於比較簡單的 DriverManager ,它比較複雜,也比較全面、詳細。

使用 DriverManager 鏈接數據庫:
要使用 DriverManager ,咱們先要把該類加載進來,使用最簡單的方法(在要加載的類裏添加如下代碼)

Class.forName("com.mysql.jdbc.Driver").newInstance();

加載了 DriverManager 後,咱們就可使用它來獲取與數據庫的鏈接(假設咱們使用本地數據,默認路徑爲 localhost ;數據庫名爲 test ;用戶名爲 root;密碼爲 123):

// DriverManager、Connection 類在 java.sql 裏都有定義
String URL = "jdbc:mysql://localhost:3306/test?user=root&password=123";
Connection conn = DriverManager.getConnection(URL); 

//或者
String URL = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "123";
Connection conn = DriverManager.getConnection(URL, user, password); 

//或者
String URL = "jdbc:mysql://localhost:3306/test";
Properties connectionProps = new Properties();
connectionProps.put("user", this.userName);
connectionProps.put("password", this.password);
Connection conn = DriverManager.getConnection(URL, connectionProps);

(我的以爲,第一種看起來簡單、方便,可是修改麻煩、可讀性不高,不太建議使用。若是你只想簡單地傳遞用戶名與密碼能夠選用第二種。若是你有不少參數要傳遞,好比字符編碼、用戶名密碼等,優先選擇第三種。)

鏈接數據庫,咱們只需調用 getConnection() 方法而且返回與數據庫的鏈接(Connection)就 OK ,有了此鏈接咱們就能夠操做數據了。

在這要注意的是 getConnection 方法裏的字符串參數 URL 。該字符串指定了數據庫的路徑、數據庫名、數據庫配置(用戶名密碼等)。 MySQL 的 URL 語法以下:

jdbc:mysql://[host][,failoverhost...][:port]/[database] [?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...
詳細說明

使用 DataSource 鏈接:
DataSource 鏈接涉及的東西比較多,找時間另開一篇來總結。 ^_^

建立語句

鏈接上了數據庫,我就能夠操控數據庫了。一般咱們是編寫 SQL 語句來操控數據庫的。所以,在操控數據庫以前,咱們還要建立 SQL 語句。JDBC 定義了 3 種類型語句接口,用來運行 SQL 語句,而且返回執行結果:

  • Statement
  • PreparedStatement
  • CallableStatement

相應地,建立語句也有三種方法:

  • Connection.createStatement() ——建立普通的語句,它一般不須要提供參數。更多
  • Connection.prepareStatement(String stringSQL)——建立預編譯語句,一般要提供一個帶有佔位符的字符串 SQL 語句。 更多
  • Connection.prepareCall()——建立存儲過程。更多

這裏要注意的是,StatementPreparedStatement 的區別。它們的最主要區別就是:

  1. PreparedStatement 對 SQL 語句進行了預編譯,在須要運行屢次 SQL 語句是能獲得顯著的性能提高
  2. 能夠有效地防止 SQL 注入攻擊( SQL injection attacks
  3. 能夠輕鬆地在 SQL 字符串裏使用非標準的 Java 對象,如DateTimeTimestampBigDecimal
  4. 相對於使用拼接方式的 Statement,它使用佔位符(?) 很好地把查詢語句以及變量值分開。
  5. 更多請看 stackoverflow 上的討論

操控數據庫

平時咱們操控數據庫,最經常使用的、最簡單的就是selectupdatedeleteinsert 等經常使用的操做了。那麼咱們是怎麼經過 JDBC API 來實現這些行爲的呢?

一般,咱們會使用 Statement.executeQuery(String sql) 來執行 select 查詢操做,它會返回一個 ResultSet 的對象,這個對象包含了查詢返回的數據。updatedeleteinsert 等更新操做使用 Statement.executeUpdate(String sql),它會返回一個整數,表明影響的行數。

ResultSet

ResultSet 是查詢數據庫時返回的數據集,咱們能夠把它想象爲一張與數據表相似的數據表,就像咱們使用命令行執行 select 語句時控制檯返回的數據表。不一樣之處是它擁有一個一開始處於第一行數據的前一行的指針。而後咱們就能夠經過不停地調用 ResultSet.next() 來移動指針獲取每一行的數據,該函數在指針移動到最後一行的下一行時就返回 false ,咱們能夠利用這個特性來做爲終止條件遍歷整張表。(第一行的前一行與最後一行的下一行都是不存在的行,是虛擬的行)

此外,ResultSet 有 3 中類型(更多):

  1. TYPE_FORWARD_ONLY:這個是默認的類型,它只能不一樣地調用 next() 方法把指針向下一行移動,而不能往回走。
  2. TYPE_SCROLL_INSENSITIVE:這個類型除了能夠調用 next() 方法把指針向下一行移動外,還能夠調用previous() 方法把指針指向前一行,使用 first 方法把指針移動到第一行等。
  3. TYPE_SCROLL_SENSITIVE:此方法與第 2 個類型同樣,能夠任意移動指針。但它是敏感型的。也就是說,當你使用 Statement.executeQuery(String sql) 產生了 ResultSet 後,數據庫中響應的數據發生了改變,它會更新 ResultSet 並保持數據與數據庫一致。而第 2 個類型是非敏感型的,它不會更新 ResultSet。

要指定 ResultSet 的類型,咱們只需在建立 Statement 時指定:

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE);

OK,我已經能夠在獲取數據表中的任意行了,咱們如今來獲取一行數據中的特定列的數據。ResultSet 提供了 getter 方法(getBoolean、getLong、getInt等方法)來獲取當前行的列。這些方法的參數既能夠是列的索引號(從 1 開始的整型)也能夠是列的別名或者列名(字符串)。好比 ResultSet.getInt(1) 獲取第一列的數據,ResultSet.getFloat("score") 獲取列名爲 score 的列。更多

參考

Oracle 官方 Java教程 —— JDBC(TM) Database Access
MySQL 5.6 參考手冊
維基百科 JDBC Driver
java.sql 包
stackoverflow

相關文章
相關標籤/搜索