statement和PreparedStatement的区别

2023-05-16

学习总结转载,有改动,建议移步原作者。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yudianxiaoxiao/article/details/100879175


一、语法

两者的语法区别

    statement语法

Statement st=conn.createStatement();
//执行sql语句,放进结果集中,execute执行,executeQuery()放入到结果集中
//executeQuery只能用于查询,execute方法才可以执行insert,update,delete操作。
ResultSet rs=st.executeQuery("select * from emp");

    preparedstatement

String sql="update emp set job=? where job=?";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setString(1,"manager");
ps.setString(2,"managet");
int i=ps.executeUpdate();
System.out.println(i);

二、访问数据库的速度

prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。
createStatement不会初始化,没有预处理,每次都是从0开始执行SQL

PreparedStatement对象不仅包含了SQL语句,而且大多数情况下这个语句已经被预编译过,因而当其执行时,只需DBMS运行SQL语句,而不必先编译。当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,当然也加快了访问数据库的速度。
这种转换也给你带来很大的便利,不必重复SQL语句的句法,而只需更改其中变量的值,便可重新执行SQL语句。选择PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次,而且两次之间的差别仅仅是变量的不同。如果仅仅执行了一次的话,它应该和普通的对象毫无差异,体现不出它预编译的优越性。


三、prepareStatement批量执行:

好处:Update大量的数据时, 先构建一个INSERT语句再多次的执行, 会导致很多次的网络连接.。要减少JDBC的调用次数改善性能, 可以使用PreparedStatement的AddBatch()方法一次性发送多个查询给数据库。

// 初始实现:
PreparedStatement ps = conn.prepareStatement(
                "INSERT into db_user values (?, ?, ?)");
        for (n = 0; n < 100; n++) {
            ps.setString(name[n]);
            ps.setLong(id[n]);
            ps.setInt(salary[n]);
            ps.executeUpdate();
        }
//改进实现:
//使用Batch功能
        PreparedStatement ps = conn.prepareStatement(
                "INSERT into db_user values (?, ?, ?)");
        for (n = 0; n < 100; n++) {
            ps.setString(username[n]);
            ps.setString(password[n]);
            ps.addBatch();
        }
        ps.executeBatch();

四、SQL注入漏洞:

Statement stmt = connect.createStatement();
String sql= "SELECT * FROM cg_user WHERE userId"+ userId +" AND name LIKE " + name";
ResultSet rs = stmt.executeUpdate(sql);

假如入参name的值为 or '1' = '1' 那么SQL是成立的,就会返回所有数据,或者变成这个[‘;drop table cg_user ;],那么SQL拼接后就变成:

SELECT * FROM cg_user WHERE userId='' AND name LIKE '' ; 
drop table cg_user ;

如果使用prepareStatement预编译就不会了,因为SQL语句在程序运行前已经进行了预编译,在程序运行时第一次操作数据库之前,SQL语句已经被数据库分析和编译,对应的执行计划也会缓存下来,之后数据库就会以参数化的形式进行查询。set值永远是把占位符当成data处理。

PreparedStatement preparedStatement = connect.prepareStatement("SELECT * FROM cg_user WHERE userId= ? AND name LIKE ?");  
preparedStatement .setInt(1, '');  
preparedStatement .setString(2, "; drop table cg_user");  
preparedStatement .executeUpdate();  

sql会变成:

SELECT * FROM cg_user WHERE userId='' AND name LIKE '; drop table cg_user'  ;

总结:

    JDBC驱动的最佳化是基于使用的是什么功能,选择PreparedStatement还是Statement取决于你要怎么使用它们,对于只执行一次的SQL语句选择Statement是最好的。相反,如果SQL语句被多次执行选用PreparedStatement是最好的。

    PreparedStatement的第一次执行消耗是很高的,它的性能体现在后面的重复执行,使用PreparedStatement的方式来执行一个针对数据库表的查询,JDBC驱动会发送一个网络请求到数据解析和优化这个查询,而执行时会产生另一个网络请求,在JDBC驱动中,减少网络通讯是最终的目的。如果我的程序在运行期间只需要一次请求, 那么就使用Statement,对于Statement,同一个查询只会产生一次网络到数据库的通讯。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

statement和PreparedStatement的区别 的相关文章

