以下内容全面详尽地梳理了 JDBC (Java Database Connectivity)的核心知识点,并在关键环节配以示例代码。若要快速定位,可先查看下方结构:

  1. JDBC 概览
  2. 驱动加载与注册
  3. 获取数据库连接
  4. 执行 SQL(Statement、PreparedStatement、CallableStatement)
  5. 处理结果集(ResultSet)
  6. 批量操作与批处理
  7. 事务管理
  8. 元数据操作(DatabaseMetaData、ResultSetMetaData)
  9. 异常处理
  10. 连接池与 DataSource
  11. 最佳实践与性能优化

1. JDBC 概览

  • 用途:提供 Java 程序访问各种关系型数据库(MySQL、Oracle、PostgreSQL 等)的统一 API。
  • 核心接口包java.sql.*
  • 主要角色
    • DriverManager/Driver:驱动注册、连接分发
    • Connection:管理会话、事务
    • Statement/PreparedStatement/CallableStatement:执行 SQL
    • ResultSet:承载查询结果
    • DataSource:替代 DriverManager 的连接获取方式(可集成连接池)

执行过程可总结为:

  1. 驱动加载(现在可以省略)
  2. 获取数据库连接
  3. 定义要执行的sql语句
  4. 获取执行对象
  5. 执行对象执行sql语句,获取返回结果
  6. 后续处理

2. 驱动加载与注册

2.1 自动注册(JDBC 4.0+)

只要在 classpath 中包含相应数据库的 JDBC 驱动(如 mysql-connector-java.jar),Driver 会通过 SPI 自动注册,无需显式调用。

// 不需要 Class.forName(...),直接拿连接即可
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "root", "password");

2.2 手动加载(向后兼容)

Class.forName("com.mysql.cj.jdbc.Driver");
// 或者老版本
// Class.forName("com.mysql.jdbc.Driver");

3. 获取数据库连接

String url      = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC";
String user     = "root";
String password = "password";try (Connection conn = DriverManager.getConnection(url, user, password)) {// 使用 conn 
} catch (SQLException e) {e.printStackTrace();
}
  • 常用参数
    • useSSL=false:禁用 SSL
    • serverTimezone=UTC:指定时区
    • autoReconnect=true:自动重连

当然可以,以下是重新整理并扩充后的第4部分内容,加入了 SQL 注入的讲解,并对 Statement 的两个方法做了深入分析,保持原有结构和风格:


4. 获取执行 SQL 对象,Cnn 获取

在 JDBC 中,获取数据库连接后,我们需要通过执行 SQL 语句与数据库交互,这一过程通常通过以下三种执行对象实现:

  • Statement:用于执行静态 SQL 语句(不带参数),简单但易受 SQL 注入攻击;
  • PreparedStatement:预编译 SQL 语句,支持参数绑定,性能更优、安全性更高;

Statement 的核心方法:

int executeUpdate(String sql)
  • 执行 DML(INSERT、UPDATE、DELETE)DDL(CREATE、DROP)
  • 返回值为 受影响的行数,若为 DDL,通常返回 0(不代表失败)。
ResultSet executeQuery(String sql)
  • 执行 DQL(SELECT)语句,返回查询结果集 ResultSet

关于 SQL 注入(SQL Injection)

SQL 注入是一种严重的安全漏洞,攻击者可以通过拼接恶意 SQL 来操控数据库。例如:

String name = "' OR '1'='1";
String sql = "SELECT * FROM user WHERE name = '" + name + "'";

构造出的 SQL 实际是:

SELECT * FROM user WHERE name = '' OR '1'='1'

where后面的结果将永远是真的,所以就可以永远的查询出来.
将返回所有用户数据,甚至可用于删除表结构,极其危险!


4.1 Statement(不预编译,易受 SQL 注入)

String name = "张三";
String sql = "SELECT id, name FROM user WHERE name = '" + name + "'";
try (Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql)
) {while (rs.next()) {System.out.println(rs.getInt("id") + ": " + rs.getString("name"));}
}

优点:简单,适合一次性、非常简单的 SQL;
缺点:拼接字符串,极易受 SQL 注入攻击不能复用或预编译,性能差。


4.2 PreparedStatement(预编译,防注入、性能更优)

String sql = "SELECT id, name FROM user WHERE name = ? AND age > ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, "张三");pstmt.setInt(2, 18);try (ResultSet rs = pstmt.executeQuery()) {while (rs.next()) {System.out.println(rs.getInt("id") + ": " + rs.getString("name"));}}
}

优点:

  • 使用 占位符 ? 实现参数绑定,不拼接字符串,有效防止 SQL 注入
  • SQL 会被 预编译并缓存,适合多次执行,提高效率
  • 自动转义字符串,避免因特殊字符出错

缺点:相比 Statement 书写稍复杂,不适合拼接动态结构的 SQL(如条件列名)。


Statement vs PreparedStatement 详细对比

特性StatementPreparedStatement
SQL 预编译是(可缓存执行计划)
防 SQL 注入能力差(需要手动拼接字符串)强(使用参数绑定)
性能(重复执行场景)差(每次都解析)优(执行计划可复用)
可读性与维护性差(大量拼接容易混乱)高(结构清晰,安全)
支持占位符 ?
使用场景简单、临时查询正式项目、复杂参数、安全性要求高场合

5. 处理结果集(ResultSet)

  • 指针导航.next(), .first(), .last(), .absolute(n)(需指定 TYPE_SCROLL)
  • 获取列值getInt(), getString(), getDate()
  • 按列名或列索引
  • 类型转换注意:避免隐式类型转换带来的性能/精度问题
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {int    id   = rs.getInt(1);String name = rs.getString("name");Date   dob  = rs.getDate("dob");// ...
}

6. 批量操作与批处理

批量执行可显著提升大量插入/更新的性能。

String sql = "INSERT INTO user(name, age) VALUES(?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {conn.setAutoCommit(false);  // 关闭自动提交for (int i = 1; i <= 1000; i++) {pstmt.setString(1, "User" + i);pstmt.setInt(2, 20 + (i % 30));pstmt.addBatch();if (i % 200 == 0) {pstmt.executeBatch();conn.commit();  // 分批提交}}// 提交剩余pstmt.executeBatch();conn.commit();
}

7. 事务管理Cnn对象负责管理

try {conn.setAutoCommit(false);  // 开启事务// 操作1// 操作2// ...conn.commit();              // 提交事务
} catch (SQLException e) {conn.rollback();            // 回滚事务
} finally {conn.setAutoCommit(true);   // 恢复默认
}
  • 隔离级别conn.setTransactionIsolation(...)
  • 保存点Savepoint sp = conn.setSavepoint("sp1"); conn.rollback(sp);

8. 元数据操作

8.1 DatabaseMetaData

DatabaseMetaData dbMeta = conn.getMetaData();
System.out.println("Database product: " + dbMeta.getDatabaseProductName());
System.out.println("Driver version: " + dbMeta.getDriverVersion());

8.2 ResultSetMetaData

ResultSetMetaData rsMeta = rs.getMetaData();
int columnCount = rsMeta.getColumnCount();
for (int i = 1; i <= columnCount; i++) {System.out.println("Column " + i + ": " + rsMeta.getColumnName(i)+ " (" + rsMeta.getColumnTypeName(i) + ")");
}

9. 异常处理

  • SQLException
    • .getErrorCode():数据库错误码
    • .getSQLState():标准 SQLState
  • 资源释放:强烈推荐使用 try-with-resources 自动关闭 ConnectionStatementResultSet
try (Connection conn =;PreparedStatement pstmt = conn.prepareStatement(...);ResultSet rs = pstmt.executeQuery();
) {// ...
} catch (SQLException e) {System.err.println("Error Code: " + e.getErrorCode());System.err.println("SQL State : " + e.getSQLState());e.printStackTrace();
}

10. 连接池与 DataSource

10.1 为什么使用连接池

  • 连接创建开销大
  • 重复使用可提升性能

10.2 常见连接池

  • HikariCP(高性能)
  • Apache DBCP
  • C3P0

10.3 DataSource 示例(HikariCP)

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/testdb");
config.setUsername("root");
config.setPassword("password");
config.setMaximumPoolSize(10);DataSource ds = new HikariDataSource(config);// 获取连接
try (Connection conn = ds.getConnection()) {// ...
}

11. 最佳实践与性能优化

  1. 使用 PreparedStatement 防止 SQL 注入、提升性能。
  2. 合理设置批量大小,避免长事务占用资源。
  3. 关闭不必要的自动提交,批量操作时手动管理事务。
  4. 使用连接池,避免频繁创建销毁连接。
  5. 定期监控慢查询,并为频繁访问的字段添加索引。
  6. 尽量只查询所需列,避免 SELECT *
  7. 及时关闭资源,防止连接泄漏(try-with-resources)。

IDEA调试总结:

更通俗、贴近实际编程操作的语言来重新解释 IntelliJ IDEA 中调试时常用的快捷键,避免术语,让你一看就懂:


IDEA 调试快捷键(简单易懂版)

功能Windows / LinuxmacOS说明(通俗解释)
启动调试Shift + F9Control + D像运行程序一样运行,但可以中途停下来看代码状态
停止调试Ctrl + F2Command + F2停掉整个程序
一步一步执行代码(当前行)F8F8当前行执行完再停在下一行(如果是循环,就跳下一次)
进入方法体中去看具体执行F7F7如果当前行是一个函数调用,按它会跳进去函数里看细节
跳出当前方法返回上一层Shift + F8Shift + F8如果你已经进了方法里,按这个会回到调用这个方法的地方
执行到光标处停下Alt + F9Option + F9让程序一直跑到你当前鼠标点的位置再停下(省得一直按F8)
继续往下执行程序F9Command + Option + RF9程序继续往下跑,直到遇到下一个断点
设置或取消断点Ctrl + F8Command + F8在代码左边点一下,红点就是断点,程序会在这里暂停

常用调试辅助操作

功能Windows / LinuxmacOS说明
查看某个变量的值鼠标悬停鼠标悬停把鼠标放在变量上面,就会显示它当前的值
手动输入表达式查看结果Alt + F8Option + F8弹出一个窗口,你可以输入变量或表达式看结果,比如 a + b
查看所有断点Ctrl + Shift + F8Command + Shift + F8可以集中管理所有断点
快速查看变量内容Ctrl + Shift + ICommand + Shift + I不用跳转,临时查看变量内容

举个简单例子:

public class Demo {public static void main(String[] args) {int a = 10;int b = 20;int c = add(a, b);  // 👉 在这里打断点System.out.println("结果是:" + c);}public static int add(int x, int y) {return x + y;}
}

如果你在 int c = add(a, b); 那一行打断点:

  • Shift + F9 开始调试;
  • 程序会停在 add(a, b) 那一行;
  • F8,它会直接执行完这一行然后到下一行;
  • F7,它会跳进 add() 方法里面
  • 在方法中可以继续按 F8 看一步步怎么返回结果;
  • 再按 Shift + F8 就可以返回到 main() 继续调试;
  • 最后按 F9 可以直接让程序跑完。

如果你还不熟练,可以先只记住这两个:

