資料庫的重要性不言而喻,不管是什麼系統,什麼應用軟體,也不管它們是 Windows 上的應用程式,還是 Web 應用程式,存儲(持久化)和查詢(檢索)數據都是核心的功能。 大家學習資料庫時,比如 MySQL 這個資料庫管理系統,都是在 CLI(Command Line Interface)上操作數據... ...
前言
資料庫的重要性不言而喻,不管是什麼系統,什麼應用軟體,也不管它們是 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 的使用主要有如下幾個步驟:
- 註冊資料庫驅動程式(database driver program)到 JDBC 的驅動管理器中。
在連接資料庫之前,需要將資料庫廠商提供的資料庫驅動類註冊到 JDBC 的驅動管理器中,一般是把驅動類載入到 JVM 實現的。
Class.forName("com.mysql.jdbc.Driver");
- 構建資料庫連接的 URL。
要與資料庫建立連接,那麼就需要構建資料庫連接的 URL,這個 URL 由資料庫廠商指定,一般符合一種基本格式,即 JDBC協議+IP地址或功能變數名稱+埠+資料庫名稱
。MySQL 的 URL 是 jdbc:mysql://localhost:3306/dbname
- 獲取連接對象(Connection 對象)。
String url = "jdbc:mysql://localhost:3306/dbname";
String username = "root";
String password = "123456";
// Connection 對象的獲取需要藉助 DriverManager 對象
Connection conn = DriverManager.getConnection(url, username, password);
- 進行資料庫操作。
編寫 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 開始的。
- 關閉連接
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)或者是其他任意的持久化框架。
最後的最後
由本人水平所限,難免有錯誤以及不足之處, 屏幕前的靚仔靚女們
如有發現,懇請指出!
最後,謝謝你看到這裡,謝謝你認真對待我的努力,希望這篇博客對你有所幫助!
你輕輕地點了個贊,那將在我的心裡世界增添一顆明亮而耀眼的星!