SQL注入问题
在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全问题
1.例如: 输入的用户名随意,输入的密码:a’ or ‘a’ = ‘a
-
定义sql的代码如下:
// 定义sql String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
如果根据所给例子输入随意的用户名和密码
a’ or ‘a’ = ‘a
,则最终执行的sql语句为:select * from user where username = ‘sadasadas’ and password = ‘a’ or ‘a’ = ‘a’
。由于**‘a’=‘a’**是一个恒等式,所以结果为true,因此该条sql的where判断结果会为true,查询user表中的所有数据。 -
sql的执行和登录判断代码如下:
// 执行sql查询语句 rs = stmt.executeQuery(sql); // 判断是否登录成功 if (rs != null) { System.out.println("登录成功!"); } else { System.out.println("登录失败!"); }
由于
rs
不为空。所以程序会判断登陆成功,出现安全隐患。
2. 使用PreparedStatement对象来解决sql注入问题
- 步骤如下:
-
导入驱动包
-
注册驱动
-
获取数据库连接对象
Connection
-
定义sql
注意:sql的参数使用?作为占位符。如:selelct * from user where username = ? and password = ?;
-
获取执行sql语句的对象
PreparedStatement ps = Connetion.prepareStatement(String sql);
-
给占位符?赋值:
ps.setXxx(参数1,参数2)
- 参数1:?位置编号,从1开始
- 参数2:?的值
-
执行sql,接收返回结果,不需要传递sql语句,在获取
PreparedStatement
对象时已经传递了 -
处理结果
-
释放资源
-
- 通常都会使用
PreparedStatement
来完成增删改查的所有操作- 可以防止SQL注入
- 效率更高