SQL注入的问题&使用PreparedStatement对象防止SQL注入
1.SQL注入的问题:sql存在漏洞,会被攻击导致数据泄露
SQL注入是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
在拼接SQL时,有一些sql的特殊关键字参与字符串的拼接,会造成一些安全性的问题

package cn.company.jdbc;
import cn.company.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQL注入 {
public static void main(String[] args) throws SQLException {
login("kuangshen", "123456"); // 正常传参
System.out.println("===========");
login(" 'or '1=1", "123456"); // SQL注入,把所有的信息都盗取出来
}
// 登录业务
public static void login(String username, String password) throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet rs = null;
try {
connection = JdbcUtils.getConnection();
statement = connection.createStatement();
String sql = "select * from users where `name`='"+username+"'AND `password` ='"+password+"'";
rs = statement.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getObject("name"));
System.out.println(rs.getObject("password"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.releaseConnection(connection, statement, rs);
}
}
}


可以看到SQL注入能够把所有的信息盗取出来。
2.解决SQL注入问题
后期都会使用PreparedStatement来完成增删改查的所有操作
使用PreparedStatement可以防止SQL注入,并且效率更高
PreparedStatement防止SQL注入的本质,把传递进来的参数当做字符,假设其中存在转义字符,就直接忽略,比如说 ' 会被直接转义
预编译SQL,参数使用?作为占位符,需要在执行SQL的时候,给?赋值
静态的SQL,之前的Statement用于执行静态SQL语句,所谓静态的,就是SQL语句是字符串拼接的方式,
步骤:
(1)导入驱动jar包
(2)注册驱动(让程序知道是哪个驱动包)
(3)获取数据库链接对象Connection
(4)定义sql
注意:SQL的参数使用?作为占位符,如:select * from user where username=? and password=?;
(5)获取执行sql语句的对象,PreparedSatement Connection.prepareStatement(String sql)
(6)给?赋值:
方法:使用setXxx(参数1,参数2),参数1表示?的位置编号,从1开始;参数2表示?的值
(7)执行sql,接受返回结果,不需要传递SQL语句
(7)处理结果
(8)释放资源
新增:
package cn.company.jdbc;
import cn.company.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.util.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestPreparedStatement {
public static void main(String[] args) throws SQLException {
Connection conn = null;
PreparedStatement statement = null;
try {
conn = JdbcUtils.getConnection();
// 使用占位符?代替参数
String sql = "INSERT INTO users values(?,?,?,?,?)";
statement = conn.prepareStatement(sql);
// 手动给参数赋值
statement.setString(1, String.valueOf(4));
statement.setString(2, "qijiang");
statement.setString(3, "123456");
statement.setString(4,"243555777@qq.com" );
// 注意点:sql.Date 数据库用的
// util.Date java用的 new Date().getTime()获取当前时间戳
statement.setDate(5, new java.sql.Date(new Date().getTime()));
// 执行sql
int i = statement.executeUpdate();
if (i > 0) {
System.out.println("插入成功!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.releaseConnection(conn, statement, null);
}
}
}

删除
package cn.company.jdbc;
import cn.company.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestPreparedStatementDelete {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JdbcUtils.getConnection();
String sql = "delete from users where id=?";
// 预编译
preparedStatement = connection.prepareStatement(sql);
// 手动赋值
preparedStatement.setInt(1, 4); // id=4
// 执行sql
int i = preparedStatement.executeUpdate();
if (i > 0) {
System.out.println("删除成功!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.releaseConnection(connection, preparedStatement, null);
}
}
}
更新
package cn.company.jdbc;
import cn.company.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestPreparedStatementUpdate {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JdbcUtils.getConnection();
String sql = "update users set name=? where id=?";
// 预编译sql
preparedStatement = connection.prepareStatement(sql);
// 手动给参数赋值
preparedStatement.setString(1, "Gump Yan");
preparedStatement.setString(2, "3");
// 执行sql
int i = preparedStatement.executeUpdate();
if (i > 0) {
System.out.println("修改成功!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.releaseConnection(connection, preparedStatement, null);
}
}
}

查询
package cn.company.jdbc;
import cn.company.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestPreparedStatementQuery {
public static void main(String[] args) throws SQLException {
login("lisi", "123456");
// login(" 'or '1=1","123456"); // SQL注入
}
private static void login(String username, String password) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
connection = JdbcUtils.getConnection();
String sql = "select * from users where `name`=? and `password`=?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
rs = preparedStatement.executeQuery();
while (rs.next()) {
System.out.println(rs.getObject("name"));
System.out.println(rs.getObject("password"));
System.out.println("===============");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.releaseConnection(connection, preparedStatement, rs);
}
}
}


浙公网安备 33010602011771号