当前位置: 首页 > 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.比例环节的模拟电路 提…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

Python第七周作业

Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt&#xff0c;并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径&#xff0c;并创建logs目录&#xff08;若不存在&#xff09; 3.递归遍历目录data&#xff0c;输出所有.csv文件的路径…...

在Spring Boot中集成RabbitMQ的完整指南

前言 在现代微服务架构中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件&#xff0c;支持多种消息协议&#xff0c;具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...

【向量库】Weaviate概述与架构解析

文章目录 一、什么是weaviate二、High-Level Architecture1. Core Components2. Storage Layer3. 组件交互流程 三、核心组件1. API Layer2. Schema Management3. Vector Indexing3.1. 查询原理3.2. 左侧&#xff1a;Search Process&#xff08;搜索流程&#xff09;3.3. 右侧&…...