[J2EE] 有关 PreparedStatement

今天同事遇到一个问题,简言之,就是PreparedStatement的预编译究竟是怎么发挥作用的...

嘿嘿,说来惭愧,我以前就只知道PreparedStatement比Statement要好,要防SQL注入,就要用PS。

But,它的预编译作用,我却没关注过。现在经过一番研究,我不敢说我已经“了解”了,但是总归是思路清晰了一些,

我把我理解的整理出来希望对大家也有所帮助,有不对的地方请大家指正。

  • 预编译

首先要说的就是“预编译”。我们知道数据库在执行SQL语句的时候,首先要解析这个SQL语句,有一个“执行计划”的概念(差不多就是指寻找执行这个sql语句的一个最优路径)。对于经常执行的sql,数据库会把执行计划给缓存起来,对应的key就是该条sql。那么当再次执行同样的sql的时候,数据库就不再解析了,直接根据key返回相应的执行计划。这就节省了很多时间。

  • PreparedStatement(后面简称PS)

当我们说到PS的时候,可能我们会关心几个问题:

  1. 预编译发生在什么时候
  2. PS何时被缓存起来的

回答第一个问题:

在创建PreparedStatement 对象时就指定了SQL语句,该语句立即发送给DBMS进行编译”。

回答第二个问题:

是当我们执行PS的close()方法时~~~~

  •  TEST

我针对PS cache,做了一个测验,想法是针对同一个SQL,如果我每次取到的PS都是同一个,说明确实是拿的缓存的....

代码如下:

 1 import java.sql.Connection;
 2 import java.sql.DriverManager;
 3 import java.sql.PreparedStatement;
 4 import java.sql.SQLException;
 5
 6 import oracle.jdbc.OracleConnection;
 7
 8
 9 public class Test
10 {
11      static Connection con = null;
12     public static void main(String args[]) throws ClassNotFoundException, SQLException
13     {
14         con = ((oracle.jdbc.OracleConnection)getConnection());
15         PreparedStatement ps0 = getPS(con);
16         ps0.close();
17         PreparedStatement ps1 = getPS(con);
18         ps1.close();
19         System.out.println(ps0==ps1);//如果是true,说明cache发生了作用
20
21
22         con.close();
23         con = null;
24         con = ((oracle.jdbc.OracleConnection)getConnection());
25         PreparedStatement ps2 = getPS(con);
26         ps2.close();
27         con.close();
28         System.out.println(ps1==ps2);//如果是false,说明connection关闭后,会重新缓存
29
30     }
31
32     //获取PS实例
33     public static PreparedStatement getPS(Connection con)throws ClassNotFoundException, SQLException{
34
35            String sql = "select * from cms_turbine t where t.mapping like ?";
36            PreparedStatement ps1 = con.prepareStatement(sql);
37            ps1.setString(1, "hello");
38           return ps1;
39     }
40
41     //建立连接
42     public static Connection getConnection(){
43         if(con == null){
44         try{
45             Class.forName("oracle.jdbc.driver.OracleDriver");
46             con = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1523:XXX",xx,xx);
47
48 //下面两句是为了开启cache
49             ((oracle.jdbc.OracleConnection)con).setImplicitCachingEnabled(true);
50             ((oracle.jdbc.OracleConnection)con).setStatementCacheSize(10);
51        }catch(Exception e){
52            e.printStackTrace();
53        }
54         }
55         return con;
56     }
57 }

执行结果是: true

false

说明同一个connection中两次取到的PS是同一个实例,不同connection不共用PS。

参考:

http://www.linuxidc.com/Linux/2011-07/38776.htm

http://docs.oracle.com/cd/E11882_01/java.112/e10589/stmtcach.htm#JJDBC28649

时间: 2024-08-28 10:42:55

[J2EE] 有关 PreparedStatement的相关文章

PreparedStatement是如何大幅度提高性能的

