MySQL數(shù)據(jù)庫?JDBC?編程(Java?連接?MySQL)
1. 數(shù)據(jù)庫編程的基礎(chǔ)條件
如果你想實現(xiàn)代碼操作數(shù)據(jù)庫,那么以下條件是你實現(xiàn)它的前提
編程語言:
例如 Java、C++、Python 等等,這些語言都能夠?qū)崿F(xiàn)操作數(shù)據(jù)庫
某個數(shù)據(jù)庫的操作:
例如我在前面章節(jié)就介紹了關(guān)于 MySQL 的操作,實現(xiàn)其它數(shù)據(jù)庫如 Oracle、SQL Server 等等也要學(xué)會對應(yīng)數(shù)據(jù)庫的一些操作
安裝數(shù)據(jù)庫驅(qū)動包:
不同的數(shù)據(jù)庫對應(yīng)不同的編程語言提供了不同的數(shù)據(jù)庫驅(qū)動包,這些驅(qū)動包內(nèi)實現(xiàn)了操作對應(yīng)數(shù)據(jù)庫的 API
2. Java 的數(shù)據(jù)庫編程:JDBC
由于不同數(shù)據(jù)庫的廠商實現(xiàn)數(shù)據(jù)庫的 API 其實是不太一樣的,因此很多語言就把這些數(shù)據(jù)庫的 API 進行再一次的封裝,封裝出了一套統(tǒng)一的 API。這樣就可以通過一套代碼來操作多個不同的數(shù)據(jù)庫了
在 Java 中,這樣的封裝就是由 Java 標準庫來完成的,封裝出了一套統(tǒng)一的數(shù)據(jù)庫 API 稱為 JDBC
拓展:
Java 本身是跨平臺語言,雖然不同操作系統(tǒng)提供了不同的 API,但是 Java 本身也把這些 API 封裝了起來,在標準庫中提供了統(tǒng)一的接口,因此 Java 就可以一次編譯,到處運行
JDBC 介紹:
- JDBC,即
Java Database Connectivity
,是指 Java 數(shù)據(jù)庫連接。是一種用于執(zhí)行 SQL 語句的Java API
,它是 Java 中的數(shù)據(jù)庫連接規(guī)范。 - 這個 API 由
java.sql
和javax.sql
包中的一些類和接口組成,它為 Java 開發(fā)人員操作數(shù)據(jù)庫提供了一個標準的 API,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問
注意:
- JDBC API 是 Java 標準庫自帶的,可以直接用,但是 MySQL 的 JDBC 驅(qū)動不是系統(tǒng)自帶的,因此需要額外進行下載安裝
- MySQL 的 JDBC 驅(qū)動其實就是對 JDBC API 里面一些類和接口的具體實現(xiàn)
3. JDBC 訪問數(shù)據(jù)庫的層次結(jié)構(gòu)
4. MySQL 數(shù)據(jù)庫操作介紹
在前面章節(jié)我就介紹了關(guān)于 MySQL 的一些知識了,如果你在這方面有漏洞的話,可以直接通過下面的文章來進行補充。
第一章鏈接: 【MySQL 數(shù)據(jù)庫】數(shù)據(jù)庫的基礎(chǔ)知識
第二章鏈接: 【MySQL 數(shù)據(jù)庫】MySQL 的對庫的操作及其數(shù)據(jù)類型
第三章鏈接: 【MySQL 數(shù)據(jù)庫】數(shù)據(jù)表的基本操作
第四章鏈接: 【MySQL 數(shù)據(jù)庫】數(shù)據(jù)庫的約束及數(shù)據(jù)表的設(shè)計原理
第五章鏈接: 【MySQL 數(shù)據(jù)庫】聚合查詢和聯(lián)合查詢操作
第六章鏈接: 【MySQL 數(shù)據(jù)庫】MySQL 的索引和事務(wù)
5. MySQL 驅(qū)動包的下載及添加到項目
由于 MySQL 的 JDBC 驅(qū)動不是系統(tǒng)自帶的,因此需要額外進行下載安裝
各大數(shù)據(jù)庫的官網(wǎng)就有對應(yīng)數(shù)據(jù)庫的 JDBC 驅(qū)動,但這里我推薦使用一些中央倉庫來進行下載,例如 mvnrepository
驅(qū)動包下載步驟:
進入 mvnrepository 網(wǎng)站,在搜索欄搜索 MySQL,就可以查詢到以下結(jié)果
選擇第一個 MySQL Connector/J,就可以跳轉(zhuǎn)到下載版本選擇的頁面
選擇好自己對應(yīng)的數(shù)據(jù)庫版本的驅(qū)動(大版本一定要對應(yīng),小版本區(qū)別不大可以隨意選),由于我自己是 5.x 系列的MySQL,因此,我選擇大版號是5的就行。選擇后就跳到了最終下載的頁面
點擊 jar 就開始下載了(這個 jar 包就是將這個驅(qū)動包中的一些 .class 文件以壓縮包的形式進行打包了)
下載完成后,這個驅(qū)動包就已經(jīng)下載到你本地了,只再將它引入到你的項目就可以是用
6. JDBC 使用步驟
6.1 創(chuàng)建數(shù)據(jù)庫源,連接 Connection
創(chuàng)建一個數(shù)據(jù)庫源:
DataSource dataSource=new MysqlDataSource(); // DataSource 是來自于 Java 標準庫的一個接口,它用來表示“數(shù)據(jù)庫在哪” // MysqlDataSource 是來自于 MySQL 的驅(qū)動包,它是實現(xiàn)了 DataSource 接口的類
數(shù)據(jù)庫就是一個服務(wù)器程序,可以通過 DataSource
來描述服務(wù)器的 地址、端口、用戶名、密碼、要訪問的數(shù)據(jù)庫名等
把數(shù)據(jù)庫的位置信息,設(shè)置到 DataSource
中
// 1)通過一個 URL 來表示連接的數(shù)據(jù)庫、數(shù)據(jù)庫的 ip、端口、數(shù)據(jù)庫名、編碼方式、是否加密 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&setSSL=false"); // 2)設(shè)置登錄數(shù)據(jù)庫的用戶名 ((MysqlDataSource)dataSource).setUser("root"); // 3)設(shè)置登錄數(shù)據(jù)庫的密碼 ((MysqlDataSource)dataSource).setPassword("1234");
由于 setURL
、setUser
、setPassword
都是 MysqlDataSource
實現(xiàn)的,所以使用時需要向下轉(zhuǎn)型
上述 URL 是一種固定的寫法,例如:jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&setSSL=false
- jdbc 表示使用 JDBC 訪問數(shù)據(jù)庫
- mysql 表示訪問的數(shù)據(jù)庫是 MySQL
- 172.0.0.1 是 IP 地址,IP 地址是用來區(qū)分是哪個主機,172.0.0.1 這個 IP 地址表示當前使用的主機自身,因為我的 MySQL 服務(wù)器也裝在自己電腦上,自行修改
- 3306 是端口號,這是安裝數(shù)據(jù)庫服務(wù)器時手動設(shè)置的,一般默認是3306,它是用來區(qū)分主機上的某個程序
- test 是要訪問的數(shù)據(jù)庫名,這是我數(shù)據(jù)庫里面的,自行修改
characterEncoding=utf8
是用來指定編碼方式的,此處是使用 utf8,需要和使用的數(shù)據(jù)庫便方式對應(yīng),自行修改useSSL=false
是用來表示是否加密的,此處表示不加密,自行修改
連接數(shù)據(jù)庫,進行真正的網(wǎng)絡(luò)通信:
Connection connection=dataSource.getConnection();
Connection
是 Java 標準庫里的,雖然 MySQL 驅(qū)動里面也有。它是用來進行和數(shù)據(jù)庫服務(wù)器進行網(wǎng)絡(luò)連接的
getConnection 用于獲得試圖建立到指定數(shù)據(jù)庫 URL 的連接,如果連接成功就返回一個 Connection
對象,如果失敗就拋出異常
由于 getConnection
可能會連接失敗(例如 IP 地址、端口等輸入錯誤),因此就需要在方法聲明時通過 throws 給上層調(diào)用者拋出異?;蛘呤褂?code> try-catch 去處理異常
6.2 構(gòu)造 SQL 語句,為執(zhí)行的操作做準備
通過字符串,構(gòu)造一個要執(zhí)行的 sql
// 例如要執(zhí)行新增元素操作(表名為 student,有兩列 id 和 student Scanner scanner=new Scanner(System.in); System.out.print("請輸入 id:"); int id=scanner.nextInt(); System.out.print("請輸入 姓名:"); String name=scanner.next(); String sql="insert into student values(?,?)";
- sql 就是構(gòu)造的 SQL 語句,里面就是要執(zhí)行的具體操作
- sql 語句中可以不用加分號
- 表示通配符,可以通過它對 sql 語句里的內(nèi)容進行動態(tài)替換,需要替換的內(nèi)容用 ?代替,后續(xù)再使用 PreparedStatement 對象的一些方法將其再替換成具體要更改的值
例如:
void setInt(int paramenterIndex, int x)
:paramenterIndex 表示 sql 語句中要替換通配符的具體位置(從1開始),x 表示要替換掉具體值void setString(int parameterIndex, String x)
:paramenterIndex 表示 sql 語句中要替換通配符的具體位置(從1開始),x 表示要替換掉具體值
通過 prepareStatement(sql) 方法,將構(gòu)造的字符串 sql 轉(zhuǎn)化成真正的數(shù)據(jù)庫底層的 SQL 語句
PreparedStatement statement=connection.prepareStatement(sql); // 通過 setInt 方法,將 SQL 語句中的第一處通配符進行具體值的替換 statement.setInt(1,id); // 通過 setString 方法,將 SQL 語句中的第二處通配符進行具體值的替換 statement.setString(2,name);
JDBC 中,使用 Connection 和數(shù)據(jù)庫建立了連接對象 connection
,那么 connection
就可以調(diào)用 prepareStatement(String sql) 方法對參數(shù) sql 指定的 SQL 語句進行編譯預(yù)處理,生成該數(shù)據(jù)庫底層的內(nèi)部命令,并將該命令封裝在 PreparedStatement 對象中
6.3 執(zhí)行 SQL,并處理結(jié)果集
通過 PreparedStatement
對象的 executeQuery
或者 executeUpdate 方法來執(zhí)行 SQL
如果是執(zhí)行內(nèi)容變更的操作(增加、修改、刪除),就使用 int executeUpdate() 方法
int ret=statement.executeUpdate(); // executeUpdate 的返回結(jié)果是執(zhí)行該操作后影響的行數(shù) // 可以通過打印返回值來顯示影響的行數(shù) System.out.println("ret: "+ret);
如果要是要執(zhí)行查詢操作,就使用 ResultSet executeQuery() 方法
ResultSet resultSet=statement.executeQuery(); // executeQuery 的返回結(jié)果是執(zhí)行該操作后查詢到的類似于臨時表的結(jié)構(gòu),存放在 ResultSet 對象中 // 接下來我們可以對它進行遍歷,類似于迭代器的遍歷,方法如下 while(resultSet.next()){ // 假設(shè)有兩列 id 和 name int id=resultSet.getInt(id); String name=resultSet.getString(name); System.out.println("id="+id+", name="+name); }
SQL 查詢語句對數(shù)據(jù)庫的查詢操作將返回一個 ResultSet
對象,ResultSet
對象由按列(字段)組織的數(shù)據(jù)行構(gòu)成
ResultSet 對象一次只能看到一行數(shù)據(jù),使用 next() 方法,可以移到下一個數(shù)據(jù)行(類似于 i++)
可以使用 ResultSet
對象的 getXxx()
方法,去獲得字段。常用方法后面講將介紹
6.4 釋放資源
當我們執(zhí)行完了我們的 SQL 語句后,如果不再使用某些對象,就需要把連接關(guān)閉,釋放掉對應(yīng)的資源
// 如果有 ResultSet 對象不需要使用后,需要關(guān)閉這個連接 resultSet.close(); // Connection 不需要使用后,需要關(guān)閉這個連接 connection.close(); // PreparedStatement 不需要使用后,需要關(guān)閉這個連接 statement.close();
ResultSet
、Connection
、PreparedStatement
這些對象都對應(yīng)著一些及機器的硬件資源,如果不使用的話就要及時還回去。就類似于借書,如果大家在圖書館只借書,不還書,那么圖書館的書籍資源就會一直減少
這些對象可以使用 close()
方法,來關(guān)閉和客戶端與服務(wù)器建立的連接,以此釋放占用的資源
6.5 JDBC 編程模板
通過上面五步,就可以進行基礎(chǔ)的 Java 的 JDBC 編程了,雖然方法不止這一種,但如果你還不會的話,掌握這個方法就行了。最后再總結(jié)下整個的模板,依據(jù)它,我們就可以用 Java 語言對 MySQL 數(shù)據(jù)庫進行各種操作
public static void test(){ // 1. 創(chuàng)建數(shù)據(jù)庫源,連接 Connection DataSource dataSource=new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("1234"); Connection connection=dataSource.getConnection(); // 2. 構(gòu)造一個 SQL 語句,為要進行的操作做準備 String sql=""; PreparedStatement statement=connection.prepareStatement(sql); // 3. 執(zhí)行 SQL,并處理結(jié)果集 int ret=statement.executeUpdate(); // 4. 執(zhí)行完成,釋放資源 statement.close(); connection.close(); }
7. JDBC 常用接口和類
上述 JDBC 編程步驟中已經(jīng)將以下接口和類介紹了很多,所以可以互相補充漏洞
7.1 DataSource 和 MysqlDataSource
補充:
上述代碼也可以直接使用 MysqlDataSource
來創(chuàng)建一個數(shù)據(jù)源,這樣就可以不用使用向下轉(zhuǎn)型了。但是如果使用 DataSource 的話,那么代碼中其它代碼其實都是使用 DataSource
這個類型的,這是和具體數(shù)據(jù)庫類型無關(guān)的類,當你需要切換數(shù)據(jù)庫時,就不需要大幅度修改代碼
7.2 Connection
Connection
接口實現(xiàn)類由數(shù)據(jù)庫提供,獲取 Connection
對象通常有兩種方式:
方式一: 通過 DataSource(數(shù)據(jù)源)對象獲取
// 創(chuàng)建一個數(shù)據(jù)庫源 DataSource dataSource=new MysqlDataSource(); // 設(shè)置數(shù)據(jù)庫具體信息 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("1234"); // 創(chuàng)建數(shù)據(jù)庫連接 Connection connection=dataSource.getConnection();
方式二: 通過 DriverManager
(驅(qū)動管理類)的靜態(tài)方法獲取
// 加載 JDBC 驅(qū)動程序 Class.forName("com.mysql.cj.jdbc.Driver"); // 創(chuàng)建數(shù)據(jù)庫連接 Connection connection=DriverManager.getConnection(url);
MySQL 數(shù)據(jù)庫驅(qū)動程序被封裝在 Driver
類中,該類的包名是 com.mysql.cj.jdbc
,該類不是 Java 運行環(huán)境類庫中的類
上述兩種方式的區(qū)別:
DriverManager
類來獲取的Connection
連接,是無法重復(fù)利用的,每次使用完以后釋放資源時,通過connection.close()
都是關(guān)閉物理連接DataSource
提供連接池的支持。連接池在初始化時創(chuàng)建一定數(shù)量的數(shù)據(jù)庫連接,這些連接是可以重復(fù)利用的,每次使用完數(shù)據(jù)庫連接,通過connection.close()
釋放資源,都是將Connection
連接對象回收
7.3 PreparedStatement
PreparedStatement
是 JDBC API 提供的三種可以將 SQL 語句發(fā)送到數(shù)據(jù)庫的對象之一。這里對這三種做一個簡單介紹
Statement
: 用于執(zhí)行不帶參數(shù)的簡單 SQLPreparedStatement
:
- 用于執(zhí)行帶或者不帶參數(shù)的 SQL 語句
- SQL 語句會預(yù)編譯在數(shù)據(jù)庫系統(tǒng)
- 執(zhí)行速度快于 Statement 對象
CallableStatement
: 用于執(zhí)行數(shù)據(jù)庫存儲過程的調(diào)用
7.4 ResultSet
ResultSet
對象它被稱為結(jié)果集,它代表符合 SQL 語句條件的所有行,并且它通過一套 getXxx() 方法提供了對這些行中數(shù)據(jù)的訪問
ResultSet 里的數(shù)據(jù)是一行一行排列的,每當有多個字段,并且有一個記錄指針,指針所指的數(shù)據(jù)行叫做當前數(shù)據(jù)行,我們只能來操作當前的數(shù)據(jù)行。我們?nèi)绻胍〉媚骋粭l記錄,就要使用 ResultSet
的 next()
方法,可以通過結(jié)合 while 循環(huán)來遍歷 ResultSet 里的所有記錄
常見 ResultSet 對象方法:
注意:
ResultSet 對象和數(shù)據(jù)庫連接對象 Connection 實現(xiàn)了緊密連接,一旦連接對象被關(guān)閉,ResultSet 對象中的數(shù)據(jù)就會立刻消失
8. Java 操作數(shù)據(jù)庫實例
8.1 往表中新增數(shù)據(jù)
在 student 表中新增學(xué)生 id 和 name:
public static void testInsert() throws SQLException { DataSource dataSource=new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("1234"); Connection connection=dataSource.getConnection(); Scanner scanner=new Scanner(System.in); System.out.print("請輸入id:"); int id=scanner.nextInt(); System.out.print("請輸入姓名:"); String name=scanner.next(); String sql="insert into student values(?,?)"; PreparedStatement statement=connection.prepareStatement(sql); statement.setInt(1,id); statement.setString(2,name); int ret=statement.executeUpdate(); System.out.println("ret: "+ret); statement.close(); connection.close(); }
8.2 刪除表中的數(shù)據(jù)
在表名為 student 的表中,刪除學(xué)生表中符合 id 條件的記錄:
public static void testDelete() throws SQLException { DataSource dataSource=new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("1234"); Connection connection=dataSource.getConnection(); Scanner scanner=new Scanner(System.in); System.out.print("請輸入要刪除的 id:"); int id=scanner.nextInt(); String sql="delete from student where id=?"; PreparedStatement statement=connection.prepareStatement(sql); statement.setInt(1,id); int ret=statement.executeUpdate(); System.out.println("ret: "+ret); statement.close(); connection.close(); }
8.3 修改表中的數(shù)據(jù)
在表名為 student 的表中,將符合 id 條件的學(xué)生姓名進行修改:
public static void testUpdate() throws SQLException { DataSource dataSource=new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("1234"); Connection connection=dataSource.getConnection(); Scanner scanner=new Scanner(System.in); System.out.print("情輸入你要更改的學(xué)生 id:"); int id=scanner.nextInt(); System.out.print("請輸入你要更改后的學(xué)生姓名:"); String name=scanner.next(); String sql="update student set name=? where id=?"; PreparedStatement statement=connection.prepareStatement(sql); statement.setString(1,name); statement.setInt(2,id); int ret=statement.executeUpdate(); System.out.println("ret: "+ret); statement.close(); connection.close(); }
8.4 查找表中的數(shù)據(jù)
查找表名為 student 的表中的所有數(shù)據(jù):
public static void testSelect() throws SQLException { DataSource dataSource=new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("1234"); Connection connection=dataSource.getConnection(); String sql="select * from student"; PreparedStatement statement=connection.prepareStatement(sql); ResultSet resultSet=statement.executeQuery(); while(resultSet.next()){ int id=resultSet.getInt("id"); String name=resultSet.getString("name"); System.out.println("id = "+id+", name = "+name); } resultSet.close(); statement.close(); connection.close(); }
到此這篇關(guān)于MySQL數(shù)據(jù)庫 JDBC 編程(Java 連接 MySQL)的文章就介紹到這了,更多相關(guān)Java 連接 MySQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL中使用FREDATED引擎實現(xiàn)跨數(shù)據(jù)庫服務(wù)器、跨實例訪問
這篇文章主要介紹了MySQL中使用FREDATED引擎實現(xiàn)跨數(shù)據(jù)庫服務(wù)器、跨實例訪問,本文講解了FEDERATED存儲引擎的描述、安裝與啟用FEDERATED存儲引擎、準備遠程服務(wù)器環(huán)境等內(nèi)容,需要的朋友可以參考下2014-10-10Mysql大數(shù)據(jù)量查詢優(yōu)化思路詳析
這篇文章主要介紹了Mysql大數(shù)據(jù)量查詢優(yōu)化思路,Mysql大表查詢優(yōu)化,理論上千萬級別以下的數(shù)據(jù)量Mysql單表查詢性能處理都是可以的。下文我們就來看看具體得思路解析2022-01-01Mysql中TIMESTAMPDIFF函數(shù)的語法與練習(xí)案例
在應(yīng)用時經(jīng)常要使用這兩個函數(shù)TIMESTAMPDIFF和TIMESTAMPADD,下面這篇文章主要給大家介紹了關(guān)于Mysql中TIMESTAMPDIFF函數(shù)的語法與練習(xí)案例的相關(guān)資料,需要的朋友可以參考下2022-09-09mysql 5.7.17 安裝配置方法圖文教程(windows)
這篇文章主要為大家分享了mysql 5.7.17 安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01