【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 方法可用于不同数据类型的参数设置,例如 setIntsetStringsetDouble 等。以下是一个设置参数的示例:

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();
}

在上述示例中,我们使用 setStringsetInt 方法分别为 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();
}

在上述示例中,我们执行了一个带有占位符的更新操作,通过 setIntsetString 方法设置了占位符的参数值,然后使用 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

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

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

相关文章

跟着顶级科研报告IPCC学绘图:温度折线/柱图/条带/双y轴

复现IPCC气候变化过程图 引言 升温条带Warming stripes&#xff08;有时称为气候条带&#xff0c;目前尚无合适且统一的中文释义&#xff09;是数据可视化图形&#xff0c;使用一系列按时间顺序排列的彩色条纹来视觉化描绘长期温度趋势。 在IPCC报告中经常使用这一方案 IPCC是…

认识柔性数组

在C99中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫做柔性数组成员 限制条件是&#xff1a; 结构体中最后一个成员未知大小的数组 1.柔性数组的形式 那么我们怎样写一个柔性数组呢 typedef struct st_type {int i;int a[0];//柔性数组成员 }ty…

SpringBoot 可以同时处理多少请求

一、前言 首先&#xff0c;在Spring Boot应用中&#xff0c;我们可以使用 Tomcat、Jetty、Undertow 等嵌入式 Web 服务器作为应用程序的运行容器。这些服务器都支持并发请求处理的能力。另外&#xff0c;Spring Boot 还提供了一些配置参数&#xff0c;可以对 Web 服务器进行调…

互联网Java工程师面试题·MyBatis 篇·第二弹

目录 16、Xml 映射文件中&#xff0c;除了常见的 select|insert|updae|delete标签之外&#xff0c;还有哪些标签&#xff1f; 17、Mybatis 的 Xml 映射文件中&#xff0c;不同的 Xml 映射文件&#xff0c;id 是否可以重复&#xff1f; 18、为什么说 Mybatis 是半自动 ORM 映射…

Vue项目搭建图文详解教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 预备工作 请在本地创建文件夹用于存放Vue项目&#xff0c;例如&#xff1a;创建HelloWorld文件夹存放即将创建的Vue新项目。 创建Vue项目 首先&#xff0c;请在DOS中将目录…

踩坑 | vue动态绑定img标签src属性的一系列报错

文章目录 踩坑 | vue项目运行后使用require()图片也不显示问题描述vue中动态设置img的src不生效问题的原因require is not defined 解决办法1&#xff1a;src属性直接传入地址解决办法2 踩坑 | vue项目运行后使用require()图片也不显示 问题描述 在网上查阅之后&#xff0c;发…

深度学习笔记之线性代数

深度学习笔记之线性代数 一、向量 在数学表示法中&#xff0c;向量通常记为粗体小写的符号&#xff08;例如&#xff0c;x&#xff0c;y&#xff0c;z&#xff09;当向量表示数据集中的样本时&#xff0c;它们的值具有一定的现实意义。例如研究医院患者可能面临的心脏病发作风…

<C++> STL_bitset使用和模拟实现

bitset的介绍 位图的引入 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中&#xff1f; 要判断一个数是否在某一堆数中&#xff0c;我们可能会想到如下方法&#xff1a; 将这一堆数进行排序&#xff0…

Linux-正则三剑客

目录 一、正则简介 1.正则表达式分两类&#xff1a; 2.正则表达式的意义 二、Linux三剑客简介 1.文本处理工具&#xff0c;均支持正则表达式引擎 2.正则表达式分类 3.基本正则表达式BRE集合 4.扩展正则表达式ere集合 三、grep 1.简介 2.实践 3.贪婪匹配 四、sed …

STM32Cubemx新建F429基础工程

配置STM32CubeMX 配置KEY 配置USART1 配置RCC Project Manager Toolchain 选择 MDK-ARM Code Generator 配置如下 GENERATE CODE 即可 配置Keil5 魔术棒配置 – Target – 勾选 Use MicroLIB – Debug – Flash Download – 勾选Reset and Run 基础代码 /* Private incl…

GD32F103x IIC通信

1. IIC通信 1.IIC的介绍 IIC总线有两条串行线&#xff0c;其一是时钟线SCK&#xff08;同步&#xff09;&#xff0c;其二是数据线SDA。只有一条数据线属于半双工。应用中&#xff0c;单片机常常作为主机&#xff0c;外围器件可以挂载多个。&#xff08;当然主机也可以有多个。…

AJAX--Express速成

一、基本概念 1、AJAX(Asynchronous JavaScript And XML)&#xff0c;即为异步的JavaScript 和 XML。 2、异步的JavaScript 它可以异步地向服务器发送请求&#xff0c;在等待响应的过程中&#xff0c;不会阻塞当前页面。浏览器可以做自己的事情。直到成功获取响应后&#xf…

【Spring MVC】MVC如何浏览器请求(service方法)

文章目录 1. DispatcherServlet 的 service 方法1.1. processRequest 方法1.2. doService 方法 背景&#xff1a;平时我们学习 MVC 重点关注的时DispatcherServlet 的 doDispatcher 方法&#xff0c;但是在 doDispatcher 方法之前 还有请求处理的前置过程&#xff0c;这个过程…

vue 使用 创建二维数组响应数据 渲染 echarts图标

目前我遇到的情况就是用动态的二维数组数据渲染echarts图标&#xff0c;我们从后端收到的接口一般是个一维数组&#xff0c;需要手动构建并且保证响应式。接下来我做了个案例 一、案例总逻辑 1. 先创建一个vue项目 2. 添加 echarts依赖 3. 模拟数据请求&#xff0c;构建二维数组…

Axios post请求出现500错误

笔者在编写前端form表单传后端数据的时候&#xff0c;出现了以下问题 一、问题场景 当我用axios发送post请求的时候&#xff0c;出现了500错误 笔者找了很长时间错误&#xff0c;代码没问题&#xff0c;后端接口也没问题&#xff0c;后来发现问题出在实体类上了 当前端post请…

数据结构: 数组与链表

目录 1 数组 1.1 数组常用操作 1. 初始化数组 2. 访问元素 3. 插入元素 4. 删除元素 5. 遍历数组 6. 查找元素 7. 扩容数组 1.2 数组优点与局限性 1.3 数组典型应用 2 链表 2.1 链表常用操作 1. 初始化链表 2. 插入节点 3. 删除…

10.03

代码 #include <iostream>using namespace std; class cz { private:int num1; //实部int num2; //虚部 public:cz(){}cz(int a,int b):num1(a),num2(b){}cz(const cz &other):num1(other.num1),num2(other.num2){}~cz(){}const cz operator(const cz &othe…

websocket逆向【python实现http/https拦截】

python实现http拦截 前言:为什么要使用http拦截一、技术调研二、技术选择三、使用方法前言:为什么要使用http拦截 大多数爬虫玩家会直接选择API请求数据,但是有的网站需要解决扫码登录、Cookie校验、数字签名等,这种方法实现时间长,难度高。需求里面不需要高并发,有没有…

5月22日比特币披萨日,今天你吃披萨了吗?

比特币披萨日 1. Laszlo Hanyecz2. 最贵披萨诞生记3. 梭哈买披萨4. 未完待续 2010年5月22日&#xff0c;美国佛罗里达州的程序员Laszlo Hanyecz&#xff08;拉兹洛哈涅克斯&#xff09;用10000个比特币购买了棒约翰&#xff08;Papa Johns&#xff09;比萨店一个价值25美元的奶…

C语言:选择+编程(每日一练Day9)

目录 选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;自除数 思路一&#xff1a; 题二&#xff1a;除自身以外数组的乘积 思路二&#xff1a; 本人实力有限可能对…