随机推荐

  • 【C语言】数组排序方法总结

    一 冒泡排序 相邻元素两两比较 xff0c 按照要求交换位置 xff0c n个元素一共要比较n 1趟 xff0c 每趟要两两比较未排序元素个数 1次 span class token macro property span class to
  • 【C语言】通讯录实现

    通讯录功能 添加联系人信息 xff08 名字 xff0c 性别 xff0c 年龄 xff0c 电话号码 xff0c 家庭住址 xff09 输出指定联系人信息查找指定联系人信息修改指定联系人信息打印所有联系人信息对所有联系人 xff08 通过
  • 如何把64GB或以上的SD卡格式化为FAT32的格式

    对于64GB或以上的SD卡或U盘 xff0c Windows系统自带的格式化工具只支持格式为exFAT或NTFS格式 但事实上 xff0c FAT32最大可以支持2TB的分区 通过第三方分区工具也支持把64GB或以上的SD卡或U盘格式化成F
  • 【Linux】线程基础知识

    文章目录 一 什么是线程 xff1f 1 线程概念2 重新理解进程3 线程优缺点4 线程周期5 线程调度6 线程工作原理7 线程异常8 线程资源 二 为什么要有线程 xff1f 三 如何控制线程 xff1f 1 Linux支持的POSIX线
  • 【MySQL】数据库基础知识

    文章目录 一 什么是数据库二 为什么要有数据库三 数据库分类四 数据库的基本使用1 MySQL安装2 检查MySQL后端服务器是否启动3 连接MySQL服务器4 服务器 xff0c 数据库 xff0c 表关系5 数据存储逻辑 五 MySQL
  • 【C语言】typedef关键字

    文章目录 一 使用介绍1 对一般类型进行重命名2 对结构体类型进行重命名3 对指针进行重命名4 对数组进行重命名 二 typedef 和 define 的区别 一 使用介绍 typedef 的作用就是对类型进行重命名 xff0c 具体作用在
  • 【C语言】深入理解注释

    文章目录 一 预处理阶段对注释的处理二 注释使用时的注意事项1 C风格的注释无法嵌套使用2 基本注释注意事项3 注释导致的二义性 四 关于注释的一个使用建议 一 预处理阶段对注释的处理 我们知道一个源文件要变成可执行程序的话 xff0c 首
  • 【Java】数组

    文章目录 一 为什么要有数组 xff1f 二 什么是数组 xff1f 1 基本语法2 数组的本质 三 数组的使用1 获取长度 访问元素2 遍历数组3 下标越界 空引用4 数组作为函数参数5 数组作为函数返回值 四 数组拷贝1 手动拷贝2 使
  • Windows下无感后台启动Vmware虚拟机配置方法

    Windows下无感后台启动Vmware虚拟机配置方案 以Ubuntu为例 必要准备 1 在Vmware虚拟机里有一个虚拟机且已经设置静态IP 不同OS设置方法不同 xff0c 这里不再概述 2 Windows 需安装 Windows Te
  • Ubuntu桌面没有图标的解决方案

    我的ubuntu打开的时候就只有鼠标和背景 xff0c 在网上找了一些方法 当桌面啥也没有时 xff0c 按Ctrl 43 Alt 43 T进入终端 xff0c 然后我在网上 找了这个解决方法 xff1a sudo apt span cla
  • Vmmem进程占用大解决办法

    Vmmem xff08 WSL2 xff09 进程占用大解决办法 艹 xff0c 这玩意属实有点过分了 xff0c 办他 xff01 我们先看看docker设置怎么说 哦 xff0c 大概意思就是要通过这个配置文件来配置docker的占用资
  • 2023-03-12 java 子类对父类所拥有的方法的重命名

    例如 xff1a person 里面有个Id方法 public void Id System out println 34 身份证号 xff1a 34 43 id student引用person类 xff0c 现在我们在student里面改
  • Ubuntu2204LTS基础操作详解

    废话不多 说上干货 Ubuntu2204LTS下载链接 xff1a https ubuntu com download 默认使用root用户操作 或者命令前边加 sudo 关闭图形界面 关闭图形界面 xff0c 启用tty终端登录的方法如下
  • 解决Xamarin开发Android项目时的"Could not create the Java Virtual Machine"错误

    如题 xff0c 笔者在编辑Main axml界面时出现 34 Could not create the Java Virtual Machine 34 错误 xff0c 可按以下步骤解决 xff1a 1 运行注册表编辑器 xff1a 开始
  • Centos 7 虚拟机ifconfig或ip addr时,ens33不显示inet地址(已设置NOBOOT为yes)

    在虚拟机中输入ifconfig或ip addr时 xff0c 出现如下情况 xff1a sudo dhclient ens33 sudo ifconfig ens33 依次执行上面两行 xff0c 之后发现ens33中可以显示inet了 本
  • 7---整数反转

    给你一个 32 位的有符号整数 x x x xff0c 返回将 x x x 中的数字部分反转后的结果 如果反转后整数超过 32 位的有符号整数的范围
  • 使用windows远程连接kali的桌面

    使用windows远程连接kali的桌面 kali操作系统需要做的一些配置 安装xrdp span class token function apt span span class token parameter variable y sp
  • Android Studio模拟器出错无法运行的解决办法

    之前在运行Android Studio项目的时候 xff0c 原本用的是AS上安装过的模拟器 xff0c 然后我中途又把夜神模拟器打开也运行了一下 结果当我再次使用AS上的模拟器时 xff0c 模拟器上总是出现一个白色弹窗 xff0c 里面
  • Spring框架

    目录 一 Spring概述 二 Spring入门程序 xff08 理解控制反转IoC xff09 三 依赖注入 xff08 Dependency Injection xff0c DI xff09 3 1 依赖注入的实现方式 一 Spring
  • statement和PreparedStatement的区别

    学习总结转载 xff0c 有改动 xff0c 建议移步原作者 版权声明 xff1a 本文为博主原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https bl