在敲机房收费系统的时候,就曾经遇到过SQL注入的问题,也写过一篇博客。而在学习java的过程中,有一次遇到了,不错的是,JDBC为我们提供了一个PreparementStatement接口,可以防止SQL的注入,下面介绍一下。
1.SQL注入问题
在以前过程中,总是采取拼接SQL语句的方式,来实现数据的增删改查!
String Sql=select * from user where username="" and password=""
由于没有对拼接的字符进行检查,很容易遭受到恶意的攻击,例如变成如下操作。
select * from user where username='老李' or '1'='1' and password=";
由此及产生了SQL注入的问题。
2.Preparement
PreparedStatement 解决SQL注入原理,运行在SQL中参数以?占位符的方式表示
select * from user where username = ? andpassword = ? ;
将带有?的SQL 发送给数据库完成编译(不能执行的SQL 带有?的SQL 进行编译 叫做预编译),在SQL编译后发现缺少两个参数
PreparedStatement 可以将? 代替参数发送给数据库服务器,因为SQL已经编译过,参数中特殊字符不会当做特殊字符编译,无法达到SQL注入的目的
主要是采取预编译
3.Demo演示
<span style="font-family:SimSun;font-size:18px;"><strong>// 使用PreparedStatement来解决登录操作,可以解决sql注入
public User findUserByUserNameAndPassword(String username, String password) {
String sql = "select * from user where username=? and password=?";
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
// 1.得到连接对象
con = JdbcUtils.getConnection();
// 2.获取操作sql语句对象
pst = con.prepareStatement(sql); // 将sql语句进行预加载.
// 需要对占位符进行传参数
pst.setString(1, username);
pst.setString(2, password);
// 3.操作sql语句
rs = pst.executeQuery();// 注意无参数
// 4.操作结果集
if (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
return user;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}</strong></span>
4.批处理操作
另外PreparementStatement还支持批量SQL语句的操作,有兴趣的可以查一下相关的API,主要方法如下
addBatch(); 添加sql到批处理
executeBatch();执行批处理
5.Demo演示
//PreparedStatement批处理
public class PreparedStatementBatchTest {
public static void main(String[] args) throws ClassNotFoundException,
SQLException {
String sql = "insert into user values(?,?)";
// 1.得到Connection
Connection con = JdbcUtils.getConnection();
// 2.得到PreparedStatement 对象
PreparedStatement pst = con.prepareStatement(sql);
// 3.执行批处理
long l1=System.currentTimeMillis();
for (int i = 1; i <= 10000; i++) {
pst.setInt(1, i);
pst.setString(2, "name" + i);
pst.addBatch(); //添加批处理
if(i%1000==0){
pst.executeBatch();
pst.clearBatch(); //清空批处理语句.
}
}
System.out.println(System.currentTimeMillis()-l1);
pst.executeBatch();
//4.关闭资源
pst.close();
con.close();
}