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

是啊超ya 發佈 2024-03-27T00:29:00.929547+00:00

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

前言

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

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)或者是其他任意的持久化框架。

關鍵字: