Java数据库操作指南:快速上手JDBC【学术会议-2025年数字化教育与信息技术(DEIT 2025】
大会官网:www.ic-deit.org
前言
在现代企业应用中,数据库是数据存储和管理的重要组成部分。Java作为一种广泛使用的编程语言,提供了多种方式与数据库进行交互。本文将介绍 JDBC(Java Database Connectivity),它是Java语言与数据库之间的桥梁,帮助开发者通过Java程序与数据库进行连接、查询、插入、更新和删除数据。
什么是JDBC?
JDBC(Java数据库连接)是Java提供的一套API,用于从Java程序中访问和操作关系型数据库。通过JDBC,Java程序能够执行SQL语句、管理数据库连接,并处理结果集。JDBC是Java平台的标准一部分,支持多种数据库管理系统(DBMS),如MySQL、Oracle、PostgreSQL、SQL Server等。
JDBC的核心组件
-
DriverManager
管理数据库驱动程序,负责选择正确的驱动程序并与数据库建立连接。 -
Connection
代表数据库连接,JDBC的核心对象之一。通过Connection可以执行SQL语句、获取Statement、PreparedStatement等对象。 -
Statement
用于执行SQL语句,分为以下几类:Statement
: 用于执行简单的SQL查询。PreparedStatement
: 用于执行预编译的SQL查询,避免SQL注入问题,并提高性能。CallableStatement
: 用于执行存储过程。
-
ResultSet
执行查询后返回的结果集。通过ResultSet对象,可以访问查询的结果数据。
配置JDBC
在使用JDBC时,需要确保以下几个步骤:
- 加载数据库驱动:首先要加载数据库的JDBC驱动,通常使用
Class.forName()
来动态加载。 - 建立数据库连接:使用
DriverManager.getConnection()
方法建立与数据库的连接。 - 执行SQL语句:通过
Statement
或PreparedStatement
对象执行SQL语句。 - 处理结果集:使用
ResultSet
对象读取查询的结果数据。 - 关闭连接:最后,关闭数据库连接以释放资源。
实践示例:JDBC数据库操作
1. 连接数据库
首先,我们需要添加数据库的JDBC驱动包。如果使用的是MySQL,可以下载并添加 MySQL JDBC 驱动(mysql-connector-java
)。
然后,创建一个简单的Java程序来连接数据库。
import java.sql.*;public class JDBCExample {public static void main(String[] args) {// 数据库连接信息String url = "jdbc:mysql://localhost:3306/testdb";String user = "root";String password = "root";// 连接对象Connection connection = null;try {// 1. 加载数据库驱动(对于MySQL数据库)Class.forName("com.mysql.cj.jdbc.Driver");// 2. 获取数据库连接connection = DriverManager.getConnection(url, user, password);System.out.println("连接成功!");} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 关闭连接try {if (connection != null) {connection.close();}} catch (SQLException e) {e.printStackTrace();}}}
}
这段代码展示了如何加载MySQL驱动、建立数据库连接并进行简单的连接验证。
2. 执行查询操作
接下来,我们通过JDBC查询数据库,获取并输出查询结果。
public class JDBCQueryExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/testdb";String user = "root";String password = "root";String query = "SELECT * FROM users"; // 假设有一个名为users的表Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {// 1. 加载数据库驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2. 获取数据库连接connection = DriverManager.getConnection(url, user, password);// 3. 创建Statement对象statement = connection.createStatement();// 4. 执行SQL查询resultSet = statement.executeQuery(query);// 5. 处理结果集while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");String email = resultSet.getString("email");System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);}} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 关闭资源try {if (resultSet != null) resultSet.close();if (statement != null) statement.close();if (connection != null) connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
此代码通过executeQuery()
方法执行一个SELECT
语句,返回一个ResultSet
对象,并通过next()
方法遍历结果。
3. 插入数据
使用PreparedStatement
进行数据插入,可以提高性能并避免SQL注入。
public class JDBCInsertExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/testdb";String user = "root";String password = "root";String insertQuery = "INSERT INTO users (name, email) VALUES (?, ?)";Connection connection = null;PreparedStatement preparedStatement = null;try {// 1. 加载数据库驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2. 获取数据库连接connection = DriverManager.getConnection(url, user, password);// 3. 创建PreparedStatement对象preparedStatement = connection.prepareStatement(insertQuery);preparedStatement.setString(1, "John Doe");preparedStatement.setString(2, "john.doe@example.com");// 4. 执行更新操作(插入数据)int rowsAffected = preparedStatement.executeUpdate();System.out.println("插入了 " + rowsAffected + " 行数据");} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 关闭资源try {if (preparedStatement != null) preparedStatement.close();if (connection != null) connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
PreparedStatement
允许我们使用占位符?
,在插入数据时动态绑定参数,避免SQL注入问题。
4. 更新数据
通过PreparedStatement
更新数据:
public class JDBCUpdateExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/testdb";String user = "root";String password = "root";String updateQuery = "UPDATE users SET email = ? WHERE name = ?";Connection connection = null;PreparedStatement preparedStatement = null;try {// 1. 加载数据库驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2. 获取数据库连接connection = DriverManager.getConnection(url, user, password);// 3. 创建PreparedStatement对象preparedStatement = connection.prepareStatement(updateQuery);preparedStatement.setString(1, "new.email@example.com");preparedStatement.setString(2, "John Doe");// 4. 执行更新操作int rowsAffected = preparedStatement.executeUpdate();System.out.println("更新了 " + rowsAffected + " 行数据");} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 关闭资源try {if (preparedStatement != null) preparedStatement.close();if (connection != null) connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
5. 删除数据
通过PreparedStatement
删除数据:
public class JDBCDeleteExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/testdb";String user = "root";String password = "root";String deleteQuery = "DELETE FROM users WHERE name = ?";Connection connection = null;PreparedStatement preparedStatement = null;try {// 1. 加载数据库驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2. 获取数据库连接connection = DriverManager.getConnection(url, user, password);// 3. 创建PreparedStatement对象preparedStatement = connection.prepareStatement(deleteQuery);preparedStatement.setString(1, "John Doe");// 4. 执行删除操作int rowsAffected = preparedStatement.executeUpdate();System.out.println("删除了 " + rowsAffected + " 行数据");} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 关闭资源try {if (preparedStatement != null) preparedStatement.close();if (connection != null) connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
扩展:
具体来说,setString(int parameterIndex, String x)
方法用于将指定位置的占位符(?
)替换成指定的字符串值。
PreparedStatement
的工作原理
PreparedStatement
是一个接口,用于执行预编译的 SQL 查询。在 SQL 查询中,通常使用 ?
来表示占位符,表示参数将在运行时被动态传入,而不是在 SQL 查询字符串中直接硬编码。
例如,假设你要执行一个插入操作,SQL 语句可能是这样的:
INSERT INTO users (name, email) VALUES (?, ?);
这个 SQL 语句有两个 ?
占位符,表示你将动态地插入两个值(例如,name
和 email
)。
setString(int parameterIndex, String x)
详解
parameterIndex
:这个参数表示要替换的占位符的位置(从1开始),也就是你想要设置哪个位置的参数。x
:这是你想要设置的值,类型必须与占位符的类型匹配。在这种情况下,我们使用setString
,意味着占位符将会被一个字符串值替换。
preparedStatement.setString(1, "John Doe");
1
:这是第一个?
占位符的位置(从1开始计数)。表示要将?
的位置替换为John Doe
。"John Doe"
:这是你要插入的实际值(字符串"John Doe"
)。这个值会替代 SQL 语句中的第一个占位符?
。
等价于:
INSERT INTO users (name, email) VALUES ('John Doe', ?);
preparedStatement.setString(2, "john.doe@example.com");
2
:这是第二个?
占位符的位置,表示要将 SQL 中的第二个?
替换为john.doe@example.com
。"john.doe@example.com"
:这是你要插入的实际值(字符串"john.doe@example.com"
)。这个值会替代 SQL 语句中的第二个占位符?
。
等价于:
INSERT INTO users (name, email) VALUES ('John Doe', 'john.doe@example.com');
结合完整 SQL 语句
将这两行代码与 SQL 语句结合,最终执行的 SQL 语句就是:
INSERT INTO users (name, email) VALUES ('John Doe', 'john.doe@example.com');
这两行代码的作用是:
- 第一行将
"John Doe"
作为第一个参数(name
)传递给 SQL 查询。 - 第二行将
"john.doe@example.com"
作为第二个参数(email
)传递给 SQL 查询。
使用 PreparedStatement
设置参数有两个主要优点:
- 防止 SQL 注入攻击:通过占位符传递参数,避免直接将数据嵌入 SQL 语句中,减少了恶意 SQL 注入的风险。
- 提高性能:对于重复执行相同 SQL 查询的情况,JDBC 可以重用编译后的 SQL 执行计划,避免了每次都需要重新解析 SQL。
总结
本文展示了如何在Java中使用JDBC进行简单的数据库操作,包括连接数据库、查询、插入、更新和删除等基本操作。JDBC为Java应用程序提供了强大的数据库交互功能,但也需要注意资源管理(如连接的关闭)以及SQL注入等安全问题。希望本文能够帮助大家快速上手并实现Java与数据库的交互。
相关文章:
Java数据库操作指南:快速上手JDBC【学术会议-2025年数字化教育与信息技术(DEIT 2025】
大会官网:www.ic-deit.org 前言 在现代企业应用中,数据库是数据存储和管理的重要组成部分。Java作为一种广泛使用的编程语言,提供了多种方式与数据库进行交互。本文将介绍 JDBC(Java Database Connectivity)&#x…...
2024年个人总结
序 照例,每年都有的个人年度总结来了,看了很多其他大佬的总结,感觉自己的2024过于单薄,故事也不太丰满,自己就回去比较,自己哪里做的不好 ?但后来发现已经进入了一个思维误区。 年度总结年度总结…...
GitHub 仓库的 Archived 功能详解:中英双语
GitHub 仓库的 Archived 功能详解 一、什么是 GitHub 仓库的 “Archived” 功能? 在 GitHub 上,“Archived” 是一个专门用于标记仓库状态的功能。当仓库被归档后,它变为只读模式,所有的功能如提交代码、创建 issue 和 pull req…...
LeetCode:56.合并区间
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:56.合并区间 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti,…...
Vue演练场基础知识(七)插槽
为学习Vue基础知识,我动手操作通关了Vue演练场,该演练场教程的目标是快速体验使用 Vue 是什么感受,设置偏好时我选的是选项式 单文件组件。以下是我结合深入指南写的总结笔记,希望对Vue初学者有所帮助。 文章目录 十五. 插槽插槽…...

进程池的制作(linux进程间通信,匿名管道... ...)
目录 一、进程间通信的理解 1.为什么进程间要通信 2.如何进行通信 二、匿名管道 1.管道的理解 2.匿名管道的使用 3.管道的五种特性 4.管道的四种通信情况 5.管道缓冲区容量 三、进程池 1.进程池的理解 2.进程池的制作 四、源码 1.ProcessPool.hpp 2.Task.hpp 3…...
【Linux】Linux C比较两个 IPv6 网关地址是否相等,包括前缀
功能说明 在 Linux 环境下使用 C 语言比较两个 IPv6 网关地址是否相等,包括前缀 实现步骤 解析 IPv6 地址:使用 inet_pton 将字符串形式的 IPv6 地址转换为二进制形式。解析前缀长度:从地址字符串中提取前缀长度(如 /64…...
【uniapp】uniapp使用java线程池
标题 由于js是性能孱弱的单线程语言,只要在渲染中执行了一些其他操作,会中断渲染,导致页面卡死,卡顿,吐司不消失等问题。在安卓端可以调用java线程池,把耗时操作写入线程池里面,优化性能。 实…...

面试题-Java集合框架
前言 Java集合框架(Java Collections Framework)是Java平台提供的一套用于表示和操作集合的统一架构。它位于java.util包中,并且自Java 1.2(也称为Java 2平台,标准版,即Java SE 2)起成为Java平…...

Java基础教程(007):方法的重载与方法的练习
文章目录 6.5 方法的重载6.6 方法练习数组遍历数组最大值 6.5 方法的重载 在 Java 中,方法的重载是指在同一个类中定义多个方法,这些方法具有相同的名称,但参数列表不同。方法的重载是一种实现多态的方式,允许一个方法名以不同的…...

【ESP32】ESP-IDF开发 | WiFi开发 | TCP传输控制协议 + TCP服务器和客户端例程
1. 简介 TCP(Transmission Control Protocol),全称传输控制协议。它的特点有以下几点:面向连接,每一个TCP连接只能是点对点的(一对一);提供可靠交付服务;提供全双工通信&…...
npm cnpm pnpm npx yarn的区别
npm、cnpm、pnpm、npx、yarn 这几个工具都与 Node.js 项目的包管理和命令执行相关,它们的区别具体如下: 本质与功能定位 npm:是 Node.js 官方的包管理工具,提供了安装、卸载、更新、发布等全方位的包管理功能,还能通…...
debian12.9编译freeswitch1.10.12【默认安装】
服务器操作系统 cat /etc/os-release PRETTY_NAME"Debian GNU/Linux 12 (bookworm)" NAME"Debian GNU/Linux" VERSION_ID"12" VERSION"12 (bookworm)" VERSION_CODENAMEbookworm IDdebian HOME_URL"https://www.debian.org/&quo…...
使用 C/C++ 调用 libcurl 调试消息
在使用 C/C 调用 libcurl 进行 HTTP 请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试。libcurl 提供了多种方法来捕获和输出这些信息,本文介绍具体的使用方式。 1. libcurl 调试工具简介 libcurl 是…...

【愚公系列】《循序渐进Vue.js 3.x前端开发实践》030-自定义组件的插槽Mixin
标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主&…...
大一计算机的自学总结:异或运算
前言 异或运算这个操作看上去很匪夷所思,实际上作用非常大。 一、异或运算的性质 1.异或运算就是无进位相加。 2.满足交换律、结合律。 3.0^nn,n^n0。 4.若集合B为集合A子集,集合A异或和为x,集合B异或和为y,则集…...
通过protoc工具生成proto的pb.go文件以及使用protoc-go-inject-tag工具注入自定义标签
1.ProtoBuf认识,安装以及用法 参考:[golang 微服务] 3. ProtoBuf认识,安装以及golang 中ProtoBuf使用 2. 使用protoc-go-inject-tag工具注入自定义标签 这里有一个案例: syntaxproto3; package test;option go_package ".;test";message MyMessage {int6…...

C语言练习(29)
13个人围成一圈,从第1个人开始顺序报号1、2、3。凡报到“3”者退出圈子,找出最后留在圈子中的人原来的序号。本题要求用链表实现。 #include <stdio.h> #include <stdlib.h>// 定义链表节点结构体 typedef struct Node {int num;struct Nod…...

Android实训九 数据存储和访问
实训9 数据存储和访问 一、【实训目的】 1、 SharedPreferences存储数据; 2、 借助Java的I/O体系实现文件的存储, 3、使用Android内置的轻量级数据库SQLite存储数据; 二、【实训内容】 1、实现下图所示的界面,实现以下功能: 1ÿ…...

实验一---典型环节及其阶跃响应---自动控制原理实验课
一 实验目的 1.掌握典型环节阶跃响应分析的基本原理和一般方法。 2. 掌握MATLAB编程分析阶跃响应方法。 二 实验仪器 1. 计算机 2. MATLAB软件 三 实验内容及步骤 利用MATLAB中Simulink模块构建下述典型一阶系统的模拟电路并测量其在阶跃响应。 1.比例环节的模拟电路 提…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...

C++中vector类型的介绍和使用
文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...

奈飞工厂官网,国内Netflix影视在线看|中文网页电脑版入口
奈飞工厂是一个专注于提供免费Netflix影视资源的在线播放平台,致力于为国内用户提供的Netflix热门影视内容。该平台的资源与Netflix官网基本同步,涵盖电影、电视剧、动漫和综艺等多个领域。奈飞工厂的界面简洁流畅,资源分类清晰,方…...