用预查询(JDBC里的preparedstatement)为什么比直接用字符串拼SQL效率高

2021/6/11 19:22:33

本文主要是介绍用预查询(JDBC里的preparedstatement)为什么比直接用字符串拼SQL效率高,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

用预查询(JDBC里的preparedstatement)为什么比直接用字符串拼SQL效率高

用JDBC里的preparedstatement的好处

1、相对比较安全,可以防止sql注入

  • 举个例子,假如我们在做用户的登录认证,里面有两个字段username,passwword,我们如果用字符串拼接,我们一般这么写:“select id from users where username = '”+username +"’ and password = ‘" + password +"’" 这里的username和password都是我们存取从web表单获得的数据。如果我们在字符串上面输入

    'or 1 = 1’那么意味着我根本不用管他的数据库,直接可以通过验证,password我写一个简单的123,这时候

    select id from users where username = ‘’ or 1=1-- and password = ‘123’,这好吗,这不好。这就是简单的sql注入

  • 但是preparedstatement传参数的时候用占位符"?"解决了这个问题

2、有预编译功能,相同操作批量数据效率较高

  • 这个从名字可以读出preparedstatement,prepared准备好的,当数据库见到preparedstatement的sql语句,数据库会在数据库缓冲区里面去找,如果没找到,会编译一次
import java.io.IOException;
public class TestMark_to_win {
    public static void main(String[] args) throws java.sql.SQLException,
            ClassNotFoundException, IOException {
        int i = 0;
        java.sql.Connection connection = null;
        java.sql.PreparedStatement pstmt;
        Class.forName("com.mysql.jdbc.Driver");
        connection = java.sql.DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test", "root", "1234");
        pstmt = connection
                .prepareStatement("UPDATE login SET name = ? WHERE id = ?");
        long t = System.currentTimeMillis();
        for(i=0;i<10000;i++) {
            pstmt.setString(1, "qqqq");
            pstmt.setString(2, "2");
            pstmt.executeUpdate();
        }
        t = System.currentTimeMillis() - t;
        System.out.println("用了如下时间:" + t);
        pstmt.close();
        System.out.println("ok");
        connection.close();
    }
}

3、讲讲区别

  • 如果用字符串拼接。当一个数据库收到一个statement后,数据库引擎会先解析statement,然后检查其是否有语法错误。一旦statement被正确的解析,数据库会选出执行statement的最优途径。遗憾的是这个计算开销非常昂贵。数据库会首先检查是否有相关的索引可以对此提供帮助,不管是否会将一个表中的全部行都读出来。数据库对数据进行统计,然后选出最优途径。当决创建查询方案后,数据库引擎会将它执行。

  • 数据库已经具有了类似的功能。它们通常会用如下方法对statement进行缓存。使用statement本身作为key并将存取方案存入与statement对应的缓存中。这样数据库引擎就可以对曾经执行过的statements中的存取方案进行重用。举个例子,如果我们发送一条包含SELECT a, b FROM t WHERE c = 2的statement到数据库,然后首先会将存取方案进行缓存。当我们再次发送相同的statement时,数据库会对先前使用过的存取方案进行重用,这样就降低了CPU的开销。

  • 那么,当c = 3的时候,那么缓冲区没有了就会自己去编译

  • 那么PareparedStatement就像是一个没吃过饭的用户,他点的的食物很多而且都是准备好的,所以在准备做菜的时候会有开销,一旦运行起来它的效果是非常好的,所以.PreparedStatement是预编译的,对于批量处理可以大大提高效率

  • 结论: prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。 createStatement不会初始化,没有预处理,没次都是从0开始执行SQL

4、提出疑问

那么什么时候preparedstatement效果会比字符串拼接差,这得问老师



这篇关于用预查询(JDBC里的preparedstatement)为什么比直接用字符串拼SQL效率高的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程