使用PreparedStatement防止SQL注入
使用Statement对象执行静态SQL语句,如果执行了特殊构造的语句,会导致SQL注入,出现安全漏洞。
使用PreparedStatement对象能够防止 SQL 注入。
PreparedStatement对象是预编译的SQL语句的对象,继承自Statement。
什么是预编译的SQL语句?
静态SQL语句
1
| String sql = "select * from user where username = '" + username + "' and password = ' " + password + "'";
|
改为预编译的SQL语句:
1
| String sql = "select * from user where username = ? and password = ? ";
|
编写SQL语句时,不使用字符串进行拼接,而是使用问号?占位符代替变量。
使用JDBC的步骤有所变化:
- 注册驱动
- 获取连接对象
- 创建SQL语句
- 创建执行SQL语句的PreparedStatement对象
- 给 ? 赋值
- 执行SQL语句
- 释放资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| public static void main(String[] args) { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useSSL=false", "root", "123456"); String username = "行小观"; String password = "1234"; String sql = "select * from user where username = ? and password = ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, username); pstmt.setString(2, password); rs = pstmt.executeQuery(); while (rs.next()) { int id = rs.getInt("id"); String unm = rs.getString("username"); String pwd = rs.getString("password"); System.out.println(id + "--"+ unm + "--" + pwd); }
} catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } }
if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
|