一、引言
1、數據的存儲
開發java程序的時候,數據都是存儲在內存中,屬于臨時存儲,當程序停止或重啟時,內存中的數據就丟失了。為了解決數據的長期存儲問題,有如下解決方案:
1、數據通過I/O流技術,存儲在本地磁盤中,解決了持久化問題,但是沒有結構和邏輯,不方便管理和維護。
2、通過關系型數據庫,將數據按照特定的格式交由數據庫管理系統維護。關系型數據庫是通過庫和表分隔不同的數據,表中存儲的方式是行和列,區分相同格式不同值的數據
2、數據的操作
通過jdbc使用java程序對數據庫進行(CRUD)操作
二、JDBC
1、概念
1、JDBC:Java DataBase Connectivity,意為java數據庫連接
2、JDBC是java提供的一組獨立于任何數據庫管理系統的API
3、Java提供接口規范,由各個數據庫廠商提供接口的實現,廠商提供的實現類封裝成jar文件,也就是我們俗稱的數據庫驅動jar包
4、學習JDBC,充分體現了面向接口編程的好處,程序員只關心標準和規范,而無需關注實現過程?
2、JDBC的核心組成
接口規范:
1、為了項目代碼的可移植性、可維護性,制定了Java程序連接各種數據庫的統一接口規范。這樣的話,不管是連接哪一種DBMS軟件,Java代碼可以保持一致性。
2、接口存儲在java.sql和javax.sql包下
實現規范:
1、接口規范交由各個數據庫廠商實現
2、將實現內容封裝成jar文件,我們只需引入即可
三、JDBC快速入門
1、JDBC搭建步驟
1、準備數據庫
2、官網下載數據庫連接驅動jar包(使用mavan,不需下載)
3、創建Java項目,在項目下創建lib文件夾,將下載的驅動jar包復制到文件夾里
4、選中lib文件夾右鍵->Add as Library,與項目集成
5、編寫代碼
2、代碼實現
1、以下為示例數據庫的sql文件代碼
-- 圖書管理系統數據庫(簡化版)
CREATE DATABASE IF NOT EXISTS library_management;
USE library_management;-- 圖書表
CREATE TABLE books (id INT PRIMARY KEY AUTO_INCREMENT,title VARCHAR(255) NOT NULL,author VARCHAR(100) NOT NULL,publisher VARCHAR(100) NOT NULL,publish_year YEAR NOT NULL,isbn VARCHAR(20) UNIQUE NOT NULL,category VARCHAR(50) NOT NULL,total_copies INT NOT NULL DEFAULT 1,available_copies INT NOT NULL DEFAULT 1,location VARCHAR(50) NOT NULL -- 書架位置
);-- 插入圖書假數據
INSERT INTO books (title, author, publisher, publish_year, isbn, category, total_copies, available_copies, location) VALUES
('Python編程:從入門到實踐', '埃里克·馬瑟斯', '人民郵電出版社', 2016, '9787115428028', '編程', 5, 5, 'A區-1架'),
('數據結構與算法分析', '馬克·艾倫·維斯', '機械工業出版社', 2019, '9787111641247', '計算機', 3, 3, 'A區-2架'),
('紅樓夢', '曹雪芹', '人民文學出版社', 2018, '9787020002207', '文學', 4, 4, 'B區-1架'),
('三國演義', '羅貫中', '人民文學出版社', 2015, '9787020090008', '文學', 6, 6, 'B區-1架'),
('算法導論', '托馬斯·H·科爾曼', '機械工業出版社', 2013, '9787111407010', '計算機', 2, 2, 'A區-3架'),
('人類簡史', '尤瓦爾·赫拉利', '中信出版社', 2017, '9787508647357', '歷史', 5, 5, 'C區-2架'),
('活著', '余華', '作家出版社', 2012, '9787506365437', '文學', 8, 8, 'B區-2架'),
('數學之美', '吳軍', '人民郵電出版社', 2014, '9787115379320', '數學', 3, 3, 'D區-1架'),
('解憂雜貨店', '東野圭吾', '南海出版公司', 2014, '9787544270878', '小說', 7, 7, 'B區-3架'),
('三體', '劉慈欣', '重慶出版社', 2008, '9787536692930', '科幻', 10, 10, 'E區-1架');
2、以下為java程序的實現,由于使用maven進行管理,無需導包等操作,只需要在pom.xml中添加依賴即可
package org.lib_mana;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class quickSQL {public static void main(String[] args) throws Exception {
// 1、注冊驅動(由于使用maven進行管理則省去該步驟0// 2、獲取連接對象
// 這是url的固定結構String url = "jdbc:mysql://localhost:3306/library_management";String username = "root";String password = "20050824";Connection connection = DriverManager.getConnection(url, username, password);// 3、獲取執行sql語句的對象Statement statement = connection.createStatement();// 4、編寫sql語句并執行ResultSet resultSet = statement.executeQuery("select id,title,author,isbn,location from books");while (resultSet.next()) {int id = resultSet.getInt("id");String title = resultSet.getString("title");String author = resultSet.getString("author");String isbn = resultSet.getString("isbn");String location = resultSet.getString("location");System.out.println(id+","+title+","+author+","+isbn+","+location);}// 5、釋放資源resultSet.close();statement.close();connection.close();}
}
四、核心API理解
1、注冊驅動
Class.forName("com.mysql.cj.jdbc.Driver");
在Java中,當使用JDBC連接數據庫時,需要加載數據庫特定的驅動程序,以便與數據庫進行通信
從JDK6開始,不需要顯式地調用Class.forName()來加載JDBC驅動程序,只要在類路徑中集成了對應的jar文件,會自動在初始化時注冊驅動程序
2、Connection
1、Connection接口是JDBC API的重要接口,用于建立與數據庫的通信通道。換而言之,Connection對象不為空,則代表一次數據庫連接
2、在建立連接時,需要指定數據庫URL、用戶名、密碼參數
URL:jdbc:mysql://localhost:3306/atguigu
jdbc:mysql://IP地址:端口號/數據庫名?參數鍵值對1&參數鍵值對2
3、Connection接口還負責管理事務,接口提供了commit和rollback方法,用于提交事務和回滾事務
4、可以創建Statement對象,用于執行SQL語句并與數據庫進行交互
5、在使用JDBC技術時,必須要先獲取Connection對象,并且最后需要釋放資源
3、Statement
1、Statement接口用于執行SQL語句并與數據庫進行交互。它是JDBC API中一個重要接口。通過Statement對象,可以向數據庫發送SQL語句并執行結果
2、結果可以是一個或多個結果
增刪改:受影響行數單個結果
查詢:單行單列、多行多列、單行多列結果
3、但是Statement接口在執行SQL語句時會產生SQL注入攻擊問題:
當使用Statement執行動態構建的SQL查詢時,往往需要將查詢條件與SQL語句拼接在一起,直接將參數和SQL語句一并生成,讓SQL的查詢條件始終為true得到結果
4、PreparedStatement
1、preparedStatement是Statement接口的子接口,用于執行預編譯的SQL查詢,作用如下:
預編譯的SQL語句:在創建PreparedStatement時,就會預編譯SQL語句,也就是SQL語句以及固定
防止SQL注入:PreparedStatement支持參數化查詢,將數據作為參數傳遞到SQL語句中,采用?占位符的方式。將傳入的參數用一對單引號包裹起來,無論傳遞什么都作為值,有效防止傳入關鍵字或值導致SQL注入問題
性能提升:PreparedStatement是預編譯SQL語句,同一SQL語句多次執行的情況下,可以復用,不必每次重新編譯和解析
2、后續的學習我們都是基于PreparedStatement進行實現,更安全,效率更高!
以下為示例代碼:
package org.lib_mana;import java.sql.*;
import java.util.Scanner;public class quickSQL {public static void main(String[] args) throws Exception {
// 1、注冊驅動(由于使用maven進行管理則省去該步驟0// 2、獲取連接對象
// 這是url的固定結構String url = "jdbc:mysql://localhost:3306/library_management";String username = "root";String password = "20050824";Connection connection = DriverManager.getConnection(url, username, password);// 3、獲取執行sql語句的對象String sql = "select * from books where id= ?";PreparedStatement statement = connection.prepareStatement(sql);// 4、編寫sql語句并執行Scanner input = new Scanner(System.in);String book_id = input.nextLine();statement.setString(1,book_id);System.out.println(sql);ResultSet resultSet = statement.executeQuery();while (resultSet.next()) {int id = resultSet.getInt("id");String title = resultSet.getString("title");String author = resultSet.getString("author");String isbn = resultSet.getString("isbn");String location = resultSet.getString("location");System.out.println(id+","+title+","+author+","+isbn+","+location);}// 5、釋放資源resultSet.close();statement.close();connection.close();}
}
此時輸入的任何的值都會被解析為值,防止被sql注入
5、ResultSet
1、ResultSet是JDBC API中的一個接口,用于表示從數據庫中執行查詢語句所返回的結果集。它提供了一種用于遍歷和訪問查詢結果的方式
2、遍歷結果:ResultSet可以使用next()方法將游標移動到結果集的下一行,逐行遍歷數據庫查詢的結果,返回值為boolean類型,true代表有下一行,false則代表沒有
3、獲取單列結果:可以通過getXxx的方法獲取單列的數據,該方法為重載方法,支持索引和列名進行獲取