什么是预编译语句
预编译语句PreparedStatement 是java.sql中的一个接口,它是Statement的子接口。通过Statement对象执行SQL语句时,需要将SQL语句发送给DBMS,由 DBMS首先进行编译后再执行。预编译语句和Statement不同,在创建PreparedStatement 对象时就指定了SQL语句,该语句立即发送给DBMS进行编译。当该编译语句被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那 样首先将其编译。
什么时候使用预编译语句
一般是在需要反复使用一个SQL语句时才使用预编译语句,预编译语句常常放在一个for或者while循环里面使用,通过反复设置参数从而多次使用该SQL语句;为了防止SQL注入漏洞,在某些数据操作中也使用预编译语句。
为什么使用预编译语句
1、提高效率
当需要对数据库进行数据插入、更新或者删除的时候,程序会发送整个SQL语句给数据库处理和执行。数据库处理一个SQL语句,需要完成解析 SQL语句、检查语法和语义以及生成代码;一般说来,处理时间要比执行语句所需要的时间长。预编译语句在创建的时候已经是将指定的SQL语句发送给了 DBMS,完成了解析、检查、编译等工作。因此,当一个SQL语句需要执行多次时,使用预编译语句可以减少处理时间,提高执行效率。
2、提高安全性
恶意的SQL语句
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
如果我们把[' or '1' = '1]作为varpasswd传入进来.用户名随意,看看会成为什么?
select * from tb_name = '随意' and passwd = '' or '1' = '1';因为'1'='1'肯定成立,所以可以任何通过验证.更有甚者:
把[';drop table tb_name;]作为varpasswd传入进来,则:select * from tb_name = '随意' and passwd = '';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
如果我们把[' or '1' = '1]作为varpasswd传入进来.用户名随意,看看会成为什么?
select * from tb_name = '随意' and passwd = '' or '1' = '1';因为'1'='1'肯定成立,所以可以任何通过验证.更有甚者:
把[';drop table tb_name;]作为varpasswd传入进来,则:select * from tb_name = '随意' and passwd = '';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.
预编译语句的使用
1、创建 PreparedStatement 对象
以下的代码段(其中 con 是 Connection 对象)创建包含带两个 IN 参数占位符的 SQL 语句的 PreparedStatement 对象:
PreparedStatement pstmt = con.prepareStatement("UPDATE table4 SET m = ? WHERE x = ?");
pstmt 对象包含语句 "UPDATE table4 SET m = ? WHERE x = ?",它已发送给DBMS,并为执行作好了准备。
2、传递 IN 参数
在执行 PreparedStatement 对象之前,必须设置每个 ? 参数的值。这可通过调用 setXXX 方法来完成,其中 XXX 是与该参数相应的类型。例如,如果参数具有Java 类型 long,则使用的方法就是 setLong。setXXX 方法的第一个参数是要设置的参数的序数位置,第二个参数是设置给该参数的值。例如,以下代码将第一个参数设为 123456789,第二个参数设为 100000000:
pstmt.setLong(1, 123456789);
pstmt.setLong(2, 100000000);
一旦设置了给定语句的参数值,其值将一直保留,直到被设置为新值或者调用clearParameters()方法清除它为止。
以下的代码段(其中 con 是 Connection 对象)创建包含带两个 IN 参数占位符的 SQL 语句的 PreparedStatement 对象:
PreparedStatement pstmt = con.prepareStatement("UPDATE table4 SET m = ? WHERE x = ?");
pstmt 对象包含语句 "UPDATE table4 SET m = ? WHERE x = ?",它已发送给DBMS,并为执行作好了准备。
2、传递 IN 参数
在执行 PreparedStatement 对象之前,必须设置每个 ? 参数的值。这可通过调用 setXXX 方法来完成,其中 XXX 是与该参数相应的类型。例如,如果参数具有Java 类型 long,则使用的方法就是 setLong。setXXX 方法的第一个参数是要设置的参数的序数位置,第二个参数是设置给该参数的值。例如,以下代码将第一个参数设为 123456789,第二个参数设为 100000000:
pstmt.setLong(1, 123456789);
pstmt.setLong(2, 100000000);
一旦设置了给定语句的参数值,其值将一直保留,直到被设置为新值或者调用clearParameters()方法清除它为止。
示例:
import java.sql.*;
public class PreparedTest{
Connection con=null;
PreparedStatement update=null;
public void test(){
String sql="UPDATE STUDENT SET AGE=? WHERE ID=?";
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:stu","name","password");
}catch(ClassNotFoundException e){}
catch(SQLException ex){}
try{
update=con.prepareStatement(sql);
for(int i=0;i<6;i++){
update.setInt(1,i+18);
update.setInt(2,i);
update.executeUpdate();
}
update.close();
con.close();
}catch(SQLException ex){}
}
}
相关推荐
总的来说,预编译语句PreparedStatement是Java JDBC中提高性能和保障安全性的重要工具,尤其是在处理大量重复的SQL操作和处理用户输入时。正确使用PreparedStatement,能够有效地优化数据库操作,并增强应用程序的...
1. 执行预编译语句,例如:prepare myfun from 'select * from t_book where bid=?' 2. 设置变量,例如:set @str='b1' 3. 执行语句,例如:execute myfun using @str 如果需要再次执行 myfun,那么就不需要再编译...
JDBC进阶1
5. **PreparedStatement**: 提供预编译的SQL语句,支持参数化查询,提高性能和安全性。 6. **CallableStatement**: 用于执行存储过程的接口,支持输入、输出和输入/输出参数。 7. **ResultSet**: 存储查询结果的游标...
在这个例子中,`StartQueryLook`方法接收一个SQL语句和一个对象数组,数组中的每个元素对应SQL语句中的一个占位符,循环设置参数后执行查询。 总的来说,PreparedStatement在JDBC中扮演着重要角色,尤其是在处理...
在Java数据库连接(JDBC)中,增删改查(CRUD)操作是与数据库交互的基础,事务处理、批处理和预编译SQL语句则是提高效率和保证数据一致性的关键技术。以下是对这些概念的详细说明: 1. **JDBC增删改查(CRUD)**:...
**Statement对象**用于将SQL语句发送到数据库中,它是JDBC中最基本的执行SQL语句的对象。具体来说,JDBC提供了三种类型的`Statement`对象: 1. **Statement**:用于执行简单的SQL语句,特别是那些没有参数的SQL语句...
顺序是:先关闭结果集(ResultSet),再关闭预编译语句(PreparedStatement),最后关闭连接(Connection)。 ```java pstmt.close(); conn.close(); ``` **事务处理** 在处理多条相关SQL语句时,可以使用数据库...
PreparedStatement提供了多种方法来设置参数,如`setString()`, `setInt()`, `setFloat()`等,这些方法对应于SQL语句中的占位符。在案例中,可以看到以下代码用于设置各个参数: ```java pstmt.setString(1, p_...
在执行SQL语句时,我们通常使用`PreparedStatement`而非`Statement`,因为`PreparedStatement`支持预编译的SQL语句,能有效防止SQL注入攻击,并且允许我们以参数化的方式设置SQL语句中的值。这种方式不仅提高了效率...
使用 `Connection.prepareStatement(String sql)` 创建预编译语句对象,然后使用 `setXXX()` 方法设置参数。 - 预编译语句特别适合于多次执行的SQL,因为它们只需要编译一次。 6. **存储过程的使用**: - 存储...
要获取这个预编译语句在执行时的具体SQL,我们需要深入到JDBC驱动的内部或者利用一些第三方工具。由于源码标签的提及,我们可能需要查看JDBC驱动的实现细节,比如MySQL JDBC驱动或Oracle JDBC驱动。这些驱动在执行`...
例如,在Java的JDBC中,我们可以使用PreparedStatement对象来实现预编译,它的优点在于减少解析和编译SQL语句的时间,提升执行速度。 接着,我们来讨论批量提交。在传统的数据库操作中,每次插入、更新或删除操作...
预编译语句(PreparedStatement)是JDBC中的一个重要特性,它提高了性能,同时提供了防止SQL注入的安全性。预编译语句允许开发者提前编译SQL模板,并在运行时动态插入参数,减少了解析SQL的时间。例如,如果需要多次...
虽然题目主要涉及预编译语句,但存储过程也是数据库操作中的重要组成部分。存储过程是一组预编译的SQL语句,存储在数据库中,可以通过调用来执行。在Java中,可以使用CallableStatement来调用存储过程,类似于...
PreparedStatement接口实现了预编译功能,允许我们在SQL语句中使用占位符(如`?`),然后在执行时动态设置参数。这有以下优点: - 提高性能:预编译的SQL语句可以重复使用,避免了每次执行时的编译过程。 - 防止...
2. **预编译语句(PreparedStatement)**:预编译的SQL语句可以显著提升执行速度,同时防止SQL注入攻击。 3. **批处理操作**:允许多个SQL语句一次性提交,减少网络通信次数,提高整体执行效率。 4. **游标支持**:...
MySQL预编译是一种提高数据库操作效率的技术,尤其在处理大量重复SQL语句时效果显著。预编译的主要目的是减少语法检查和编译的开销,从而提升数据库的性能。本文将深入探讨MySQL预编译的概念、好处、执行过程以及...
预编译语句(PreparedStatement)在批处理中尤其有用,因为它可以防止SQL注入并提高性能。预编译语句在首次创建时解析SQL,然后只需替换占位符即可多次使用,减少了解析和编译的时间。 五、注意事项 1. 适当设置...