天天看點

一文快速回顧 Java 操作資料庫的方式-JDBC

作者:是啊超ya
一文快速回顧 Java 操作資料庫的方式-JDBC

前言

資料庫的重要性不言而喻,不管是什麼系統,什麼應用軟體,也不管它們是 Windows 上的應用程式,還是 Web 應用程式,存儲(持久化)和查詢(檢索)資料都是核心的功能。

大家學習資料庫時,比如 MySQL 這個資料庫管理系統,都是在 CLI(Command Line Interface)上操作資料庫的,現在,我們看看,在 Java Web 中,我們如何使用 Java 去操作資料庫。

JDBC

JDBC(Java Data Base Connectivity)是 Java 操作資料庫的一種規範,也是一種 API(與資料庫系統進行通信的标準的 API),更是一門技術。

JDBC 是由一組用 Java 編寫的類和接口組成,對資料庫的操作提供了基本的方法。但是,對于資料庫細節的操作,那就是由資料庫的廠商實作的。使用 JDBC 操作資料庫,需要資料庫廠商提供的資料庫驅動程式的支援。

那什麼是資料庫驅動程式呢?這個驅動(driver)可以了解成一種可以讓資料庫和 Java 彼此進行互動的程式。

簡單來講,JDBC 提供了一種 API 的規範,告訴各大資料庫廠商按這種規範來實作這些 API 具體的實作代碼。可以從兩個角色的角度來說這個 JDBC。從咱們開發人員的角度來說,JDBC 為我們開發人員提供了統一的操作資料庫的 API,不用管這些 API 的具體實作,專注于 API 的調用;從資料庫廠商的角度來說,JDBC 為他們提供了一套标準的模型接口,都按這個接口去做自己的實作。

如何使用 JDBC?

JDBC 的使用主要有如下幾個步驟:

1.注冊資料庫驅動程式(database driver program)到 JDBC 的驅動管理器中。

在連接配接資料庫之前,需要将資料庫廠商提供的資料庫驅動類注冊到 JDBC 的驅動管理器中,一般是把驅動類加載到 JVM 實作的。

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

2.建構資料庫連接配接的 URL。

要與資料庫建立連接配接,那麼就需要建構資料庫連接配接的 URL,這個 URL 由資料庫廠商指定,一般符合一種基本格式,即 JDBC協定+IP位址或域名+端口+資料庫名稱。MySQL 的 URL 是 jdbc:mysql://localhost:3306/dbname

3.擷取連接配接對象(Connection 對象)。

String url = "jdbc:mysql://localhost:3306/dbname";
String username = "root";
String password = "123456";
// Connection 對象的擷取需要借助 DriverManager 對象
Connection conn = DriverManager.getConnection(url, username, password);
           

4.進行資料庫操作。

編寫 SQL,然後擷取 PreparedStatement 對象,對 SQL 語句進行執行。SQL 語句的參數是可以使用占位符 “?” 代替,再通過 PreparedStatement 對象對 SQL 語句中的占位符進行指派。

Statment 這個單詞的意思在這裡指的就是 SQL 語句。
// 編寫SQL
String sql = "INSERT INTO tb_game(name, price, platform) values(?, ?, ?)";
// 擷取 PreparedStatement 對象
PreparedStatement ps = conn.preparedStatement(sql);
// 給占位符指派
ps.setString(1, "NBA2K");
ps.setDouble(2, 198.0);
ps.setString(3, "Windows");
// 執行 SQL,将這條資料寫入資料庫,傳回影響的行數
int row = ps.executeUpdate();
           
使用 PreparedStatement 對象對 SQL 語句的占位符參數指派,其參數的下标是從 1 開始的。

5.關閉連接配接

conn.close();
           

CRUD

新增操作

新增操作,就是上面的插入操作,請看上面。

查詢操作

ResultSet

使用 JDBC 查詢資料,與插入資料的操作流程基本一樣,但是執行查詢操作後需要通過一個對象來接收查詢的結果,這個對象就是 ResultSet (結果集)。

ResultSet 是 JDBC API 中封裝的對象,從資料表中查到的所有記錄都會放在這個集合中。ResultSet 中維護着一個 cursor(遊标)來指向目前的資料行(資料記錄),初始化的時候,這個遊标指向第一行的前一行,可以通過 next() 方法來移動遊标,讓遊标指向下一行。

調用這個 next() 它傳回的是一個布爾值,為 true 說明 ResultSet 中還有下一行的資料,為 false 說明沒有,是以可以結合 while 循環使用這個方法來周遊整個 ResultSet。

