javawebスタディノートのJDBCプリコンパイルとSQLインジェクションの問題

SQLインジェクションとは

ログインインターフェイスを作成し、パスワードをfdsaと1に設定します。コードは、次のとおりです。

select * from tbl_user where username = 'fdsafds' and password = 'fdsa' or '1'='1'; 

入ると

用户名:fdsafds
密码:fdsa' or '1'='1
这样可以登录成功,为什么?

条件が常に確立され、データベーステーブル内のすべてのデータがクエリされる上記のSQLステートメント
上記の現象はSQLインジェクションと呼ばれます

    当用户提供的信息当中含有SQL语句的关键字,并且这些关键字参与了SQL语句的编译过程,导致原先的SQL语句原意被扭曲。
    根本原因:先拼接SQL语句,再进行编译,这是根本原因。

SQLインジェクションをどのように見るか

SQLインジェクションは必ずしも危険ではありませんが、ほとんどの場合、システムのセキュリティを危険にさらします。システムの一部の特殊機能でもSQLインジェクションが必要になる場合があります。
現時点でSQLインジェクションをサポートするには、java.sql.Statementインターフェースを使用する必要があります。

SQLインジェクションを解決する方法、またはSQLインジェクションを防ぐ方法は?

java.sql.PreparedStatementは、プリコンパイルされたデータベース操作オブジェクトと呼ばれ、SQLインジェクションを防ぐことができます。
原則:

对SQL语句框架进行预先编译,再接收用户提供的信息,即使提供的信息当中含有SQL语句的关键字,但是这些关键字并没有参与SQL语句的编译,
那么它也只是一个普通的字符串,SQL语句原意不会被扭曲,防止了SQL注入。

PreparedStatementは、Statementのサブインターフェースです。

ほとんどの場合、SQLインジェクションを防ぐ必要があるため、PreparedStatementがより多く使用されます。

StatementとPreparedStatementの違い

1.	Statement是先进行SQL语句拼接,再进行SQL语句的编译,存在SQL注入问题;
2.	PreparedStatement是预先编译SQL语句框架(带有占位符的SQL),然后再给占位符赋值,防止SQL注入;
3.	Statement编译一次,执行一次,编译一次,执行一次,PreparedStatement编译一次框架,执行N次,
4.	PreparedStatement效率较高。

バッチ処理のための事前コンパイル

100以上のデータを処理する必要がある場合、元の処理方法を使用すると、次のようになります。

for(int i=1;i<=100;i++){
    
    
            String sql="insert into dept(deptno,dname,loc) values("+i+",'dept_"+i+"','北京')";
            ps.executeUpdate(sql);
        }

次の問題が発生する可能性があります。

  1. SQLコマンドの記述の問題:
    各SQLステートメントが異なるデータを確実に伝送するために、文字列スプライシングメソッド
    "insert into dept(deptno、dname、loc)values(" + i + "、 'dept _" + i + "'、 'Beijing' ) ";

  2. 時間の浪費:PreparedStatementオブジェクトは、一度に1つのSQLコマンドしかプッシュできません。
    100個のSQLコマンドをプッシュするには、100回のラウンドトリップが必要であり、多くの時間を浪費します。

ご覧のとおり、上記のプログラムはプログラマー
にとって恐ろしいものです。この種のバッチ処理の問題では、コンパイル済みのSQLコマンドの形式を取ります。

    "?"是占位符,一个问号代替一个值
    预编译SQL相当一个模具,在后续开发时,只需要将数据填充到占位符,就可以得到一个全新SQL
String sql ="insert into dept(deptno,dname,loc) values(?,?,?)";
    //注册Driver
  Class.forName("com.mysql.jdbc.Driver");
    //建立通道
   Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode", "root", "123");
    //【建立交通工具时,需要将预编译SQL命令注册到PreparedStatement】
    PreparedStatement ps =  con.prepareStatement(sql);

//プリコンパイルされたSQLコマンドにデータを入力して、まったく新しいSQLコマンドを生成します

 //4.向MySql服务器推送100条数据
        for(int i=1;i<=100;i++){
    
    
          
            ps.setInt(1, i); //inser into dept (deptno,dname,loc) values(1,?,?)
            ps.setString(2, "dept_"+i); //inser into dept (deptno,dname,loc) values(1,'dept_1',?)
            ps.setString(3, "北京");//inser into dept (deptno,dname,loc) values(1,'dept_1','北京')
            //在新的SQL语句生成之后,将SQL语句作为子弹添加到PS的弹夹
            ps.addBatch(); //[sql1,sql2,...]
        }

JavaのStatement.addBath()メソッドは、指定されたSQLコマンドをこのStatementオブジェクトの現在のコマンドリストに追加します。このリストのコマンドは、executeBatchメソッドを呼び出すことでバッチで実行できます。
[1回限り] psを介して実行するために100個のSQLステートメントをmysqlサーバーにプッシュします

   ps.executeBatch(); // 推送100条SQL命令只需要往返一次

次に、前に作成したリソースを閉じることができます。

おすすめ

転載: blog.csdn.net/qq_47917118/article/details/115269293