首页 > 代码库 > Java PreparedStatement

Java PreparedStatement

PreparedStatement是一个用于执行sql语句的标准接口的对象。它是继承与Statement。根据里氏代换原则。用Statement执行的语句,一定可以用Prepared替换了。那么他们之间有什么不同呢。

PreparedStatement

  • 使用参数化的方式,可以用?表明变量的值位置,执行时根据位置提供变量的值。
  • 该对象是预编译的,多次执行的效率高
  • 安全性方面,高于Statement

Statement

  • 执行没有参数,可以动态的执行sql
  • 没有预编译,每次都是执行。多次执行的效率低 

以上是他们各自的特点。各自具有优点同时也具有自身的缺点。所以我们应根据不同的场合具体使用,不能说谁的优点多就使用谁,具体情况应该具体分析。例如,一个组合的sqlsql是动态的,由于Statement本身具有动态的执行sql特点,若安全性不高,首先考虑它还是很好的选择。


下面我们就做个对比 根据id查询

Statement写法

stringsql ="select * from people p where p.i = "+id;

PreparedStatement写法

stringsql ="select * from people p where p.id = ? ";
preparedstatement ps= connection.preparestatement(sql);

这个写法很熟悉,.NET中是常见的。所以并没有学习什么新鲜的东西。

以上两种写法是截然不同的。记得在vb中我常用的是statmen的写法,那么还不摘掉什么是sql注入,等师父验收的使用,不费吹灰之力就进入了我的系统。而如果使用PreparedStatement就不存在这种方式。验证如下

String sql ="select * from tb_name where name= '"+varname+"' andpasswd='"+varpasswd+"'";
select* from tb_name = '随意' and passwd = '' or '1' = '1';

因为‘1‘=‘1‘肯定成立,所以可以任何通过验证。甚至知道表明就可以删除里面的所有数据了。

当然了这是statement的缺点。而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.

如何使用PreparedStatement

1引入特定包

importjava.sql.PreparedStatement;

importjava.sql.ResultSet;

2实例化PreparedStatement和结果集

PreparedStatementprepstmt = null;

ResultSetrs = null;

3得到sql语句

conn 为Connection类型

prepstmt= conn.prepareStatement(String StrSQl);

4执行sql,得到结果集

rs 为ResultSet类型。

rs= prepstmt.executeQuery(); 

一个完整的事例

importjava.sql.Connection;
importjava.sql.PreparedStatement;//
import java.sql.ResultSet;//结果集包
importjava.sql.SQLException;
importjava.sql.Statement;
importjava.sql.Timestamp;
importjava.util.ArrayList;
importjava.util.Date;
importjava.util.List;
 
importcom.bjpower.drp.sysmgr.domain.User;
importcom.bjpower.drp.util.DbUtil;
importcom.bjpower.drp.util.PageModel;
 
/**
 * 根据用户代码查询用户
 * @param userId
 * @return
 * @throws SQLException
 */
publicUser findUserById(String userId) throws Exception {
StringBuffersql= new StringBuffer();
sql.append("selectuser_id, user_name, password, contact_tel, email, create_date from t_user  where user_id= ?");
Connection conn=null;//连接
PreparedStatement pstmt=null;//实例化PreparedStatement 
ResultSet rs= null;//实例化结果集,存放PreparedStatement查询的结果
User user=null;//返回的User实体对象
try{
conn= DbUtil.getconnection();//创建数据库连接
pstmt=conn.prepareStatement(sql.toString());//得到sql语句
pstmt.setString(1, userId);//传入参数
rs=pstmt.executeQuery();//执行sql语句,得到结果集
//User对象得到结果集中的值
if(rs.next()){
user=newUser();
 
user.setUserId(rs.getString("user_id"));
user.setUserName(rs.getString("user_name"));
user.setPassword(rs.getString("password"));
user.setContactTel(rs.getString("contact_tel"));
user.setEmail(rs.getString("email"));        
user.setCreateDate(rs.getTimestamp("create_date"));        
}
}catch(SQLExceptione){
e.printStackTrace(); 
}finally{
//关闭连接
DbUtil.close(rs);
DbUtil.close(pstmt);
DbUtil.close(conn);
}
returnuser;
}
 

小结

以上是PreparedStatement的基本使用。很向自己在.net中编写的sqlParameter的结合体。知识都是类似的,这次并没什么新东西。回顾对比下,只是多了几个包的引用。继续加油了。