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); } } }