Maison  >  Article  >  Pourquoi la précompilation empêche l'injection SQL

Pourquoi la précompilation empêche l'injection SQL

(*-*)浩
(*-*)浩original
2019-05-10 17:33:1612615parcourir

La raison pour laquelle la précompilation peut empêcher l'injection SQL : permettre à la base de données d'effectuer des requêtes paramétrées. Lors de l'utilisation de requêtes paramétrées, la base de données ne considérera pas le contenu des paramètres comme faisant partie de l'exécution SQL, mais comme la valeur d'attribut d'un champ. De cette manière, même si les paramètres contiennent des instructions destructives (ou '1=1' ) ne sera pas exécuté.

Pourquoi la précompilation empêche l'injection SQL

Pourquoi PreparedStatement peut-il empêcher l'injection SQL dans une certaine mesure ?

PreparedStatement précompilera SQL. La base de données analysera, compilera et optimisera avant d'exécuter SQL pour la première fois. En même temps, le plan d'exécution sera également mis en cache, ce qui permettra à la base de données de le faire. faire des requêtes paramétrées. Lors de l'utilisation de requêtes paramétrées, la base de données ne considérera pas le contenu des paramètres comme faisant partie de l'exécution SQL, mais comme la valeur d'attribut d'un champ. De cette manière, même si les paramètres contiennent des instructions destructives (ou '1=1' ) ne sera pas exécuté.

Cours recommandés : Tutoriel Java

Comment utiliser PreparedStatement ? Comment éviter les attaques par injection SQL ? Quelle est la différence entre PreparedStatement et Statement, et quels sont leurs avantages ?

Un exemple simple de PreparedStatement

public class JDBCTest {
    public static void main(String[] args) {
        //表示使用Unicode字符集;字符编码设置为utf-8;不使用SSL连接
        String URL = "jdbc:mysql://127.0.0.1:3306/sampledb?useUnicode=true&" +
                "characterEncoding=utf-8&useSSL=false";
        String USER = "spring4";//用户
        String PASSWORD = "spring4";//密码
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            //1.加载驱动程序到JVM
            Class.forName("com.mysql.jdbc.Driver");
            //2.创建数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
            //3.创建Statement,实现增删改查
            String sql = "select user_id,user_name,credits from t_user where credits > ?";
            st = conn.prepareStatement(sql);//这里使用PreparedStatement
            st.setInt(1, 8);
            //4.向数据库发送SQL命令
            rs = st.executeQuery();
            //5.使用ResultSet处理数据库的返回结果
            while (rs.next()) {
                System.out.println(rs.getLong("user_id") + " "
                        + rs.getString("user_name") + " "
                        + rs.getString("credits"));
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            //6.关闭资源
            try {
                rs.close();
                st.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

Plusieurs implémentations de l'objet Statement

Statement sont utilisées pour envoyer des instructions SQL à la base de données.

Chaque fois que Statement exécute une instruction SQL, la base de données doit exécuter la compilation de l'instruction SQL. Il est préférable de l'utiliser dans les situations où la requête n'est exécutée qu'une seule fois et les résultats sont renvoyés

. 1. Exécutez des instructions SQL statiques. Généralement implémenté via des instances de Statement.

2. Exécutez des instructions SQL dynamiques. Généralement implémenté via une instance PreparedStatement.

3. Exécutez la procédure stockée de la base de données. Généralement implémenté via une instance CallableStatement. La différence entre

'#' et '$'

pré-compilation SQL fait référence au pilote de base de données qui compile l'instruction SQL avant d'envoyer l'instruction SQL et les paramètres au SGBD De cette façon, lorsque le SGBD exécute SQL, il n'a pas besoin d'être recompilé.

'#{ }' : analysé comme un marqueur de paramètre d'une instruction préparée JDBC (instruction préparée), un ' #{ }' est analysé comme un espace réservé de paramètre ?

'${ }' n'est qu'un pur remplacement de chaîne, le remplacement de variable sera effectué pendant la phase d'analyse SQL dynamique. Déjà remplacée par des variables avant la précompilation

La phase de remplacement de la variable '${ }' se fait dans la phase d'analyse SQL dynamique, tandis que le remplacement de la variable '#{ }' se fait dans le SGBD.

Quelle est la différence entre PreparedStatement et Statement

1. PreparedStatement peut être précompilé et cette instruction de requête SQL précompilée peut être réutilisée dans les requêtes futures. qui génère des requêtes plus rapidement que les objets Statement.

2.PreparedStatement peut écrire des requêtes paramétrées dynamiques

3.PreparedStatement peut empêcher les attaques par injection SQL

4.Les requêtes PreparedStatement sont plus lisibles et peuvent ajouter des conditions L'instruction est compliquée

🎜>

5. PreparedStatement ne permet pas à un espace réservé (?) d'avoir plusieurs valeurs

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn