PreparedStatement
是Statement
接口的子接口,继承于父接口中全部的方法.它是一个预编译的SQL语句对象PreparedStatement
对象中. 而后可使用此对象屡次市郊地执行该语句与Statement
相似, 都是经过Connection
进行建立建立sql
Connection接口中的方法 | 说明 |
---|---|
PreparedStatement prepareStatement(String sql) |
指定预编译的SQL语句 |
Statement
相似,接口经常使用方法名都是int executeUpdate()
与ResultSet executeQuery
Statement
不一样,上述两个方法是没有参数的.由于在构造PrepareStatement
对象时,就已经传入SQL进行了预编译经常使用方法 | 说明 |
---|---|
int executeUpdate() |
执行insert / update / delete 语句.返回受影响的行数 |
ResultSet executeQuery() |
执行select语名.返回结果集对象Result |
select * from test_02 where name = ? and password = ?
PreparedStatement
对象setXxx
方法public class LoginTest02 { public static void main(String[] args) throws SQLException { // 1.获取链接 Connection conn = JDBCUtils.getConnection(); // 2.使用占位符建立sql语句,获取prepareStatement对象 // 使用?占位符的方式来设置参数 String sql = "select * from test_02 where name = ? and password = ?"; PreparedStatement preparedStatement = conn.prepareStatement(sql); // 3.提示用户输入用户名和密码 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String user = sc.next(); System.out.println("请输入密码:"); String pass = sc.next(); // 4.替换占位符,执行sql语句 // 设置参数,使用setXXX(int 占位符位置 从1开始, 要设置/替换的值)的方法设置占位符的参数 preparedStatement.setString(1,user); // 设置第一个问号值为name preparedStatement.setString(2,pass); ResultSet resultSet = preparedStatement.executeQuery(); // 5.处理结果集,判断是否登陆成功 if(resultSet.next()){ System.out.println("登陆成功!欢迎:" + user); }else{ System.out.println("登陆失败!"); } // 6.关闭对象 JDBCUtils.close(conn,preparedStatement,resultSet); } }
这里提示登陆失败,也就是SQL注入的方式没有成功.
缘由是: 刚刚咱们使用了?做为占位符,那么在输入密码时,不管输入什么,其实都会总体以String形式赋值给sql语句.
因此这里最终的sql语句实际上是select * from test_02 where name = 'wdm' and password = "'0704' or '1' = '1' "
. 很明显, 这个就不会返回正常结果数据库
Statement
用于执行静态SQL语句,在执行时,必须指定一个事先准备好的SQL语句PreparedStatement
是预编译的SQL语句对象,语句中能够包含动态参数"?", 在执行时能够为"?"动态设置参数值PreparedStatement
能够减小编译次数提升数据库性能