【Java 进阶篇】JDBC PreparedStatement 详解

在Java中,与关系型数据库进行交互是非常常见的任务之一。JDBC(Java Database Connectivity)是Java平台的一个标准API,用于连接和操作各种关系型数据库。其中,PreparedStatement 是 JDBC 中一个重要的接口,用于执行预编译的 SQL 语句。本篇博客将详细介绍 JDBC 的 PreparedStatement,包括它的基本概念、使用方法以及最佳实践。
什么是 PreparedStatement?
PreparedStatement 是 JDBC 中的一个接口,用于执行预编译的 SQL 语句。与普通的 Statement 不同,PreparedStatement 的 SQL 语句在执行之前已经经过编译,因此更高效且安全,同时可以防止 SQL 注入攻击。PreparedStatement 通常用于执行多次相似的 SQL 查询或更新,只需编译一次,多次执行。
创建 PreparedStatement
要创建一个 PreparedStatement 对象,首先需要获得一个 Connection 对象,然后使用 prepareStatement 方法传入 SQL 语句。以下是一个示例:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class PreparedStatementDemo {public static void main(String[] args) {// 获取数据库连接Connection connection = getConnection();try {// SQL 查询语句,使用 ? 作为占位符String sql = "SELECT * FROM users WHERE username = ?";// 创建 PreparedStatement 对象PreparedStatement preparedStatement = connection.prepareStatement(sql);} catch (SQLException e) {e.printStackTrace();}}// 获取数据库连接的示例方法private static Connection getConnection() {// 实现获取数据库连接的逻辑,这里省略具体代码return null;}
}
在上述示例中,我们创建了一个 PreparedStatement 对象,其中 SQL 查询语句中使用了 ? 作为占位符,后面可以使用 setXXX 方法为这些占位符设置具体的值。
设置参数
PreparedStatement 允许我们为 SQL 语句中的占位符设置参数值。有多种 setXXX 方法可用于不同数据类型的参数设置,例如 setInt、setString、setDouble 等。以下是一个设置参数的示例:
try {String sql = "INSERT INTO users (username, age) VALUES (?, ?)";PreparedStatement preparedStatement = connection.prepareStatement(sql);// 设置第一个参数为字符串类型preparedStatement.setString(1, "Alice");// 设置第二个参数为整数类型preparedStatement.setInt(2, 30);// 执行 SQL 语句preparedStatement.executeUpdate();
} catch (SQLException e) {e.printStackTrace();
}
在上述示例中,我们使用 setString 和 setInt 方法分别为 SQL 语句中的两个占位符设置了具体的参数值。
执行查询
要执行查询操作,可以使用 executeQuery 方法,该方法返回一个 ResultSet 对象,用于存储查询结果。以下是一个示例:
try {String sql = "SELECT * FROM users WHERE age > ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);// 设置参数preparedStatement.setInt(1, 25);// 执行查询ResultSet resultSet = preparedStatement.executeQuery();// 处理查询结果while (resultSet.next()) {String username = resultSet.getString("username");int age = resultSet.getInt("age");System.out.println("Username: " + username + ", Age: " + age);}
} catch (SQLException e) {e.printStackTrace();
}
在上述示例中,我们执行了一个带有占位符的查询操作,并通过 setInt 方法设置了占位符的参数值,然后使用 executeQuery 方法执行查询,最后遍历 ResultSet 获取查询结果。
执行更新
要执行更新操作(如插入、更新、删除),可以使用 executeUpdate 方法。以下是一个示例:
try {String sql = "UPDATE users SET age = ? WHERE username = ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);// 设置参数preparedStatement.setInt(1, 28);preparedStatement.setString(2, "Alice");// 执行更新int rowCount = preparedStatement.executeUpdate();// 输出更新的行数System.out.println("Updated " + rowCount + " rows.");
} catch (SQLException e) {e.printStackTrace();
}
在上述示例中,我们执行了一个带有占位符的更新操作,通过 setInt 和 setString 方法设置了占位符的参数值,然后使用 executeUpdate 方法执行更新操作,并输出更新的行数。
执行批处理
PreparedStatement 还支持批处理,即一次性执行多个 SQL 语句。这对于需要频繁执行相似 SQL 语句的情况非常有用,可以提高性能。以下是一个批处理的示例:
try {String insertSql = "INSERT INTO users (username, age) VALUES (?, ?)";String updateSql = "UPDATE users SET age = ? WHERE username = ?";// 创建 PreparedStatement 对象PreparedStatement insertStatement = connection.prepareStatement(insertSql);PreparedStatement updateStatement = connection.prepareStatement(updateSql);// 设置参数并添加到批处理中for (int i = 1; i <= 3; i++) {insertStatement.setString(1, "User" + i);insertStatement.setInt(2, 25 + i);insertStatement.addBatch();updateStatement.setInt(1, 30 + i);updateStatement.setString(2, "User" + i);updateStatement.addBatch();}// 执行批处理int[] insertResult = insertStatement.executeBatch();int[] updateResult = updateStatement.executeBatch();// 输出批处理结果System.out.println("Inserted rows: " + Arrays.toString(insertResult));System.out.println("Updated rows: " + Arrays.toString(updateResult));
} catch (SQLException e) {e.printStackTrace();
}
在上述示例中,我们创建了两个 PreparedStatement 对象,并使用 addBatch 方法将多个 SQL 语句添加到批处理中,然后使用 executeBatch 方法一次性执行批处理中的所有 SQL 语句。
关闭 PreparedStatement
在使用完 PreparedStatement 后,应该及时关闭它以释放资源。可以使用 close 方法来关闭 PreparedStatement。以下是一个关闭 PreparedStatement 的示例:
try {// 创建 PreparedStatement 对象PreparedStatement preparedStatement = connection.prepareStatement(sql);// 设置参数...// 执行操作...// 关闭 PreparedStatementpreparedStatement.close();
} catch (SQLException e) {e.printStackTrace();
}
总结
PreparedStatement 是 JDBC 中用于执行预编译 SQL 语句的重要接口,它具有高效性、安全性和可维护性的优势。在实际应用中,使用 PreparedStatement 能够有效地防止 SQL 注入攻击,并提高数据库操作的性能。通过本文的介绍,您应该对 PreparedStatement 的基本概念和使用方法有了更清晰的理解。在编写数据库相关的 Java 应用程序时,不妨考虑使用 PreparedStatement 来执行 SQL 操作。
| 作者信息 作者 : 繁依Fanyi CSDN: https://techfanyi.blog.csdn.net 掘金:https://juejin.cn/user/4154386571867191 |
相关文章:
【Java 进阶篇】JDBC PreparedStatement 详解
在Java中,与关系型数据库进行交互是非常常见的任务之一。JDBC(Java Database Connectivity)是Java平台的一个标准API,用于连接和操作各种关系型数据库。其中,PreparedStatement 是 JDBC 中一个重要的接口,用…...
嵌入式Linux应用开发-驱动大全-第一章同步与互斥①
嵌入式Linux应用开发-驱动大全-第一章同步与互斥① 第一章 同步与互斥①1.1 内联汇编1.1.1 C语言实现加法1.1.2 使用汇编函数实现加法1.1.3 内联汇编语法1.1.4 编写内联汇编实现加法1.1.5 earlyclobber的例子 1.2 同步与互斥的失败例子1.2.1 失败例子11.2.2 失败例子21.2.3 失败…...
【计算机网络】 基于UDP的简单通讯(客户端)
文章目录 客户端流程代码实现添加头文件以及库依赖加载库创建套接字发送接收数据关闭套接字、卸载库 测试 客户端 流程 客户端跟服务端差不多,也要先加载库,在加载库之后也要创建套接字,但是客户端一定是没有绑定ip地址的,之后是…...
【云备份项目】:环境搭建(g++、json库、bundle库、httplib库)
文章目录 1. g 升级到 7.3 版本2. 安装 jsoncpp 库3. 下载 bundle 数据压缩库4. 下载 httplib 库从 Win 传输文件到 Linux解压缩 1. g 升级到 7.3 版本 🔗链接跳转 2. 安装 jsoncpp 库 🔗链接跳转 3. 下载 bundle 数据压缩库 安装 git 工具 sudo yum…...
电脑右键新建记事本不见了--设置恢复篇(无需操作注册表)
电脑右键新建记事本不见了–设置恢复篇(无需修改注册表) 电脑不知怎么想右键新建记事本结果竟然不见了,搜寻网上的都是什么修改注册表,粘贴代码修复(感觉太复杂了),这里介绍通过设置内重新对记…...
JavaScript内置对象 - Array数组(四)- 序列生成器
序列生成器是生成一个指定起始值和结束值的序列,并且根据指定间隔长度,生成序列数组。 完成此功能需要使用到Array内置对象的from()对象,以及类数组相关知识,前面几篇有相关案例进行演示。 地址一:JavaScript内置对象…...
GD32F103x IIC通信
1. IIC通信 1.IIC的介绍 IIC总线有两条串行线,其一是时钟线SCK(同步),其二是数据线SDA。只有一条数据线属于半双工。应用中,单片机常常作为主机,外围器件可以挂载多个。(当然主机也可以有多个。…...
什么是FOSS
FOSS 是指 自由和开放源码软件(Free and Open Source Software)。这并不意味着软件是免费的。它意味着软件的源代码是开放的,任何人都可以自由使用、研究和修改代码。这个原则允许人们像一个社区一样为软件的开发和改进做出贡献。...
C++语言GDAL批量裁剪多波段栅格图像:基于像元个数裁剪
本文介绍基于C 语言的GDAL模块,按照给定的像元行数与列数,批量裁剪大量多波段栅格遥感影像文件,并将所得到的裁剪后新的多波段遥感影像文件保存在指定路径中的方法。 在之前的文章中,我们多次介绍了在不同平台,或基于不…...
简单丝的tab切换栏(html/CSS)
#html <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>CSS实现左右滑动选项卡效果</title><link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/meyer-res…...
LabVIEW开发带式谱感测技术
LabVIEW开发带式谱感测技术 如今,通过无线网络传输的数据量正在迅速增加,并导致频谱稀缺。超过数十亿的无线设备将被连接起来,并需要互联网接入。因此,无线电频谱管理方案的效率不足以授予对所有设备的访问权限。在频谱分配中&am…...
认识柔性数组
在C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员 限制条件是: 结构体中最后一个成员未知大小的数组 1.柔性数组的形式 那么我们怎样写一个柔性数组呢 typedef struct st_type {int i;int a[0];//柔性数组成员 }ty…...
熔断、限流、降级 —— SpringCloud Alibaba Sentinel
Sentinel 简介 Sentinel 是阿里中间件团队开源的,面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性 Sentinel 提供了两个服务组件…...
python经典百题之反向输出数字
题目:输入一个整数,并将其反转后输出。 程序分析 我们需要对输入的整数进行反转,即将整数的数字反向排列。 方法1:使用字符串反转 解题思路 将整数转换为字符串,然后对字符串进行反转。 代码实现 def reverse_integer_usin…...
复习Day08:哈希表part01:242.有效的字母异位词、349. 两个数组的交集、1. 两数之和、160. 相交链表
之前的blog:https://blog.csdn.net/weixin_43303286/article/details/131765317 我用的方法是在leetcode再过一遍例题,明显会的就复制粘贴,之前没写出来就重写,然后从拓展题目中找题目来写。辅以Labuladong的文章看。然后刷题不用…...
用 Pytest+Allure 生成漂亮的 HTML 图形化测试报告
本篇文章将介绍如何使用开源的测试报告生成框架 Allure 生成规范、格式统一、美观的测试报告。 通过这篇文章的介绍,你将能够: 将 Allure 与 Pytest 测试框架相结合; 如何定制化测试报告内容 执行测试之后,生成 Allure 格式的测…...
Python字符串索引解码乱码谜题
输入数行“数字字母”字符组成的乱码字符串,根据谜题规则解码出乱码字符串中隐藏的单词信息。 (本笔记适合熟悉python字符串索引操作的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”…...
协议栈——收发数据(拼接网络包,自动重发,滑动窗口机制)
目录 协议栈何时发送数据~ 数据长度 IP模块的分片功能 发送频率 网络包序号~利用syn拼接网络包ack确认网络包完整 确定偏移量 服务器ack确定收到数据总长度 序号作用 双端告知各自序号 协议栈自动重发机制 大致流程 ack等待时间如何调整 是…...
传输层协议——TCP、UDP
目录 1、UDP 协议(用户数据报协议) 协议特点 报文首部格式 2、TCP 协议(传输控制协议) 协议特点 报文首部格式 TCP连接建立时的三次握手 TCP拆除连接的四次挥手 TCP的流量控制 TCP的拥塞控制 3、传输层端口号 三类端口…...
优化您的Spring应用程序:缓存注解的精要指南
优化您的Spring应用程序:缓存注解的精要指南 前言详细说明1. Cacheable:2. CacheEvict:3. CachePut:4. Caching:5. CacheConfig: 项目中的实现前提使用 前言 当我们构建和运行Spring应用程序时,…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