本文讲述了如何正确的使用prepared statements.为什么它可以让你的应用程序运行的更快,和同样的让数据库操作变的更快.  为什么Prepared Statements非常重要?如何正确的使用它?  数据库有着非常艰苦的工作.它们接受来自众多并发的客户端所发出的SQL查询,并尽可能快的执行查询并返回结果.处理statements是一个开销昂贵的操作,不过现在有了Prepared Statements这样的方法,可以将这种开销降到最低.可是这种优化需要开发者来完成.所以本文会为大家展示

如何使用PreparedStatement

Statement执行过程 一个sql语句执行过程中,将经历这么几个步骤: 传输sql到数据库. 数据库检查sql的语法合法性,并解析sql. 计算Access Plan.数据库会通过检测index,statistics来给出最优的访问计划. 根据访问计划进行检索,返回数据. 在上面步骤中,第3步是非常耗时的.因此,为了提高性能,数据库会缓存执行语句以及其Access Plan.这被称为statement cache.在statement cache中,sql语句本身为key,access pl

J2EE学习篇之--JDBC详解

今天我们来说一下关于JDBC的相关知识,关于JDBC我想大家都不陌生了,而且我记得早就开始使用它了,记得那是大二的时候做课程设计,但是那时候是为了完成任务,所以遇到问题就google,那时候也没有时间去整理,所以这次就来详细说一下关于JDBC的知识 摘要: JDBC(Java Data Base Connectivity,java数据库连接),由一些接口和类构成的API. J2SE的一部分,由java.sql,javax.sql包组成. 应用程序.JDBC API.数据库驱动及数据库之间的关系

java.sql.preparedstatement和java.sql.statement的区别

本文转自CSDN,然后整理了一遍.原文出处:CSDN JDBC(java database connectivity,java数据库连接)的api中的主要的四个类之一的java.sql.statement要求开发者付出大量的时间和精力.在使用statement获取JDBC访问时所具有的一个共通的问题是输入适当格式的日期和时间戳:2002-02-0520:56 或者 02/05/02 8:56 pm. 通过使用java.sql.preparedstatement,这个问题可以自动解决.一个prep

关于PreparedStatement你知道多少

序言 对应PreparedStatement相信大家都很熟悉,那么为什么要用PreparedStatement呢?也许你会回答PreparedStatement为预处理语句,可以提高数据库执行效率.也许还会回答用PreparedStatement可以防止SQL注入.那么再问下,你觉得你对PreparedStatement有足够的了解吗,你在项目中PreparedStatement用对了吗? 原理分析 首先来看下Statement及PreparedStatement执行过程,一个sql语句执行过程

回头探索JDBC及PreparedStatement防SQL注入原理

概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项目中有一些配置项是有时候要变动的,比如数据库的数据源,为了在修改配置时不改动编译的代码,我们把要变动的属性提取到一个配置文件中,比如properties,因为properties里面都是键值对的形式,所以非常便于阅读和维护. 一.首先说说读取properties文件,这个相对路径和绝对路径的问题:

JDBC系列:(3)使用PreparedStatement执行sql语句

执行sql语句的接口 接口 作用 Statement接口 用于执行静态的sql语句 PreparedStatement接口 用于执行预编译sql语句 CallableStatement接口 用于执行存储过程的sql语句(call xxx) PreparedStatement Vs Statement 序号 不同 描述 1 语法不同 PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql 2 效率不同 PreparedStatement可以使用sql缓存区

【J2EE浅析】——EJB

一.EJB概述 EJB(EnterpriseJava Bean)--java企业Bean,是J2EE十三种规范的一部分,为服务器端组件模型,设计目标与核心应用是部署分布式应用程序.EJB是java的核心代码,包括三种Bean类型:会话Bean(Session Bean),实体Bean(EntityBean)和消息驱动Bean(MessageDriven Bean). 通俗的说,EJB就是一个运行在独立的服务器上,封装了业务逻辑的组件.在一个商务软件中,核心部分就是其业务逻辑,它抽象了整个商务过程

J2EE的13个规范之(二) JDBC 及其使用

我想大家都知道ODBC是什么?ODBC(OpenDatabaseConnectivity,开放数据库互连)是微软公司开放服务结构(WOSA,WindowsOpenServicesArchitecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口). JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写