文档章节

关于PreparedStatement你知道多少

Amui
 Amui
发布于 2016/04/12 15:14
字数 900
阅读 34
收藏 1

序言 

对应PreparedStatement相信大家都很熟悉,那么为什么要用PreparedStatement呢?也许你会回答PreparedStatement为预处理语句,可以提高数据库执行效率。也许还会回答用PreparedStatement可以防止SQL注入。那么再问下,你觉得你对PreparedStatement有足够的了解吗,你在项目中PreparedStatement用对了吗?

原理分析

首先来看下Statement及PreparedStatement执行过程,一个sql语句执行过程中,将经历这么几个步骤:

1、传输SQL给数据库

2、数据库验证并解析SQL

3、计算Access Plan。数据库会通过检测index,statistics来给出最优的访问计划。

4、根据访问计划进行检索,返回数据。

在上面步骤中,第3步是非常耗时的。因此,为了提高性能,数据库会缓存执行语句以及其Access Plan。这被称为statement cache。在statement cache中,sql语句本身为key,access plan为value。当相同的sql语句被发送过来时,数据库会使用缓存中的access plan以节省cpu时间。

下边看下Statement执行代码:

1
2
3
4
5
6
7
8
Statement statement =connection.createStatement();
String sql1="Select * from test where id=1";
String sql2="Select * from test where id=";
statement.execute(sql1);
statement.execute(sql1);
statement.execute(sql1);
statement.execute(sql2+"2");
statement.execute(sql2+"3");

sql1在第一次执行的时候,需要计算执行计划。但在第2和3次执行的时候,会使用缓存好的执行计划,因此后面的sql1不会再重新检验语法与计算执行计划,效率会比第一次高。

sql2却每次都在变化,在cache中,key为整个sql语句,所以每次sql2都无法命中cache,即使它仅仅参数不同,也必须重新检验语法与计算执行计划,效率自然就低下。

强大的数据库会在cache命中上做优化,但复杂的语句还是避免不了miss。

PreparedStatement的存在是为了避免sql2的劣势。看下面code。
1
2
3
4
5
6
String sql2="Select * from test where id=?";
PreparedStatement pstmt =connection.prepareStatement(sql2);
pstmt.setInt(1,2);
pstmt.executQuery();
pstmt.setInt(1,3);
pstmt.executQuery();

PreparedStatement在创建的时候,会将参数化的语句发送给数据库,进行语法检测和执行计划计算。Cache中的key将是参数化的语句。当后面preparedstatement在执行的时候,每次均会命中cache,使用已存在的access plan进行检索。

如何正确使用

PreparedStatement的生命周期跟Statement一样,在一个数据库连接connection范围内有效,所以说如果一次连接中对于同一个PreparedStatement处理多次(参数不同),那么用PreparedStatement是可以提高效率,但大多情景都是多次连接中处理同一个PreparedStatement,那么就算使用了PreparedStatement也不能提高效率,比较PreparedStatement的生命周期只在Connection中。那么如何正确的使用PreparedStatement呢?

其实不用紧张,告诉大家个好消息,J2EE服务器的连接池管理器已经实现了缓存的使用。J2EE服务器保持着连接池中每一个连接准备过的prepared statement列表。当我们在一个连接上调用preparedStatement时,应用服务器会检查这个statement是否曾经准备过。如果是,这个PreparedStatement会被返回给应用程序。如果否,调用会被转给JDBC驱动程序,然后将新生成的statement对象存入连接缓存。

如果项目未使用数据库连接池怎么办呢,这里只能告诉你,原理你已经很清楚了,自己实现吧。

本文转载自:http://www.2cto.com/database/201409/338157.html

共有 人打赏支持
Amui
粉丝 2
博文 78
码字总数 40874
作品 0
广州
程序员
关于 Db类中的批处理batch操作

@JFinal 波哥你好,我有个小小的建议,希望能考虑一下,是关于 Db类中的批处理batch操作的。 从我个人而言,我使用最多就是读取文件的中的数据,进行批量入库 (oracle数据库),其中有个问题...

ForJustice
2012/11/07
1K
4
JDBC使用预编译SQL的好处

首先是效率性 PreparedStatement可以尽可能的提高访问数据库的性能,我们都知道数据库在处理SQL语句时都有一个预编译的过程,而预编译对象就是把一些格式固定的SQL编译后,存放在内存池中即数...

liangtee
2012/10/17
0
0
一劳永逸的数据库编码解决方案

问题提出 现在几乎所有的应用系统都无法避免使用数据库系统。在JAVA世界里访问数据库是一件非常轻松的事情,JDBC为JAVA应用 程序访问数据库提供了一个统一的接口,通过使用JDBC接口开发者无需...

红薯
2008/10/05
699
0
通过libzdb连接数据库

一.引用博客一些用法介绍: Libzdb挺强大, 支持MySQL Oracle SQLite PostgreSQL,支持C和C++ Object C,不能在Window下用(看源码是因为基于Linux线程机制编写实现)。 遗憾的是找个资料太费...

Splace
2016/06/22
90
0
关于spring jdbcTemplate取得LAST_INSERT_ID

spring的jdbctemplate提供的方案: jdbctemplate中执行的相关源码

伊人梦醉
2016/06/20
12
0

没有更多内容

加载失败,请刷新页面

加载更多

现场看路演了!

HiBlock
20分钟前
0
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
36分钟前
1
0
官方精简版Windows10:微软自己都看不过去了

微软宣布,该公司正在寻求解决方案,以减轻企业客户的Windows 10规模。该公司声称,企业客户下载整个Windows 10文件以更新设备既费钱又费时。 微软宣布,该公司正在寻求解决方案,以减轻企业...

linux-tao
41分钟前
0
0
TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
今天
1
0
AVA中CAS-ABA的问题解决方案AtomicStampedReference

了解CAS(Compare-And-Swap) CAS即对比交换,它在保证数据原子性的前提下尽可能的减少了锁的使用,很多编程语言或者系统实现上都大量的使用了CAS。 JAVA中CAS的实现 JAVA中的cas主要使用的是...

码代码的小司机
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部