当前位置: 首页 > news >正文

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的核心组件

  1. DriverManager
    管理数据库驱动程序,负责选择正确的驱动程序并与数据库建立连接。

  2. Connection
    代表数据库连接,JDBC的核心对象之一。通过Connection可以执行SQL语句、获取Statement、PreparedStatement等对象。

  3. Statement
    用于执行SQL语句,分为以下几类:

    • Statement: 用于执行简单的SQL查询。
    • PreparedStatement: 用于执行预编译的SQL查询,避免SQL注入问题,并提高性能。
    • CallableStatement: 用于执行存储过程。
  4. ResultSet
    执行查询后返回的结果集。通过ResultSet对象,可以访问查询的结果数据。

配置JDBC

在使用JDBC时,需要确保以下几个步骤:

  1. 加载数据库驱动:首先要加载数据库的JDBC驱动,通常使用Class.forName()来动态加载。
  2. 建立数据库连接:使用DriverManager.getConnection()方法建立与数据库的连接。
  3. 执行SQL语句:通过StatementPreparedStatement对象执行SQL语句。
  4. 处理结果集:使用ResultSet对象读取查询的结果数据。
  5. 关闭连接:最后,关闭数据库连接以释放资源。

实践示例: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 语句有两个 ? 占位符,表示你将动态地插入两个值(例如,nameemail)。

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 设置参数有两个主要优点:

  1. 防止 SQL 注入攻击:通过占位符传递参数,避免直接将数据嵌入 SQL 语句中,减少了恶意 SQL 注入的风险。
  2. 提高性能:对于重复执行相同 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&#xf…...

【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个人围成一圈&#xff0c;从第1个人开始顺序报号1、2、3。凡报到“3”者退出圈子&#xff0c;找出最后留在圈子中的人原来的序号。本题要求用链表实现。 #include <stdio.h> #include <stdlib.h>// 定义链表节点结构体 typedef struct Node {int num;struct Nod…...

Android实训九 数据存储和访问

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

实验一---典型环节及其阶跃响应---自动控制原理实验课

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

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...