日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

更多內(nèi)容,歡迎關(guān)注微信公眾號:全菜工程師小輝~

前幾天筆者發(fā)布了博客,手寫mybatis徹底搞懂框架原理。為了幫助初學(xué)者更好理解mybatis框架,這次講解一下JAVA的JDBC的運(yùn)行過程。

JDBC的作用

JDBC的全稱是Java DataBase Connection,也就是Java數(shù)據(jù)庫連接,我們可以用它來操作關(guān)系型數(shù)據(jù)庫。JDBC接口及相關(guān)類在java.sql包和javax.sql包里。我們可以用它來連接數(shù)據(jù)庫,執(zhí)行SQL查詢,存儲過程,并處理返回的結(jié)果。

JDBC接口讓Java程序和JDBC驅(qū)動實(shí)現(xiàn)了松耦合,使得切換不同的數(shù)據(jù)庫變得更加簡單。

 

徹底搞懂JDBC的運(yùn)行過程

 

 

JDBC

JDBC的連接步驟

執(zhí)行一次JDBC連接,分六個步驟進(jìn)行:

1. 導(dǎo)入包

在程序中包含數(shù)據(jù)庫編程所需的JDBC類。大多數(shù)情況下,使用 import java.sql.* 就足夠了

2. 注冊JDBC驅(qū)動程序

需要初始化驅(qū)動程序,這樣就可以打開與數(shù)據(jù)庫的通信。

3. 打開一個連接

使用DriverManager.getConnection()方法來創(chuàng)建一個Connection對象,它代表一個數(shù)據(jù)庫的物理連接。

4. 執(zhí)行一個查詢

需要使用一個類型為Statement或PreparedStatement的對象(兩者區(qū)別看后文),并提交一個SQL語句到數(shù)據(jù)庫執(zhí)行查詢。

5. 從結(jié)果集中提取數(shù)據(jù)

這一步中演示如何從數(shù)據(jù)庫中獲取查詢結(jié)果的數(shù)據(jù)。使用ResultSet.getXXX()方法來檢索的數(shù)據(jù)結(jié)果

6. 清理環(huán)境資源

在使用JDBC與數(shù)據(jù)交互操作數(shù)據(jù)庫中的數(shù)據(jù)后,應(yīng)該明確地關(guān)閉所有的數(shù)據(jù)庫資源以減少資源的浪費(fèi)。本文使用了try with resources方式關(guān)閉資源,這是JDK7的語法糖,讀者可自行搜索。

完整代碼如下。

//STEP 1. 導(dǎo)入包
import java.sql.*;
class JDBCExample {
 // JDBC驅(qū)動包名和數(shù)據(jù)庫的URL
 static final String JDBC_DRIVER = "com.MySQL.jdbc.Driver";
 static final String DB_URL = "jdbc:mysql://localhost/test";
 // 數(shù)據(jù)庫名和密碼自己修改
 static final String USER = "username";
 static final String PASS = "password";
 public static void main(String[] args) {
 String sql = "SELECT id, first, last, age FROM Employees";
 //STEP 2: 注冊JDBC驅(qū)動程序
 try {
 Class.forName(JDBC_DRIVER);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 // try with resources方式關(guān)閉資源。
 //STEP 6: 清理環(huán)境資源
 try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
 Statement stmt = conn.createStatement();
 ResultSet rs = stmt.executeQuery(sql)) {
 //STEP 3: 打開一個連接
 System.out.println("Connecting to database...");
// Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
 //STEP 4: 執(zhí)行一個查詢
 System.out.println("Creating statement...");
// Statement stmt = conn.createStatement();
// ResultSet rs = stmt.executeQuery(sql);
 //STEP 5: 從結(jié)果集中提取數(shù)據(jù)
 while (rs.next()) {
 // 根據(jù)列名獲取數(shù)據(jù)
 int id = rs.getInt("id");
 int age = rs.getInt("age");
 String first = rs.getString("first");
 String last = rs.getString("last");
 // 顯示結(jié)果
 System.out.print("ID: " + id);
 System.out.print(", Age: " + age);
 System.out.print(", First: " + first);
 System.out.println(", Last: " + last);
 }
 } catch (SQLException se) {
 // 處理可能出現(xiàn)的錯誤
 se.printStackTrace();
 }
 System.out.println("Goodbye!");
 }
}

JDBC的最佳實(shí)踐

  • 數(shù)據(jù)庫資源是非常昂貴的,用完了應(yīng)該盡快關(guān)閉它。Connection, Statement, ResultSet等JDBC對象都有close方法,調(diào)用它就好了。
  • 在代碼中必須顯式關(guān)閉掉ResultSet,Statement,Connection,如果你用的是連接池的話,連接用完后會放回池里,但是沒有關(guān)閉的ResultSet和Statement就會造成資源泄漏了。
  • 在finally塊中關(guān)閉資源,保證即便出了異常也能正常關(guān)閉。
  • 大量相似的查詢應(yīng)當(dāng)使用批處理完成。
  • 盡量使用PreparedStatement而不是Statement,以避免SQL注入,同時還能通過預(yù)編譯和緩存機(jī)制提升執(zhí)行的效率。
  • 如果你要將大量數(shù)據(jù)讀入到ResultSet中,應(yīng)該合理的設(shè)置fetchSize以便提升性能。
  • 你用的數(shù)據(jù)庫可能沒有支持所有的隔離級別,用之前先仔細(xì)確認(rèn)下。
  • 數(shù)據(jù)庫隔離級別越高性能越差,確保你的數(shù)據(jù)庫連接設(shè)置的隔離級別是最優(yōu)的。
  • 如果你需要長時間對ResultSet進(jìn)行操作的話,盡量使用離線的RowSet。

