124.Statement
Statement基本介绍:
-
Statement对象用于执行静态SQL语句并返回其生成的结果的对象
-
在连接建立后,需要对数据库进行访问,执行命名或是SQL语句,可以通过Statement【存在SQL注入】,PreparedStatement【预处理】,CallableStatement【存储过程】
-
Statement对象执行SQL语句,存在SQL注入风险
-
SQL注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段或命令,恶意攻击数据库
-
要防范SQL注入,只要用PreparedStatement(从Statement扩展而来)取代Statement就可以了
举例子:
--查找某个管理是否存在 SELECT * FROM admin WHERE NAME = 'tom' AND pwd = '123' --SQL注入 --用户名为 1' OR --密码为 or '1'='1 SELECT * FROM admin WHERE NAME = '1' OR ' AND pwd = 'OR '1' = '1' //这样就被注入了,无论怎么查询都可以查到人
用代码在IDEA测试
public class TestJava { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { Scanner scanner = new Scanner(System.in); //让用户输入账号和密码 System.out.print("请输入管理员的名字");//next:接收 空格 或 单引号 表示结束,nextLine回车才是结束 String admin_name = scanner.nextLine();//如果希望看见注入效果,要用nextLine System.out.print("请输入管理员的密码"); String admin_pwd = scanner.nextLine(); //通过Properties对象获取配置文件的信息 Properties properties = new Properties(); properties.load(new FileInputStream("src\\mysql.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //1.注册驱动 Class.forName(driver); //2.得到连接 Connection connection = (Connection) DriverManager.getConnection(url, user, password); //3.得到Statement Statement statement = connection.createStatement(); //4.组织sql String sql = "select name , pwd from admin where name='" + admin_name + "' and pwd = '"+admin_pwd +"'"; ResultSet resultSet = statement.executeQuery(sql); if (resultSet.next()){//如果查询到一条记录,则说明该用户存在 System.out.println("恭喜:登陆成功"); } else { System.out.println("对不起:登陆失败"); } //关闭连接 resultSet.close(); statement.close(); connection.close(); } }
125.PreparedStatement
基本介绍
-
PreparedStatement执行的SQL语句中的参数用问号(?)来表示,调用PreparedStatement对象的setXxx()方法来设置这些参数,setXxx()方法有两个参数,第一个参数是要设置的SQL语句中的参数的索引(从1开始),第二个是设置的SQL语句中的参数的值
-
调用executeQuery():返回ResultSet对象
-
调用executeUpdate():执行更新,包括增删改修
预处理好处:
-
不再使用 + 拼接sql语句,减少语法错误
-
有效的解决了sql注入问题
-
大大减少了编译次数,效率较高
public class TestJava { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { Scanner scanner = new Scanner(System.in); //让用户输入账号和密码 System.out.print("请输入管理员的名字");//next:接收 空格 或 单引号 表示结束,nextLine回车才是结束 String admin_name = scanner.nextLine();//如果希望看见注入效果,要用nextLine System.out.print("请输入管理员的密码"); String admin_pwd = scanner.nextLine(); //通过Properties对象获取配置文件的信息 Properties properties = new Properties(); properties.load(new FileInputStream("src\\mysql.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //1.注册驱动 Class.forName(driver); //2.得到连接 Connection connection = (Connection) DriverManager.getConnection(url, user, password); //3.得到PreparedStatement //3.1 组织sql,sql语句的问号相当于占位符 String sql = "select name , pwd from admin where name= ? and pwd = ?"; //3.2 preparedStatement 对象实现了 PreparedStatement 接口的实现类的对象 PreparedStatement preparedStatement = connection.prepareStatement(sql); //3.3 给问号赋值 preparedStatement.setString(1,admin_name); preparedStatement.setString(2,admin_pwd); //4. 执行select语句,用 executrQuery // 如果执行的是 dml(update,inset,delete) executeUpdate() // 执行 executeQuery,不要在写 sql ResultSet resultSet = preparedStatement.executeQuery(); if (resultSet.next()){//如果查询到一条记录,则说明该用户存在 System.out.println("恭喜:登陆成功"); } else { System.out.println("对不起:登陆失败"); } //关闭连接 resultSet.close(); preparedStatement.close(); connection.close(); } }
126.预处理DML
public class TestJava { public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { Scanner scanner = new Scanner(System.in); //让用户输入账号和密码 System.out.print("请输入管理员的名字");//next:接收 空格 或 单引号 表示结束,nextLine回车才是结束 String admin_name = scanner.nextLine();//如果希望看见注入效果,要用nextLine System.out.print("请输入管理员的密码"); String admin_pwd = scanner.nextLine(); //通过Properties对象获取配置文件的信息 Properties properties = new Properties(); properties.load(new FileInputStream("src\\mysql.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); //1.注册驱动 Class.forName(driver); //2.得到连接 Connection connection = (Connection) DriverManager.getConnection(url, user, password); //3.得到PreparedStatement //3.1 组织sql,sql语句的问号相当于占位符 //添加记录 //String sql = "insert into admin values(?,?)"; //修改记录 //String sql = "update admin set pwd = ? where name = ?"; //删除记录 //String sql = "delete from admin where name = ?"; //3.2 preparedStatement 对象实现了 PreparedStatement 接口的实现类的对象 PreparedStatement preparedStatement = connection.prepareStatement(sql); //3.3 给问号赋值 preparedStatement.setString(1,admin_name); preparedStatement.setString(2,admin_pwd); //4. 执行dml语句,用 executrUpdate int rows = preparedStatement.executeUpdate(); System.out.println(rows > 0 ? "执行成功" : "执行失败"); //关闭连接 preparedStatement.close(); connection.close(); } }