PreparedStatement接口
为什么使用PreparedStatement接口?
我们使用Statement接口有一个缺点。我们在精心设计内容时,用户名和密码都是错误的时候也可以登录成功比如输入密码的时候 12 ‘or’1‘=‘1;这样就会登录成工。这就是典型的sql注入攻击。原因是在使用Statement接口方式要进行SQl语句的拼接不仅麻烦,容易出错,还存在安全漏洞。而在使用PreparedStatement接口就不存在这个问题,PreparedStatement接口的优点还不仅如此后面会比较一下PreparedStatement接口和statement接口的区别。
使用PreparedStatement更新信息
我们上面说了PreparedStatement接口的优点,在使用之前我们先了解以下方法。
方法名称 | 作用 |
---|---|
boolean exectute() | 在此PreparedStatement对象中执行SQL语句,该语句可以是任何SQL语句。如果是Result对象,则返回true,如果是更新计数或没有结果,则返回false |
ResultSet executeQuery() | 在此PreparedStatement对象中执行SQl查询,并返回查询生成的ResultSet对象 |
int executeUpdate() | 在此PreparedStatement对象中执行SQL语句,该语句必须是一个DML语句,如INSERT,UPDATE或DELETE语句;或者是无法返回内容的SQl语句,如DDL语句。返回值是执行该操作所影响的行数 |
void setInt(int index,int x) | 将指定参数设置给定JAva int值。设置其他类型参数的方法于此方法类似,如setFloat(int index,float x),setDouble(int index,double x)等 |
void setObject(int index,Object x) | 使用给定设置指定参数的值 |
使用PreparedStatement接口数据库的进本步骤有三步。
(1)创建PreparedStatement对象
通过Connection接口的PreparedStatement(String sql)方法创建PreparedStatement对象,SQl语句可具有一个或多个输入参数。这些输入参数的值在SQL语句创建时未被指定,而是每个输入参数保留一个问号(“?”)作为占位符。
以下的代码段(其中conn是Connection对象)将创建包含带有三个输入参数的SQl语句的PreparedStatement对象。
PreparedStatement pstmt=con.prepareStatement("Update dog set health=?,love=? where id=?");
(2)设置每个输入参数的值
通过调用setXXX()方法来完成,其中xxx是该参数相应的类型。例如,若参数是String类型,则使用的方法是setString()。setXxx()方法的第一个参数是要设置参数的序数位置(从1开始计数),第二个参数是设置给该参数的值。例如,以下代码将第一参数设置为整数型值80,第二个参数设置为整形值15,第三个设置为整形值1.
pstmt.setInt(1,80);
pstmt.setInt(2,15);
pstmt.setInt(3,1);
3)执行SQl语句
在设置个各个输入参数的值后,就可以调用PreparedStatement接口的三个执行方法(ResultSet executeQuery(),int executeUpdaye(),boolean execute())之一来执行SQL语句。
注意这三个执行方法和Statement接口中三个方法名称相同,作用相同,但是不需要SQL语句做参数,SQL语句已经在创建对象PrepareStatement时指定了。例如:
pstmt.executeUpdate();
创建PrepareStatement对象会对SQl语句进行预编译,所以执行速度要快于Statement对象。因此,如果在程序中需要多次执行sql语句时,应使用preparedStatement对象来执行数据库操作,以提高效率。
try{
String sql="update dog set health=?,love=?,where id=?"
pstmt=conn.prepareStatement(sql);
pstmt.setInt(1,80);
pstmt.setInt(2,15);
pstmt.setInt(3,1);
pstmt.executeUpdate();
}
PreparedStatement比Statement好在哪里?
1提高了代码的可读性和可维护性。虽然使用PreparedStatement来替代Statement会多几行代码,但避免了烦琐麻烦又容易出错的SQl语句拼接,提高了代码的可读性和可维护性。
2.提高了SQL语句执行的性能。创建Statement对象时不使用SQL语句做参数,不会解析和编译SQl语句,每次调用方法执行SQL语句时都要进行SQl语句解析和编译操作,即操作相同仅仅是数据不同。
创建PreparedStatement对象时使用SQl语句做参数,会解析和编译该SQL语句。也可以使用带用占位符的SQL语句做参数,在通过setXXX()方法给占位符赋值后执行SQl语句时无须在解析和编译SQL语句,直接执行即可。多次执行相同的操作可以大大提高性能。
3.提高了安全性。PreparedStatement使用预编译语句,传入的任何数据都不会和已经预编译的SQl语句进行拼接,避免了SQL注入攻击。