124.Statement
Statement基本介绍:
-
Statement对象用于执行静态SQL语句并返回其生成的结果的对象
-
在连接建立后,需要对数据库进行访问,执行命名或是SQL语句,可以通过Statement【存在SQL注入】,PreparedStatement【预处理】,CallableStatement【存储过程】
-
Statement对象执行SQL语句,存在SQL注入风险
-
SQL注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段或命令,恶意攻击数据库
-
要防范SQL注入,只要用PreparedStatement(从Statement扩展而来)取代Statement就可以了
举例子:
--查找某个管理是否存在 SELECT * FROM adminWHERE NAME = 'tom' AND pwd = '123'--SQL注入 --用户名为 1' OR --密码为 or '1'='1 SELECT *FROM adminWHERE 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();//如果希望看见注入效果,要用nextLineSystem.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.得到StatementStatement statement = connection.createStatement();//4.组织sqlString 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();//如果希望看见注入效果,要用nextLineSystem.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,不要在写 sqlResultSet 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();//如果希望看见注入效果,要用nextLineSystem.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语句,用 executrUpdateint rows = preparedStatement.executeUpdate();System.out.println(rows > 0 ? "执行成功" : "执行失败"); //关闭连接preparedStatement.close();connection.close();} }