Statement和PreparedStatement之间的区别

Statement

  1. Statement 对象表示基本语句,其中将单个方法应用于某一目标和一组参数,以返回结果

  2. .构造方法
    public Statement(Object target,String methodName, Object[] arguments)按照所给参数创建一个新的 Statement 对象,使其具有 target、methodName 和 arguments。
    参数:
    target - 此语句的目标。
    methodName - 此语句的 methodName。
    arguments - 此语句的参数。如果该参数为 null,则使用一个空数组。

  3. 每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.

PreparedStatement

  1. PreparedStatement对象表示预编译的 SQL 语句的对象。SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。

  2. 方法:executeQuery ResultSet executeQuery() throws SQLException在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。

  3. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。 安全性好,有效防止Sql注入等问题。

  4. Statement和PreparedStatement之间的区别

Statement和PreparedStatement之间的区别
1:效率

             try {
                 Connection conn = DriverManager.getConnection(url,user,password);
                 String sql = "insert into user (id,name,age,sex) values(?,?,?,?);";
                 Statement p = conn.prepareStatement(sql);
                 p.setString(1, id);
                 p.setString(2, name);
                 p.setInt(3,age);
                 p.setString(4, sex);
                 p.executeUpdate();
                 conn.close();
             } catch (SQLException e) {
                 e.printStackTrace();
             }
     }
Connection conn = DriverManager.getConnection(url,user,password);
                 String sql = "insert into user (id,name,age,sex) values(?,?,?,?);";
                 PreparedStatement p = conn.prepareStatement(sql);
                 p.setString(1, id);
                 p.setString(2, name);
                 p.setInt(3,age);
                 p.setString(4, sex);
                 p.executeUpdate();
                 conn.close();
    专业版本解释:代码一和代码二的区别在于,后者使用了PreparedStatement对象,而前者是普通的Statement对象。

当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,当然也加快了访问数据库的速度。这种转换也给你带来很大的便利,不必重复SQL语句的句法,而只需更改其中变量的值,便可重新执行SQL语句。选择PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次,而且两次之间的差别仅仅是变量的不同。如果仅仅执行了一次的话,它应该和普通的对象毫无差异,体现不出它预编译的优越性。执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。

 小白版本解释:

 Statement对象就像我没装备的旅行包,当我要当天就要旅行时就必须立即装备一些东西放入旅行包,需要花时间装备好。
 PreparedStatement对象就像我准备好的旅行包,当我今天就去旅行我就拿上我的旅行包立即去旅行,没有被装备旅行包的东西耽误时间PreparedStatement对象表示预编译的 SQL 语句的对象,就像提前准备好的旅行包,只要你准备去旅行就可以无限次,可以随时拿旅行包去旅行,而Statement不是预编译所以每一次运行sql语句都需要不断的编译就像每次旅行都要去当天准备一些没准备好的东西放入旅行包,每一次旅行也要不断去准备旅行包的东西。

2:安全性
Statement对象的SQL语句是字符串拼接起来的语句,无法有效防止Sql注入
PreparedStatement对象的SQL语句是占位符标识填入数据的语句,能有效防止Sql注入问题

那先了解下什么是SQL注入
SQL注入是目前比较常见的针对数据库的一种攻击方式。在这种攻击方式中,攻击者会将一些恶意代码插入到字符串中。然后会通过各种手段将该字符串传递到SQLServer数据库的实例中进行分析和执行。只要这个恶意代码符合SQL语句的规则,则在代码编译与执行的时候,就不会被系统所发现。由此可见SQL注入式攻击的危害是很大的。

防止SQL注入:
 总体来说,防治SQL注入式攻击可以采用两种方法,一是加强对用户输入内容的检查与验证;二是强迫使用参数化语句来传递用户输入的内容。(用占位符)
 

 try {
                 Connection conn = DriverManager.getConnection(url,user,password);
                 String sql = "select * from user where id=?;";//采取占位符带参数传入有效防止SQL注入,
                 PreparedStatement p = conn.prepareStatement(sql);// PreparedStatement对象使SQL注入生效,使得插入恶意字符串的SQl无法有效执行(不会报错),也就是无法输出结果。
                 p.setString(1, id);
                 ResultSet rs = p.executeQuery();
                  while(rs.next()){
                        String name1 = rs.getString("name");
                        int age1 = rs.getInt(3);
                        String sex1 = rs.getString("sex");
                        if(name1.equals(name)&&age1==age&&sex1.equals(sex)){
                            flag = true; 
                        }
                    }
                 conn.close();
             } catch (SQLException e) {
                 e.printStackTrace();
             }
 String id= "1 or 1=1";
 try {
        Connection conn   =DriverManager.getConnection(url,user,password);
        String sql = "insert into user (id,name,age,sex) values("+"'"+id+"'"+","+"'"+name+"'"+","+age+","+"'"+sex+"'"+");";//用字符串拼接的SQL语句,遇到其中一个参数id为1 or 1=1情况也会执行出结果,因为不违反SQL语句的规则
                 Statement p = conn.prepareStatement(sql);
                 //Statement对象使得插入恶意字符串的SQl有效执行,无法阻止结果输出
                 p.executeUpdate();
                 conn.close();
             } catch (SQLException e) {
                 e.printStackTrace();
             }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值