码迷,mamicode.com
首页 > 其他好文 > 详细

[J2EE] 有关 PreparedStatement

时间:2015-06-29 20:10:58      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:

  今天同事遇到一个问题,简言之,就是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

[J2EE] 有关 PreparedStatement

标签:

原文地址:http://www.cnblogs.com/simple-code/p/4608181.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!