执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。
在orcle中,statement为sql语句生成执行计划,点击打开链接
select colume from table where colume=1;//一个执行计划
select colume from table where colume=2;//第二个执行计划
//一千个查询就生成一千个执行计划!
PreparedStatement用于使用绑定变量重用执行计划
select colume from table where colume=:x;
//通过set不同数据只需要生成一次执行计划,可以重用
两种实现,同样的结果,速度可是差很多,说了这么少,下面进入主题:
从 5.1开始,mysql支持服务器端的Prepared Statements,他使用在client/server更有优势的binary protocol,(mysql的传统的协议中,再把数据通过网络传输前,需要把一切数据都转换成strings,这样就比原始数据大很多,最后,在服务器端,还必须把string转化成正确的数据格式而binary protocol去除了转换的开销,在被传输前,所有类型都转换成本地的binary类型,这样就减少了cpu转换的开销跟网络的使用)在C API php APT 中都能支持使用 Prepared Statements点击打开链接
PreparedStatement对象不仅包含了SQL语句,而且大多数情况下这个语句已经被预编译过,因而当其执行时,只需DBMS运行SQL语句,而不必先编译。
java,servlet中的PreparedStatement 接口继承了Statement,而Statement 是 Java 执行数据库操作的一个重要接口,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。Statement对象,用于执行不带参数的简单SQL语句。怎么样?来盘酸菜:
PreparedStatement updateSales = con.prepareStatement("UPDATE COFFEES SETSALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75); //sql语句的第一个? 设置值为75 int类型
updateSales.setString(2, "Colombian"); //sql第二个? 值为Colombian string类型
updateSales.executeUpdate();//执行sql
Statement用于执行静态 SQL 语句并返回它所生成结果的对象,同一时间每个 Statement 对象在只能打开一个 ResultSet 对象。因此,如果读取一个 ResultSet 对象与读取另一个交叉,则这两个对象必须是由不同的 Statement 对象生成的。如果存在某个语句的打开的当前 ResultSet 对象,则 Statement 接口中的所有执行方法都会隐式关闭它。点击打开链接
三种 Statement 对象,作为在给定连接上执行 SQL 语句的包容器:
Statement 对象用于执行不带参数的简单 SQL 语句;
PreparedStatement 对象用于执行带或不带 IN 参数的预编译 SQL 语句;
CallableStatement 对象用于执行对数据库已存在的存储过程的调用。
接口:
Statement 接口提供了执行语句和获取结果的基本方法。
PreparedStatement 接口添加了处理 IN 参数的方法;
CallableStatement 添加了处理 OUT 参数的方法。
PreparedStatement 实例包含已编译的 SQL 语句。这就是使语句“准备好”。包含于 PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。IN参数的值在 SQL 语句创建时未被指定。相反的,该语句为每个 IN 参数保留一个问号(“?”)作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX 方法来提供。点击打开链接
pstmt.setString(1, "Hi");//第1个参数 为 Hi String类型
for (int i = 0; i < 10; i++) {
pstmt.setInt(2, i);//第2个参数 为i int类型
int rowCount = pstmt.executeUpdate();
}
PreparedStatement: 数据库会对sql语句进行预编译,下次执行相同的sql语句时,数据库端不会再进行预编译了,而直接用数据库的缓冲区(所以第一次执行消耗是很高的),提高数据访问的效率(但尽量采用使用?号的方式传递参数),如果sql语句只执行一次,以后不再复用。 从安全性上来看,PreparedStatement是通过?来传递参数的,避免了拼sql而出现sql注入的问题,所以安全性较好。在开发中,推荐使用 PreparedStatement。点击打开链接
//在MySQL中 prepare的语法:
PREPARE statement_name FROM preparable_SQL_statement; /*定义*/
EXECUTE statement_name [USING @var_name [, @var_name] ...]; /*执行预处理语句*/{DEALLOCATE | DROP} PREPARE statement_name /*删除定义*/ ;
具体的例子:
mysql> prepare stmt1 from 'select sqrt(pow(?,2)+pow(?,2))as hypotenuse';
mysql> set @a=3;第一个参数
mysql> set @b=4;第二个参数
mysql> execute stmt1 using @a,@b;求斜边
+------------+
| hypotenuse |
+------------+
| 5 |
+------------+
mysql> deallocate prepare stmt1;
mysql> use sys;
mysql> create table mjx(a int not null);
mysql> insert into mjx values(4),(8),(11),(32),(80);
mysql> set @table='mjx';
mysql> set @s=concat('select * from ',@table);
mysql> prepare stmt2 from@s;
mysql> execute stmt2;
+----+
| a |
+----+
| 4 |
| 8 |
| 11 |
| 32 |
| 80 |
+----+
点击打开链接
JDBC驱动的最佳化是基于使用的是什么功能
对于只执行一次的SQL语句选择Statement是最好的.
如果SQL语句被多次执行选用PreparedStatement是最好的.
当使用PreparedStatement池时, 如果一个查询很特殊, 并且不太会再次执行到,那么可以使用Statement.
如果一个查询很少会被执行,但连接池中的Statement池可能被再次执行, 那么请使用PreparedStatement.
在不是Statement池的同样情况下, 请使用Statement.
后记:
PreparedStatement是预编译的,对于批量处理可以大大提高效率.也叫JDBC存储过程;
选择PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次,而且两次之间的差别仅仅是变量的不同。如果仅仅执行了一次的话,它应该和普通的对象毫无差异,体现不出它预编译的优越性。
这篇有点乱哈,感谢阅读