MySQL之JDBC編程用法及說明
一、什么是 JDBC?
JDBC(Java Data Base Connectivity) 是 Java 提供的一套數(shù)據(jù)庫操作接口標(biāo)準(zhǔn),用來統(tǒng)一連接數(shù)據(jù)庫、發(fā)送 SQL、處理結(jié)果。
特點(diǎn):
- 面向接口編程,不關(guān)心底層數(shù)據(jù)庫類型
- 切換數(shù)據(jù)庫只需要換驅(qū)動(dòng)包
- 是所有 ORM 框架(MyBatis、Hibernate)的底層基礎(chǔ)
JDBC 的核心作用
- 建立數(shù)據(jù)庫連接
- 發(fā)送 SQL 語句
- 接收并處理執(zhí)行結(jié)果
- 關(guān)閉資源
JDBC 工作流程
正常來說,訪問數(shù)據(jù)庫的重要步驟如下,JDBC也提供了這些接口:
- 確定數(shù)據(jù)庫服務(wù)器的地址和端口號(hào)(數(shù)據(jù)源)
- 建立連接,確定用戶名,密碼(數(shù)據(jù)庫連接)
- 發(fā)送要執(zhí)行的SQL(執(zhí)行對(duì)象)
- 接收返回結(jié)果(結(jié)果集)
- 關(guān)閉連接(釋放資源,關(guān)閉連接)
數(shù)據(jù)庫廠商提供了JDBC具體的實(shí)現(xiàn)類,Java程序員只需要利用接口來寫程序。
加載驅(qū)動(dòng) → 建立連接 → 創(chuàng)建 Statement → 執(zhí)行 SQL → 處理結(jié)果 → 釋放資源
二、開發(fā)環(huán)境準(zhǔn)備(Maven 項(xiàng)目)
Maven類似于應(yīng)用商店,在maven倉庫中維護(hù)了所有Java工程所用到的依賴。maven倉庫是國外的,可以用阿里的鏡像。
1. 配置 Maven 阿里云鏡像
加速依賴下載,在 settings.xml 的 <mirrors> 中加入:
<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共倉庫</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>
2. 引入 MySQL 驅(qū)動(dòng)依賴
pom.xml:
<dependencies>
<!-- MySQL 8.x 驅(qū)動(dòng) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
三、JDBC 核心 API
1. DriverManager(傳統(tǒng)連接)
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection= DriverManager.getConnection(url, user, password);
Driver類(驅(qū)動(dòng)類)

2. DataSource(連接池)
DataSource通過一個(gè)連接池去管理很多個(gè)連接,當(dāng)需要執(zhí)行sql時(shí)拿出一個(gè)空的連接,用完返還給連接池。是更高效、支持連接復(fù)用,企業(yè)開發(fā)標(biāo)準(zhǔn)用法
MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setURL(url); dataSource.setUser(user); dataSource.setPassword(password);
DriverManager VS DataSource
DriverManagergetConnection每次獲取的是一個(gè)物理連接,每執(zhí)行一次都會(huì)打開一個(gè)會(huì)話窗口,新建連接,用完銷毀,性能低Datasourse一個(gè)連接可以執(zhí)行很多SQL,直到關(guān)閉數(shù)據(jù)源。連接可復(fù)用,關(guān)閉只是歸還,性能極高
3. Connection(連接對(duì)象)
代表一次數(shù)據(jù)庫會(huì)話,用于創(chuàng)建 Statement。
4. Statement(執(zhí)行對(duì)象)
- Statement:靜態(tài) SQL,存在 SQL 注入風(fēng)險(xiǎn)
- PreparedStatement:預(yù)編譯 SQL,解決sql注入問題
- CallableStatement:執(zhí)行存儲(chǔ)過程
5. ResultSet(結(jié)果集)
封裝 select 查詢結(jié)果,用 next() 遍歷,getXXX(列名/下標(biāo)) 取值。
四、SQL 注入
什么是 SQL 注入?
用戶輸入惡意字符串,破壞原有 SQL 邏輯,實(shí)現(xiàn)越權(quán)查詢/刪改數(shù)據(jù)。
示例:
select * from student where name = '' or/**/1=1;#' and class_id=1
直接查出所有數(shù)據(jù):