// 由于一開始的遊标在第一行的前一行,是以執行 next() 後,遊标就指向第一行的資料了
while (resultSet.next()) {
    // 處理結果集中每一行的資料
}
           

擷取到 ResultSet 對象後,移動了光标指定了資料行,然後通過 ResultSet 對象提供的一系列 getXxxx() 方法來擷取目前行的資料,比如 resultSet.getInt("price") 擷取目前行中字段名為 price 的資料。

預設的 ResultSet 是不可更新的,同時它的遊标隻能一步一步 next 下去,隻能走一遍,不能回到上一行的。說了預設,那說明是可以設定的,通過如下代碼進行設定:

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
// rs 是可以滾動的,也就是遊标走到最後又會回到開頭繼續走,并且它的内容是可以被改變的
           

查詢

找到價格大于50塊錢的所有遊戲:

String sql = "SELECT id, name, price FROM tb_game WHERE price > ?";
PreparedStatement ps = conn.preparedStatement(sql);
ps.setDouble(1, 50);
// 執行查詢
ResultSet rs = ps.executeQuery(sql);
List<Game> gameList = new ArrayList<>();
// 周遊結果集
while (rs.next()) {
    Game game = new Game();
    // 擷取目前行中字段名為 id 的資料,并指派到 game 對象中
    game.setId(rs.getInt("id"));
    game.setName(rs.getString("name"));
    game.setPrice(rs.getDouble("price"));
    gameList.add(game);
}
System.out.println(gameList);
           

修改(更新)操作

修改(更新)資料的操作,也是和插入資料的操作是類似的。

更新 ID 為 3 的資料記錄,修改其價格為 298 塊錢。

String sql = "UPDATE tb_game SET price = ? WHERE id = ?";
PreparedStatement ps = conn.preparedStatement(sql);
ps.setDouble(1, 298);
ps.setInt(2, 3);
int row = ps.executeUpdate();
           

删除操作

同理。

String sql = "DELETE FROM tb_game WHERE id = ?";
PreparedStatement ps = conn.preparedStatement(sql);
ps.setInt(1, 1);
int row = ps.executeUpdate();
           

分頁查詢

在 Java Web 中資料量非常大的情況下,是不利于将所有資料都展示到一個頁面中的,檢視不友善,又占用系統資源。此時就需要對資料進行分頁查詢,同時,以後的工作中,可以說大部分的業務場景都會涉及到分頁查詢。

在 MySQL 中,分頁可以通過其自身的 LIMIT 關鍵字來實作:

SELECT *
FROM tb_game
WHERE price > 50
ORDER BY price DESC
LIMIT 0, 10; // 從表中下标0開始(第一行的下标為0),限制傳回10條記錄
           

目前分頁涉及到這樣的兩個參數:目前頁碼和頁面大小。

涉及的 SQL 語句:SELECT * FROM tb_game WHERE price > 50 ORDER BY price DESC LIMIT 目前頁碼, 頁面大小

// 分頁參數
int currentPage = 1, pageSize = 10;
// 分頁 SQL
String sql = "SELECT * FROM tb_game WHERE price > 50 ORDER BY price DESC LIMIT ?, ?";
PreparedStatement ps = conn.preparedStatement(sql);
// 指派
ps.setInt(1, (page - 1) * pageSize);
ps.setInt(2, pageSize);
ResultSet rs = ps.executeQuery();
           

與此同時,還需要計算擷取的資料的總記錄數,用于計算分頁的總頁數,便于前端傳遞是要哪一頁的資料給後端。

int count = 0;
String sql = "SELECT COUNT(*) FROM tb_game WHERE price > 50";
PreparedStatement ps = conn.preparedStatement(sql);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
    // 擷取總記錄數,getInt(1) 是擷取第一列的資料
    count = rs.getInt(1);
}
           

總結

目前在 Java 中通過 JDBC 來操作資料庫,就有幾個固定的步驟,先加載資料庫驅動程式,接着擷取資料庫的連接配接,有了這個連接配接後,才能進行 CRUD 的操作,操作後也可以擷取操作的結果,最後關閉這些資源,比如資料庫連接配接。

不過,在日常的開發中,基本不會用到原生的 JDBC 來操作資料庫,一般我們有多種選擇,可以使用 JdbcTemplate、Hibernate、MyBatis、JPA(Java Persistence API,Java 持久化 API)或者是其他任意的持久化架構。

繼續閱讀