JDBC編程
- 一、概述
- 1.1 概念介紹
- 1.2 驅動包下載
- 1.3 導入驅動包
- 二、通過Java程序操作數據庫
- 2.1 通過 JDBC 進行 插入數據 操作
- 2.1.1 創建“數據源(DataSource)——描述要操作的數據庫、數據是在哪”
- 2.1.2 與服務器建立連接
- 2.1.3 構造sql語句,并且對字符串類型的sql進行識別和編譯
- 2.1.4 將編譯好的sql語句傳給服務器,并且執行sql
- 2.1.5 釋放前面占用的各種資源
- 2.1.6 完整代碼
- 2.2 通過 JDBC 進行 查詢數據 操作
一、概述
1.1 概念介紹
- JDBC:Java Databases Connectivity——Java語言連接數據庫
- Java通過JDBC這樣的技術連接MySQL數據庫,MySQL是一個基于C/C++實現的數據庫,本身也提供了一系列的API,從而可以通過代碼操作數據庫
- API: Application Programming Interface——應用程序編程接口,這是一個通用的概念,不僅僅局限于Java當中;可以把這個詞理解為“一組類”/“一組方法”,都是現成的,可以直接調用實現一些功能;對于Java來說,Java提供了“標準庫”,只要安裝了Java,此時就能使用標準庫中的類和方法(標準庫API),也可以使用別人寫的類和方法(第三方API);有的庫,提供的API非常多,形成了一系列體系.這種情況也可以稱為“SDK”(軟件開發工具包)——Software development kit;Java中用到的JDK就是一個SDK,只不過起了個專屬的名字Java開發工具包
- 不同數據庫提供的API不同(功能上大同小異,細節上存在很大差異),那么在項目中使用到不同的數據庫時,就需要掌握多分api的使用,非常麻煩,這時候Java出版了一套API接口標準,使他們都按照該標準適配過來(每個數據庫廠商只需要額外寫一些代碼,能夠按照Java提供的標準把原有的API封裝一下),后續僅需掌握Java這一套API(JDBC),就可以切換各種數據庫了,如下圖:
- JDBC是Java標準庫提供的,只要裝了JDK就自帶JDBC,但是使用JDBC操作MySQL需要安裝并導入MySQL的驅動包(數據庫驅動)
1.2 驅動包下載
中央倉庫:https://mvnrepository.com/
-
搜索MySQL
-
找到與MySQL對應的版本(只要大版本相同即可,比如我的MySQL版本是8.0.34,驅動包只要是8開頭的版本都行)
如果你的MySQL是比較新的就點擊新版本,否則就點擊舊版本
在central中查看版本
- 選擇版本后,點擊jar下載即可
.jar文件就是類似于.rar文件的壓縮包,是最常見的一種發布Java程序方式,其中包含了很多的.class(Java編譯生成的字節碼文件)文件
或者在項目中配置pom文件,使用maven下載
1.3 導入驅動包
這里我使用的是IDEA編譯器
- 創建一個Java項目
- 在項目中隨便創建一個目錄
- 把jar文件拷貝到剛剛創建的目錄(lib)中,
- 右鍵目錄,選擇Add as library
告訴IDEA,這個目錄存放的是第三方庫,此時IDEA就能識別拷貝進來的驅動包了
添加完上述,可以看到這個jar文件可以展開了,說明能被識別
上述操作是JDBC程序的準備操作,接下來就可以寫代碼了
二、通過Java程序操作數據庫
2.1 通過 JDBC 進行 插入數據 操作
先在數據庫新建一張表,雖然通過JDBC也能進行建表操作,一般都是提前建好表的
接下來準備往people這張表來插入數據
2.1.1 創建“數據源(DataSource)——描述要操作的數據庫、數據是在哪”
在MySQL中,要設定好MySQL服務器的位置,訪問數據庫的用戶名、用戶密碼以及數據庫名
以上要包含的是JDBC自帶的interface(接口),而接口是不能直接new的,所以需要new一個實現該接口的類的實例
因為需要操作MySQL數據庫,所以new一個MySQL提供的類MysqlDataSource,這就是MySQL廠商提供的驅動包里面的類,需要包含信息
//向上轉型
DataSource dataSource = new MysqlDataSource();
以上過程就是數據庫廠商(MySQL)和JDBC進行對接,就是讓數據庫廠商實現JDBC中提供的接口,進一步的實現其中約定好的抽象方法
//向下轉型,并且設置url
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
Url:唯一資源定位符;MySQL是一個 客戶端—服務器 的程序,服務器是保存數據的本體,當前寫的 jdbc 代碼,就是在寫一個 mysql 客戶端;之前的cmd黑框是MySQL自帶的客戶端,這里可以通過Java代碼通過JDBC自己實現客戶端,然后客戶端通過網絡訪問到數據庫服務器(不是cmd黑框啟動的那個),才能進一步的進行數據庫操作;要想訪問服務器,就需要知道服務器所在位置,這里的Url就是描述服務器以及服務器上的資源在網絡上所在的位置,
其中jdbc:mysql:
代表給jdbc中的MySQL使用的url,127.0.0.1
代表ip地址(描述的是一個主機/電腦在網絡上的位置,這里本地ip默認為127.0.0.1),3306
端口號(區分了主機上的應用程序,這里是MySQL默認的端口號),learn_db
為即將要操作的數據庫的名字,characterEncoding=utf8
表示指定字符集為utf8,useSSl=false
表示關閉加密通信,不寫的話可能會由于依賴程序有問題導致數據庫連接失敗,serverTimezone=Asia/Shanghai
表示配置數據庫時間,確保其正確
除了設置Url之外,還需要設置用戶名和密碼
((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");
其中root為默認用戶名,密碼為123456
DataSource需要對接不同的數據庫,對于MySQL來說,設置的為url,user,password;對于其他數據庫就不一定了,所以需要向下轉型為MysqlDataSource
2.1.2 與服務器建立連接
進行 客戶端—服務器 之間通信的時候,一般兩種通信模式:
(1)有連接 (類似于打電話,對方必須接通才能進行通話)
(2)無連接 (類似于發短信,不需要對方操作,直接可以發送成功)
這里的JDBC就屬于“有連接”的這種模式,則需要先進行“撥號”——dataSource.getConnection();
寫完之后,發現報錯了,這里查看信息后發現沒有處理異常,這里使用throws關鍵字顯式處理該受查異常
處理后就不報錯了
下面使用Connection(選擇java.sql包中的Connection)來進行接收
Connection connection= dataSource.getConnection();
做到這一步后,如果能夠編譯成功說明可以與MySQL服務器進行連接了,后面就可以寫sql語句了
2.1.3 構造sql語句,并且對字符串類型的sql進行識別和編譯
雖然是通過Java來操作數據庫,但是核心還是需要通過執行sql語句來操作數據庫,只不過是把sql嵌入Java中了
String sql = "insert into people values(1,'小明')";
預編譯sql語句
以上是字符串結構的sql語句,還需要構造語句對象,使JDBC能夠識別
有兩種方法:使用Statement或者PrepareStatement
其中Statement是一個普通的語句對象,而PrepareStatement則是帶有預編譯(一個字符串sql發送到MySQL服務器上,是要先對sql進行解析,然后進行各種校驗,之后才能執行——這個操作需要花費一定開銷的,雖然開銷不大,但是MySQL服務器要同時給多個客戶端提供服務,為了減輕服務器的負擔,這里現在客戶端預編譯好,把解析后的數據交給服務器,服務器可以立即執行) 功能的語句對象;
所以下面推薦使用PrepareStatement
PreparedStatement preparedStatement = connection.prepareStatement(sql);
2.1.4 將編譯好的sql語句傳給服務器,并且執行sql
對于insert、update、delete(對數據庫進行改動的操作)都是使用executeUpdate方法
對于select則是使用executeQuery方法
int n = preparedStatement.executeUpdate(); //返回結果為整數,表示當前操作影響到了幾行數據System.out.println("n="+n); //查看影響行數
執行這個方法,就在內部會向服務器發送請求,請求中就是包含了解析后的sql語句
等待數據庫執行sql;執行完成就會返回響應,這個方法再獲取到響應,并且把數據庫返回的結果通過返回值體現出來
2.1.5 釋放前面占用的各種資源
注意:釋放 語句對象 和 連接對象 dataSource不必釋放
釋放順序和創建順序相反
preparedStatement.close();connection.close();
完成以上操作就可以運行代碼了,運行前,people表中數據為空
運行后,n=1說明1行受影響
再次查詢people表后發現數據添加成功
2.1.6 完整代碼
import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;public class JDBCDemo {public static void main(String[] args) throws SQLException {//接下來通過 JDBC 進行一個簡單的插入數據的操作//JDBC 步驟比較多,每個步驟都不難,都是固定討論//1.創建“數據源(DataSource)DataSource dataSource = new MysqlDataSource(); //向上轉型//向下轉型((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");//2. 和MySQL服務器建立連接Connection connection= dataSource.getConnection();//3.構造sql語句,并且對字符串類型的sql進行識別和編譯(PrepareStatement才能編譯,Statement不能編譯)String sql = "insert into people values(1,'小明')";PreparedStatement preparedStatement = connection.prepareStatement(sql);//4. 將編譯好的sql語句傳給服務器,并且執行sqlint n = preparedStatement.executeUpdate(); //返回結果為整數,表示當前操作影響到了幾行數據System.out.println("n="+n);//5. 釋放前面占用的各種資源preparedStatement.close();connection.close();}
}
手動輸入的代碼:
import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;public class JDBCDemo {public static void main(String[] args) throws SQLException {//接下來通過 JDBC 進行一個簡單的插入數據的操作//JDBC 步驟比較多,每個步驟都不難,都是固定討論//1.創建“數據源(DataSource)DataSource dataSource = new MysqlDataSource(); //向上轉型//向下轉型((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");//2. 和MySQL服務器建立連接Connection connection= dataSource.getConnection();//手動輸入信息System.out.println("請輸入id");Scanner scanner = new Scanner(System.in);int id = scanner.nextInt();System.out.println("請輸入姓名");String name = scanner.next();//3.構造sql語句,并且對字符串類型的sql進行識別和編譯(PrepareStatement才能編譯,Statement不能編譯)String sql = "insert into people values(?,?)";//?代表占位符PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,id);preparedStatement.setString(2,name);//4. 將編譯好的sql語句傳給服務器,并且執行sqlint n = preparedStatement.executeUpdate(); //返回結果為整數,表示當前操作影響到了幾行數據System.out.println("n="+n);//5. 釋放前面占用的各種資源preparedStatement.close();connection.close();}
}System.out.println("n="+n);//5. 釋放前面占用的各種資源preparedStatement.close();connection.close();}
}
2.2 通過 JDBC 進行 查詢數據 操作
查詢操作由于要在idea里面返回結果,所以不同于增刪改操作;
代碼如下:
import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class JDBCDemo2 {public static void main(String[] args) throws SQLException {DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");Connection connection = dataSource.getConnection();String sql = "select * from people";PreparedStatement preparedStatement = connection.prepareStatement(sql);ResultSet resultSet=preparedStatement.executeQuery();while(resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.println(id+" "+name);}resultSet.close();preparedStatement.close();connection.close();}
}