解決方案
PreparedStatement + 占位符 ?
Statement執(zhí)行靜態(tài)的sql語句,PreparedStatement可以預(yù)處理sql執(zhí)行對(duì)象。參數(shù)會(huì)被安全轉(zhuǎn)義,從根本杜絕注入。
五、完整代碼
功能:根據(jù) name 查詢學(xué)生
基礎(chǔ)版
package org.daisy;
import java.sql.*;
import java.text.MessageFormat;
import java.util.Scanner;
public class demo01_DriverManager {
static Scanner in = new Scanner(System.in);
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1. 加載數(shù)據(jù)庫廠商提供的驅(qū)動(dòng)
// "com.mysql.cj.jdbc.Driver" 通過完全限定名加載指定的類到JVM
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 建立連接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test20260422?characterEncoding=utf8" +
"&allowPublicKeyRetrieval=true&useSSL=false", "root", "pullmecloser00");
//3. 創(chuàng)建statement對(duì)象
//sql語句通過connection發(fā)送
Statement statement = connection.createStatement();
//4. 定義sql語句
System.out.println("input name:");
String name = in.nextLine();
String sql = "select studentID,sn,name,mail,classID from student where name ='"+name+"';";
//5. 執(zhí)行sql語句,獲取結(jié)果集
ResultSet resultSet = statement.executeQuery(sql);
//6. 遍歷結(jié)果集
// resultSet.next() 如果有下一條數(shù)據(jù)就返回true
while(resultSet.next()){
//獲取學(xué)生ID,sql中的int對(duì)應(yīng)Java中的int
int stuId = resultSet.getInt(1);
String stuSn = resultSet.getString(2);
String stuName = resultSet.getString(3);
String stuMail = resultSet.getString(4);
String stuClassId = resultSet.getString(5);
System.out.println(MessageFormat.format(
"學(xué)生編號(hào) = {0},學(xué)號(hào) = {1},學(xué)生姓名 = {2},郵箱 = {3},班級(jí) = {4}",
stuId,stuSn,stuName,stuMail,stuClassId)
);
}
//7. 釋放資源,關(guān)閉連接
resultSet.close();
statement.close();
connection.close();
}
}
DataSourse , Preparement 優(yōu)化
package org.daisy;
import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.*;
import java.text.MessageFormat;
import java.util.Scanner;
public class demo02_DataSource {
static Scanner in = new Scanner(System.in);
public static void main(String[] args) throws SQLException {
// 定義mysql數(shù)據(jù)源對(duì)象
MysqlDataSource mysqlDataSource = new MysqlDataSource();
//設(shè)置數(shù)據(jù)庫連接串,用戶名,密碼
mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/test20260422?characterEncoding=utf8" +
"&allowPublicKeyRetrieval=true&useSSL=false");
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("pullmecloser00");
//定義jdbc數(shù)據(jù)源對(duì)象
DataSource dataSource = mysqlDataSource;
//1. 通過數(shù)據(jù)源獲取數(shù)據(jù)庫連接
Connection connection = dataSource.getConnection();
//2. 獲取預(yù)處理sql執(zhí)行對(duì)象
//定義要執(zhí)行的sql語句
String sql = "select studentID,sn,name,mail,classID from student where name = ?";
//sql執(zhí)行對(duì)象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//用戶輸入查詢信息
System.out.println("input name:");
String name = in.nextLine();
//3. 用真實(shí)值來替換占位符
//序號(hào)1對(duì)應(yīng)第一個(gè)占位符
preparedStatement.setString(1,name);
//4. 執(zhí)行sql,獲取結(jié)果
//結(jié)果集對(duì)象
ResultSet resultSet = preparedStatement.executeQuery();
//遍歷結(jié)果
while(resultSet.next()){
//獲取學(xué)生ID,sql中的int對(duì)應(yīng)Java中的int
int stuId = resultSet.getInt(1);
String stuSn = resultSet.getString(2);
String stuName = resultSet.getString(3);
String stuMail = resultSet.getString(4);
String stuClassId = resultSet.getString(5);
System.out.println(MessageFormat.format(
"學(xué)生編號(hào) = {0},學(xué)號(hào) = {1},學(xué)生姓名 = {2},郵箱 = {3},班級(jí) = {4}",
stuId,stuSn,stuName,stuMail,stuClassId)
);
}
//5. 關(guān)閉資源,釋放連接
resultSet.close();
preparedStatement.close();
connection.close();
}
}
把建立連接和關(guān)閉資源封裝成對(duì)象
DBUtil類
package org.daisy.DBUtil;
import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBUtil {
/**
* 構(gòu)造方法私有化,禁止其他類創(chuàng)建DBUtil對(duì)象,是單例模式的一個(gè)重要特征
*/
private DBUtil(){}
//數(shù)據(jù)源
private static DataSource dataSource = null;
//連接串,用戶名,密碼
private static String URL = "jdbc:mysql://127.0.0.1:3306/test20260422?characterEncoding=utf8" +
"&allowPublicKeyRetrieval=true&useSSL=false";
private static String user = "root";
private static String password = "pullmecloser00";
//類加載到JVM時(shí),執(zhí)行數(shù)據(jù)源的初始化
static {
MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setURL(URL);
mysqlDataSource.setUser(user);
mysqlDataSource.setPassword(password);
dataSource = mysqlDataSource;
}
/**
* 獲取數(shù)據(jù)庫連接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
/**
* 釋放資源,關(guān)閉連接
* @param resultSet
* @param statement
* @param connection
* @throws SQLException
*/
public static void close(ResultSet resultSet, Statement statement,Connection connection) throws SQLException {
if(resultSet!=null)
resultSet.close();
if(statement!=null)
statement.close();
if(connection!=null)
connection.close();
}
}
Insert類
package org.daisy;
import org.daisy.DBUtil.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
public class demo03_Insert {
static Scanner in = new Scanner(System.in);
public static void main(String[] args) throws SQLException {
//1. 獲取數(shù)據(jù)庫連接
Connection connection = DBUtil.getConnection();
//2. 定義sql
String sql = "insert student (sn,name,mail,classID) values (?,?,?,?)";
//3. 定義預(yù)處理對(duì)象
PreparedStatement statement = connection.prepareStatement(sql);
//4. 用真實(shí)數(shù)據(jù)填充占位符
System.out.println("input sn:");
String sn = in.nextLine();
System.out.println("input name:");
String name = in.nextLine();
System.out.println("input mail:");
String mail = in.nextLine();
System.out.println("input classId:");
String classId = in.nextLine();
statement.setString(1,sn);
statement.setString(2,name);
statement.setString(3,mail);
statement.setString(4,classId);
//5. 執(zhí)行并判斷 executeUpdate返回結(jié)果是受影響的行數(shù)
int row = statement.executeUpdate();
if(row == 1)
System.out.println("insert successfully");
else
System.out.println("insert fail");
//6. 關(guān)閉資源
DBUtil.close(null,statement,connection);
}
}
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL數(shù)據(jù)庫常用操作技巧總結(jié)
這篇文章主要介紹了MySQL數(shù)據(jù)庫常用操作技巧,結(jié)合實(shí)例形式總結(jié)分析了mysql查詢、存儲(chǔ)過程、字符串截取、時(shí)間、排序等常用操作技巧,需要的朋友可以參考下2018-03-03
Mysql 5.7.20壓縮版下載和安裝簡(jiǎn)易教程
這篇文章主要介紹了Mysql 5.7.20壓縮版下載和安裝簡(jiǎn)易教程,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11
利用Prometheus與Grafana對(duì)Mysql服務(wù)器的性能監(jiān)控詳解
Prometheus是源于 Google Borgmon的一個(gè)開源監(jiān)控系統(tǒng),用 Golang開發(fā)。被很多人稱為下一代監(jiān)控系統(tǒng)。Grafana是一個(gè)開源的圖表可視化系統(tǒng),簡(jiǎn)單說圖表配置比較方便、生成的圖表比較漂亮。下面就介紹了利用Prometheus與Grafana對(duì)Mysql服務(wù)器性能監(jiān)控的方法。2017-03-03
MySQL中的SHOW FULL PROCESSLIST命令實(shí)現(xiàn)
SHOW FULL PROCESSLIST命令是MySQL中一個(gè)非常有用的工具,可以幫助我們理解和監(jiān)控MySQL服務(wù)器的狀態(tài),本文主要介紹了MySQL中的SHOW FULL PROCESSLIST命令,感興趣的可以了解一下2023-11-11