FAQ

JDBC是如何實(shí)現(xiàn)Java程序和JDBC驅(qū)動的松耦合?

JDBC API使用Java的反射機(jī)制來實(shí)現(xiàn)Java程序和JDBC驅(qū)動的松耦合。看一下上文的JDBC示例,你會發(fā)現(xiàn)所有操作都是通過JDBC接口完成的,而驅(qū)動只有在通過Class.forName反射機(jī)制來加載的時候才會出現(xiàn)。

這是Java核心庫里反射機(jī)制的最佳實(shí)踐之一,它使得應(yīng)用程序和驅(qū)動程序之間進(jìn)行了隔離,讓遷移數(shù)據(jù)庫的工作變得更簡單。

Statement和PreparedStatement區(qū)別

  • 關(guān)系:PreparedStatement繼承自Statement,兩者都是接口
  • 區(qū)別:PreparedStatement可以使用占位符,而且是預(yù)編譯的,批處理比Statement效率高

預(yù)編譯

創(chuàng)建時的區(qū)別:

Statement statement = conn.createStatement();
PreparedStatement preStatement = conn.prepareStatement(sql);

執(zhí)行時的區(qū)別:

ResultSet rSet = statement.executeQuery(sql);
ResultSet pSet = preStatement.executeQuery();

由上可以看出,PreparedStatement有預(yù)編譯的過程,已經(jīng)綁定sql,之后無論執(zhí)行多少次,都不會再去進(jìn)行編譯,而Statement 不同,如果執(zhí)行多次,則相應(yīng)的就要編譯多少次sql,所以從這點(diǎn)看,PreparedStatement的效率會比Statement要高一些。PreparedStatement是預(yù)編譯的,所以可以有效的防止SQL注入等問題

占位符

PrepareStatement可以替換變量在SQL語句中可以包含?,可以用?替換成變量。

ps = conn.prepareStatement("select * from Employees where id=?");
int sid = 1001;
ps.setInt(1, sid);
rs = ps.executeQuery();

而Statement只能用字符串拼接。

int sid = 1001;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from Employees where id=" + sid);

JDBC的ResultSet

在查詢數(shù)據(jù)庫后會返回一個ResultSet,它就像是查詢結(jié)果集的一張數(shù)據(jù)表。

ResultSet對象維護(hù)了一個游標(biāo),指向當(dāng)前的數(shù)據(jù)行。開始的時候這個游標(biāo)指向的是第一行。如果調(diào)用了ResultSet的next()方法游標(biāo)會下移一行,如果沒有更多的數(shù)據(jù)了,next()方法會返回false。可以在for循環(huán)中用它來遍歷數(shù)據(jù)集。

默認(rèn)的ResultSet是不能更新的,游標(biāo)也只能往下移。也就是說你只能從第一行到最后一行遍歷一遍。不過也可以創(chuàng)建可以回滾或者可更新的ResultSet,像下面這樣。

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

當(dāng)生成ResultSet的Statement對象要關(guān)閉或者重新執(zhí)行或是獲取下一個ResultSet的時候,ResultSet對象也會自動關(guān)閉。

可以通過ResultSet的getter方法,傳入列名或者從1開始的序號來獲取列數(shù)據(jù)。

ResultSet的不同類型

根據(jù)創(chuàng)建Statement時輸入?yún)?shù)的不同,會對應(yīng)不同類型的ResultSet。如果你看下Connection的方法,你會發(fā)現(xiàn)createStatement和prepareStatement方法重載了,以支持不同的ResultSet和并發(fā)類型。

ResultSet對象有三種類型。

  1. ResultSet.TYPE_FORWARD_ONLY:這是默認(rèn)的類型,它的游標(biāo)只能往下移。
  2. ResultSet.TYPE_SCROLL_INSENSITIVE:游標(biāo)可以上下移動,一旦它創(chuàng)建后,數(shù)據(jù)庫里的數(shù)據(jù)再發(fā)生修改,對它來說是透明的。
  3. ResultSet.TYPE_SCROLL_SENSITIVE:游標(biāo)可以上下移動,如果生成后數(shù)據(jù)庫還發(fā)生了修改操作,它是能夠感知到的。

ResultSet有兩種并發(fā)類型。

  1. ResultSet.CONCUR_READ_ONLY:ResultSet是只讀的,這是默認(rèn)類型。
  2. ResultSet.CONCUR_UPDATABLE:我們可以使用ResultSet的更新方法來更新里面的數(shù)據(jù)。

更多內(nèi)容,歡迎關(guān)注微信公眾號:全菜工程師小輝~

分享到:
標(biāo)簽:JDBC
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定