概要:
PreparedStatement 接口继承自 Statement 接口,PreparedStatement 比普通Statement 对象使用起来更加灵活,更有效率。
一、PreparedStatement与Statement相比,具有什么优势?
1、相对比较安全,可以防止sql注入。
2、有预编译功能,相同操作批量数据效率较高。
3、使用PreparedStatement 接口,继承自 Statement接口比Statement对象使用起来更加灵活,更有效率。
二、实例代码
1 import java.sql.*; 2 import java.util.Scanner; 3 import org.apache.log4j.Logger; 4 /** 5 * 使用 Statement 安全性差,存在 SQL 注入隐患。 6 * @author CSEE 7 */ 8 public class Test6 { 9 private static Logger logger = Logger.getLogger(Test6.class.getName()); 10 public static void main(String[] args) { 11 Connection conn = null; 12 Statement stmt = null; 13 ResultSet rs = null; 14 //0、根据控制台提示输入用户账号和密码 15 Scanner input = new Scanner(System.in); 16 System.out.println(" 宠物主人登录"); 17 System.out.print("请输入姓名:"); 18 String name=input.next(); 19 System.out.print("请输入密码:"); 20 String password=input.next(); 21 // 1、加载驱动 22 try { 23 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 24 } catch (ClassNotFoundException e) { 25 logger.error(e); 26 } 27 try { 28 // 2、建立连接 29 conn = DriverManager.getConnection( 30 "jdbc:sqlserver://localhost:1433;DatabaseName=epet", 31 "jbit", "bdqn"); 32 // 3 、判断宠物主人登录是否成功 33 stmt = conn.createStatement(); 34 String sql="select * from master where name='"+name+ 35 "' and password='"+password+"'"; 36 System.out.println(sql); 37 rs = stmt.executeQuery(sql); 38 if(rs.next()) 39 System.out.println(" 登录成功,欢迎您!"); 40 else 41 System.out.println(" 登录失败,请重新输入!"); 42 } catch (SQLException e) { 43 logger.error(e); 44 } finally { 45 // 4、关闭 Statement 和数据库连接 46 try { 47 if (null != stmt) { 48 stmt.close(); 49 } 50 if (null != conn) { 51 conn.close(); 52 } 53 } catch (SQLException e) { 54 logger.error(e); 55 } 56 } 57 } 58 }
注:这就是网上典型的 SQL 注入攻击,原因就在于使用 Statement 接口方法时要进行 SQL
语 句 的 拼 接 , 不 仅 拼 接 繁 琐 麻 烦 , 容 易 出 错 , 还 存 在 安 全 漏 洞 。 而 使 用
PreparedStatement 接口就不存在这个问题。
三、PreparedStatement 比 Statement 好在哪里?
提高了代码的可读性和可维护性。
虽然使用 PreparedStatement 来代替 Statement 会多几行代码,但避免了繁琐
麻烦又容易出错的 SQL 语句拼接,提高了代码的可读性和可维护性。
提高了 SQL 语句执行的性能。
创建 Statement 对象时不使用 SQL 语句做参数,不会解析和编译 SQL 语句,每次
调用方法执行 SQL 语句时都要进行 SQL 语句解析和编译操作,即操作相同仅仅是数
据不同。
创建 PreparedStatement 对象时使用带占位符的 SQL 语句做参数,会解析和编译
该 SQL 语句,在通过 setXxx 方法给占位符赋值后执行 SQL 语句时无需再解析和编
译 SQL 语句,直接执行即可。多次执行相同操作可以大大提高性能。
提高了安全性。
PreparedStatement 使用预编译语句,传入的任何数据都不会和已经预编译的 SQL
语句进行拼接,避免了 SQL 注入攻击。