1、Statement为每一条Sql语句生成执行计划, 如果要执行两条sql语句
select colume from table where colume=1;
select colume from table where colume=2;
会生成两个执行计划,一千个查询就生成一千个执行计划。而生成计划是非常消耗资源的
2、PreparedStatement用于使用绑定变量重用执行计划
select * from xxx.sometable t where t.id=?;
通过set方法给sql语句按占位符"?"先后顺序赋值,只需要生成一个执行计划,可以重复使用。
当处理批量SQL语句时,这个时候就可以体现PrepareStatement的优势,由于采用Cache机制,则预先编译的语句,就会放在Cache中,下次执行相同SQL语句时,则可以直接从Cache中取出来,效率要比statement高好几倍
PreparedStatement类是Statement类的子类,它直接继承并重写了Statement的方法。PrepardStatement类有两大特点:
特点一:一个PreparedStatement的对象中包含的SQL声明是预编译的,因此当需要多次执行同一条SQL声明时,利用PreparedStatement传送这条SQL声明可以大大提高执行效率。
特点二:PreparedStatement的对象所包含的SQL声明中允许有一个或多个IN参数。创建类PreparedStatement的实例时,IN参数用“?”代替。在执行带参数的SQL声明前,必须对“?”进行赋值,为了对“?”赋值,PreparedStatement类中增添了大量的setXXX方法,完成对IN参数赋值。
⑴创建PreparedStatement对象
与创建Statement类的实例方法类似,创建一个PreparedStatement类的对象也只需在建立连接后,调用Connection类中的方法
public abstract PreparedStatement prepareStatement(String sql) throws SQLException;
例 创建一个PreparedStatement的对象,其中包含一条带参数的SQL声明。
PreparedStatement pstmt=con.prepareStatement("INSERT INTO testTable(id,name) VALUES(?,?)");
⑵IN参数的赋值
PreparedStatement中提供了大量的setXXX方法对IN参数进行赋值。根据IN参数的SQL类型应选用合适的setXXX方法。
例 对上例,若需将第一个参数设为3,第二个参数设为XU,即插入的记录id=3,name="XU",可用下面的语句实现:
pstmt.setInt(1,3);
pstmt.setString(2,"XU");
除了setInt,setLong,setString,setBoolean,setShort,setByte等常见的方法外,PreparedStatement还提供了几种特殊的setXXX方法。
①setNull(int ParameterIndex,int sqlType)
这个方法将参数值赋为Null。sqlType是在java.sql.Types中定义的SQL类型号。
例 语句
pstmt.setNull(1,java.sql.Types.INTEGER);
将第一个IN参数的值赋成Null。
②setUnicodeStream(int Index,InputStream x,int length);
setBinaryStream(int Index,inputStream x,int length);
setAsciiStream(int Index,inputStream x,int length);
当参数的值很大时,可以将参数值放在一个输入流x中,再通过调用上述三种方法将其赋于特定的参数,参数length表示输入流中字符串长度。
每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:
insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次.
当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.
Code Fragment 1:
String updateString = "UPDATE COFFEES SET SALES = 75 " + "WHERE COF_NAME LIKE ′Colombian′";
stmt.executeUpdate(updateString);
Code Fragment 2:
PreparedStatement updateSales = con.prepareStatement("UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75);
updateSales.setString(2, "Colombian");
updateSales.executeUpdate();
片断2和片断1的区别在于,后者使用了PreparedStatement对象,而前者是普通的Statement对象。PreparedStatement对象不仅包含了SQL语句,而且大多数情况下这个语句已经被预编译过,因而当其执行时,只需DBMS运行SQL语句,而不必先编译。当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,当然也加快了访问数据库的速度。
这种转换也给你带来很大的便利,不必重复SQL语句的句法,而只需更改其中变量的值,便可重新执行SQL语句。选择PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次,而且两次之间的差别仅仅是变量的不同。如果仅仅执行了一次的话,它应该和普通的对象毫无差异,体现不出它预编译的优越性。
package com.ys;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class DbUtil {
private static String dbDriver = "oracle.jdbc.driver.OracleDriver";
private static String dbURL = "jdbc:oracle:thin:@localhost:1521:orcl";
private static String user = "jhfund";
private static String password = "jhfund";
static {
try {
Class.forName( dbDriver ).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection loadConnection() throws Exception{
Connection connection =
DriverManager.getConnection(dbURL, user, password);
return connection;
}
public static void close(Connection connection) throws Exception{
if(connection!=null)
connection.close();
}
public static void close(Statement statement) throws Exception{
if(statement!=null)
statement.close();
}
public static void close(ResultSet rs) throws Exception{
if(rs!=null)
rs.close();
}
public static void close(PreparedStatement preparedStatement) throws Exception{
if(preparedStatement!=null)
preparedStatement.close();
}
}
package com.ys;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
public class PreparedStatementTest {
public void Add() throws Exception{
String SQL = "insert into student(S_NUM,S_NAME,ID_CARD,ADR) values(?,?,?,?)";
Connection conn = null;
PreparedStatement st = null;
try{
conn = DbUtil.loadConnection();
st = conn.prepareStatement(SQL);
st.setInt(1, "201307043");
st.setDouble(2, "李阳");
st.setString(3,"510724199705181231");
st.setDate(4, "白桥大街15号");
st.execute();
}
catch(Exception e){
throw e;
}
finally{
DbUtil.close(st);
DbUtil.close(conn);
}
}
public void AddBatch()throws Exception{
int a = 1;
double b = 99999.99;
String c = "cat";
java.sql.Date d = new java.sql.Date(2010,1,3);
Connection conn = null;
String SQL = "insert into test(a,b,c,d) values(?,?,?,?)";
PreparedStatement st = null;
try{
conn = DbUtil.loadConnection();
st = conn.prepareStatement(SQL);
for( a = 1;a<1000;a++){
st.setInt(1, a);
st.setDouble(2, b);
st.setString(3,c);
st.setDate(4, d);
st.addBatch();
}
st.executeBatch();
}
catch(Exception e){
throw e;
}
finally{
DbUtil.close(st);
DbUtil.close(conn);
}
}
public void update() throws Exception{
int a = 1;
double b = 10000.00;
String c = "cat";
java.sql.Date d = new java.sql.Date(2010,1,3);
String SQL = "update test set b=?,c=?,d=? where a = ?";
Connection conn = null;
PreparedStatement st = null;
try{
conn = DbUtil.loadConnection();
st = conn.prepareStatement(SQL);
st.setDouble(1, b);
st.setString(2,c);
st.setDate(3, d);
st.setInt(4, a);
st.execute();
}
catch(Exception e){
throw e;
}
finally{
DbUtil.close(st);
DbUtil.close(conn);
}
}
public void del()throws Exception{
int a = 1;
String SQL = "delete test where a = ?";
Connection conn = null;
PreparedStatement st = null;
try{
conn = DbUtil.loadConnection();
st = conn.prepareStatement(SQL);
st.setInt(1, a);
st.execute();
}
catch(Exception e){
throw e;
}
finally{
DbUtil.close(st);
DbUtil.close(conn);
}
}
public void delIN()throws Exception{
String SQL = "delete test where a in ?";
Connection conn = null;
PreparedStatement st = null;
try{
conn = DbUtil.loadConnection();
st = conn.prepareStatement(SQL);
st.setString(1, "(1,2,3)");
st.execute();
}
catch(Exception e){
throw e;
}
finally{
DbUtil.close(st);
DbUtil.close(conn);
}
}
public void query(int a)throws Exception{
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
conn = DbUtil.loadConnection();
st = conn.prepareStatement(SQL);
st.setInt(1, a);
rs = st.executeQuery();
}
catch(Exception e){
throw e;
}
finally{
DbUtil.close(rs);
DbUtil.close(st);
DbUtil.close(conn);
}
}
public void query()throws Exception{
query(0);
}
}
分享到:
相关推荐
1. 存储过程只在创造时进行编译即可,以后每次执行存储过程都不需再重新编译,而我们通常使用的SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。 2. 经常会遇到复杂的业务逻辑和对数据库的...
当客户发送一条SQL语句给服务器后,服务器总是需要校验SQL语句的语法格式是否正确,然后把SQL语句编译成可执行的函数,最后才是执行SQL语句。其中校验语法,和编译所花的时间可能比执行SQL语句花的时间还要多。 ...
而批处理的T-SQL语句每次运行都需要预编译和优化,所以速度就要慢一些。 C、 存储过程减轻网络流量 对于同一个针对数据库对象的操作,如果这一操作所涉及到的T-SQL语句被组织成一存储过程,那么当在客户机上调用该...
3、EXEC 执行纯动态SQL,执行时可能无法使用预编译的执行计划,关键是不安全,可以导致 SQL 注入 ,而 SP_EXECUTESQL 执行参数化动态 SQL ,执行时能使用预编译的执行计划,而且保存存储过程时就可以确定可以使用的预...
当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句。这样就可以提高存储过程的性能。 Ø 存储过程的概念 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在...
Pro*C/C++语言就是在标准C/C++语言中通过嵌入SQL 语句完成对数据库操作的一种语言组织方式,为了编译成可执行程序必须经过Oracle 预编译程序预编译成.c/.cpp 源程序,并由系统c/c++编译器编译成可执行程序。...
SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句
14、一次执行多条SQL语句。 15、代码及文档自定义生成。 16、表、视图、存储过程、触发器等的创建、编译和执行。 17、DB设计书关联功能。(能将表字段逻辑名称关联到工具中) 18、代码及文档生成。 19、二次开发。...
6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。 9、返回了不必要...
如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。可以用一个命令对象来调用存储过程。 3。索引的作用?和它的优点缺点是什么? 答:索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速...
优化:【检查SQL语句是否能够使用索引,SQL语句如何执行效率高,制定一个执行计划】 编译: 执行SQL语句:【把编译过的查询要求提交并进行处理】 如何优化SQL 完善开发的管理 完善代码审核、测试机制,...
软件介绍 大家都知道 sql的使用时间越长.其占用的内存数就越大.由于Sql Server对于...还有一些其他类型的缓存,如执行存储过程时,Sql Server需要先编译再运行,编译后的结果也会缓存起来,下一次就无需再次编译了。
6.2.4 标识SQL语句以便以后取回计划 153 6.2.5 深入理解DBMS_XPLAN的细节 156 6.2.6 使用计划信息来解决问题 161 6.3 小结 169 第7章 高级分组 170 7.1 基本的GROUP BY用法 171 7.2 HAVING子句 174 7.3 GROUP...
还有一些其他类型的缓存,如执行存储过程时,Sql Server需要先编译再运行,编译后的结果也会缓存起来,下一次就无需再次编译了。 这个软件就是为了解决大家的这个问题. 2012年8月11日 3.3版本 1.修正一些软件错误...
java.sql.PreparedStatement 继承Statement接口,表示预编译的SQL语句的对象,SQL语句被预编译并且存储在PreparedStatement对象中。然后可以使用此对象高效地多次执行该语句。 java.sql.CallableStatement 用来...
还有一些其他类型的缓存,如执行存储过程时,Sql Server需要先编译再运行,编译后的结果也会缓存起来,下一次就无需再次编译了。 这个软件就是为了解决大家的这个问题。 剑儿SQL Server内存释放器 v3.2更新内容: ...
还有一些其他类型的缓存,如执行存储过程时,Sql Server需要先编译再运行,编译后的结果也会缓存起来,下一次就无需再次编译了。 这个软件就是为了解决大家的这个问题. ========== 作者:剑儿 QQ:157322145 ★...
这些处理很慢的,php里面有很多操作mysql数据库的函数,无非是把sql语句传递给mysql数据库,真正处理sql语句的是mysql,mysql数据库是要编译sql语句进行执行的,上面这两种操作会对相同的sql语句进行多次编译,有这...
另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口 使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同的感观...