  • 👉 F8一步一步往下执行
  • 👉 F7进入函数体里看看里面是怎么执行的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90563.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90563.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/90563.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch中nn.Module详解和综合代码示例

在 PyTorch 中&#xff0c;nn.Module 是神经网络中最核心的基类&#xff0c;用于构建所有模型。理解并熟练使用 nn.Module 是掌握 PyTorch 的关键。一、什么是 nn.Module nn.Module 是 PyTorch 中所有神经网络模块的基类。可以把它看作是“神经网络的容器”&#xff0c;它封装了…

深入解析三大Web安全威胁:文件上传漏洞、SQL注入漏洞与WebShell

文章目录文件上传漏洞SQL注入漏洞WebShell三者的核心关联&#xff1a;攻击链闭环文件上传漏洞 文件上传漏洞&#xff08;File Upload Vulnerability&#xff09; 当Web应用允许用户上传文件但未实施充分的安全验证时&#xff0c;攻击者可上传恶意文件&#xff08;如WebShell、…

【对比】群体智能优化算法 vs 贝叶斯优化

在机器学习、工程优化和科学计算中&#xff0c;优化算法的选择直接影响问题求解的效率与效果。群体智能优化算法&#xff08;Swarm Intelligence, SI&#xff09;和贝叶斯优化&#xff08;Bayesian Optimization, BO&#xff09;是两种截然不同的优化范式&#xff0c;分别以不同…

LLMs之Agent:ChatGPT Agent发布—统一代理系统将研究与行动无缝对接,开启智能助理新时代

LLMs之Agent&#xff1a;ChatGPT Agent发布—统一代理系统将研究与行动无缝对接&#xff0c;开启智能助理新时代 目录 OpenAI重磅发布ChatGPT Agent—统一代理系统将研究与行动无缝对接&#xff0c;开启智能助理新时代 第一部分&#xff1a;Operator 和深度研究的自然演进 第…

Linux726 raid0,raid1,raid5;raid 创建、保存、停止、删除

RAID创建 创建raid0 安装mdadm yum install mdadm mdadm --create /dev/md0 --raid-devices2 /dev/sdb5 /dev/sdb6 [rootsamba caozx26]# mdadm --create /dev/md0 --raid-devices2 /dev/sdb3 /dev/sdb5 --level0 mdadm: Defaulting to version 1.2 metadata mdadm: array /dev…

深入剖析 MetaGPT 中的提示词工程:WriteCode 动作的提示词设计

今天&#xff0c;我想和大家分享关于 AI 提示词工程的文章。提示词&#xff08;Prompt&#xff09;是大型语言模型&#xff08;LLM&#xff09;生成高质量输出的关键&#xff0c;而在像 MetaGPT 这样的 AI 驱动软件开发框架中&#xff0c;提示词的设计直接决定了代码生成的可靠…

关于 ESXi 中 “ExcelnstalledOnly 已禁用“ 的解决方案

第一步&#xff1a;使用ssh登录esxi esxcli system settings advanced list -o /User/execInstalledOnly可能会得到以下内容 esxcli system settings advanced list -o /User/execInstalledOnlyPath: /User/ExecInstalledOnlyType: integerInt Value: 0Default Int Value: 1Min…

HTML5 Canvas 绘制圆弧效果

HTML5 Canvas 绘制圆弧效果 以下是一个使用HTML5 Canvas绘制圆弧的完整示例&#xff0c;你可以直接在浏览器中运行看到效果&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"view…

智能Agent场景实战指南 Day 18:Agent决策树与规划能力

【智能Agent场景实战指南 Day 18】Agent决策树与规划能力 开篇 欢迎来到"智能Agent场景实战指南"系列的第18天&#xff01;今天我们将深入探讨智能Agent的核心能力之一&#xff1a;决策树与规划能力。在现代业务场景中&#xff0c;Agent需要具备类似人类的决策能力…

AI 编程工具 Trae 重要的升级。。。

大家好&#xff0c;我是樱木。 今天打开 Trae &#xff0c;已经看到它进行图标升级&#xff0c;之前的图标&#xff0c;国际和国内版本长得非常像&#xff0c;现在做了很明显的区分&#xff0c;这点给 Trae 团队点个赞。 自从 Claude 使出了压力以来&#xff0c;Cursor 锁区&…

排序算法,咕咕咕

1.选择排序void selectsort(vector<int>& v) { for(int i0;i<v.size()-1;i) {int minii;for(int ji1;j<v.size();j){if(v[i]>v[j]){minij;}}if(mini!i)swap(v[i],v[mini]); } }2.堆排序void adjustdown(vector<int>& v,int root,int size) { int …

数据库查询系统——pyqt+python实现Excel内查课

一、引言 数据库查询系统处处存在&#xff0c;在教育信息化背景下&#xff0c;数据库查询技术更已深度融入教务管理场景。本系统采用轻量化架构&#xff0c;结合Excel课表&#xff0c;通过PythonPyQt5实现跨平台桌面应用&#xff0c;以实现简单查课效果。 二、GUI界面设计 使用…

base64魔改算法 | jsvmp日志分析并还原

前言 上一篇我们讲了标准 base64 算法还原&#xff0c;为了进一步学习 base64 算法特点&#xff0c;本文将结合 jsvmp 日志&#xff0c;实战还原出 base64 魔改算法。 为了方便大家学习&#xff0c;我将入参和上篇文章一样&#xff0c;入参为 Hello, World!。 插桩 在js代码中&…

vue3笔记(2)自用

目录 一、作用域插槽 二、pinia的使用 一、Pinia 基本概念与用法 1. 安装与初始化 2. 创建 Store 3. 在组件中使用 Store 4. 高级用法 5、storeToRefs 二、Pinia 与 Vuex 的主要区别 三、为什么选择 Pinia&#xff1f; 三、定义全局指令 1.封装通用 DOM 操作&#…

大模型面试回答,介绍项目

1. 模型准备与转换&#xff08;PC端/服务器&#xff09;你先在PC上下载或训练好大语言模型&#xff08;如HuggingFace格式&#xff09;。用RKLLM-Toolkit把模型转换成瑞芯微NPU能用的专用格式&#xff08;.rkllm&#xff09;&#xff0c;并可选择量化优化。把转换好的模型文件拷…

Oracle 19.20未知BUG导致oraagent进程内存泄漏

故障现象查询操作系统进程的使用排序&#xff0c;这里看到oraagent的物理内存达到16G&#xff0c;远远超过正常环境&#xff08;正常环境在19.20大概就是100M多一点&#xff09;[rootorastd tmp]# ./hmem|more PID NAME VIRT(kB) SHARED(kB) R…

尝试几道算法题,提升python编程思维

一、跳跃游戏题目描述&#xff1a; 给定一个非负整数数组 nums&#xff0c;你最初位于数组的第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。示例&#xff1a;输入&#xff1a;nums [2,3,1,1,4] → 输出&#xff1a;True输入…

【菜狗处理脏数据】对很多个不同时间序列数据的文件聚类—20250722

目录 具体做法 可视化方法1&#xff1a;PCA降维 可视化方法2、TSNE降维可视化&#xff08;非线性降维&#xff0c;更适合聚类&#xff09; 可视化方法3、轮廓系数评判好坏 每个文件有很多行列的信息&#xff0c;每列是一个驾驶相关的数据&#xff0c;需要对这些文件进行聚类…

Qwen-MT:翻得快,译得巧

我们再向大家介绍一位新朋友&#xff1a;机器翻译模型Qwen-MT。开发者朋友们可通过Qwen API&#xff08;qwen-mt-turbo&#xff09;&#xff0c;来直接体验它又快又准的翻译技能。 本次更新基于强大的 Qwen3 模型&#xff0c;进一步使用超大规模多语言和翻译数据对模型进行训练…

在 OceanBase 中,使用 TO_CHAR 函数 直接转换日期格式,简洁高效的解决方案

SQL语句SELECT TO_CHAR(TO_DATE(your_column, DD-MON-YY), YYYY-MM-DD) AS formatted_date FROM your_table;关键说明&#xff1a;核心函数&#xff1a;TO_DATE(30-三月-15, DD-MON-YY) → 将字符串转为日期类型TO_CHAR(..., YYYY-MM-DD) → 格式化为 2015-03-30处理中文月份&a…