>일반적인 문제 >사전 컴파일이 SQL 삽입을 방지하는 이유

사전 컴파일이 SQL 삽입을 방지하는 이유

(*-*)浩
(*-*)浩원래의
2019-05-10 17:33:1612648검색

사전 컴파일이 SQL 삽입을 방지할 수 있는 이유: 데이터베이스가 매개변수화된 쿼리를 수행할 수 있도록 허용하기 때문입니다. 매개변수화된 쿼리를 사용할 때 데이터베이스는 매개변수의 내용을 SQL 실행의 일부로 간주하지 않고 이러한 방식으로 매개변수에 파괴적인 문(또는 '1=1' )이 포함된 경우에도 필드의 속성 값으로 간주합니다. 실행되지 않습니다.

사전 컴파일이 SQL 삽입을 방지하는 이유

PreparedStatement가 SQL 주입을 어느 정도 방지할 수 있는 이유는 무엇인가요?

PreparedStatement는 SQL을 사전 컴파일합니다. 데이터베이스는 SQL을 처음 실행하기 전에 분석, 컴파일 및 최적화합니다. 동시에 실행 계획도 캐시됩니다. , 이를 통해 데이터베이스는 매개변수화된 쿼리를 수행할 수 있습니다. 매개변수화된 쿼리를 사용할 때 데이터베이스는 매개변수의 내용을 SQL 실행의 일부로 간주하지 않고 이러한 방식으로 매개변수에 파괴적인 문(또는 '1=1' )이 포함된 경우에도 필드의 속성 값으로 간주합니다. 실행되지 않습니다.

추천 과정: JavaTutorial

PreparedStatement를 사용하는 방법은 무엇인가요? SQL 주입 공격을 피하는 방법은 무엇입니까? ReadyStatement와 State의 차이점은 무엇이며 장점은 무엇입니까?

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();
            }
        }
    }
}

Statement의 여러 구현

Statement 개체가 사용됩니다. SQL 문을 데이터베이스로 보냅니다.

Statement SQL 문이 실행될 때마다 데이터베이스는 SQL 문을 컴파일해야 합니다. 쿼리가 한 번만 실행되고 결과가 반환되는 상황에 가장 적합합니다

1. 정적 SQL 문을 실행합니다. 일반적으로 State 인스턴스를 통해 구현됩니다.

2. 동적 SQL 문을 실행합니다. 일반적으로 ReadyStatement 인스턴스를 통해 구현됩니다.

3. 데이터베이스 저장 프로시저를 실행합니다. 일반적으로 CallableStatement 인스턴스를 통해 구현됩니다.

'#''$'의 차이점 DBMS가 sql을 실행할 때 재컴파일할 필요가 없도록 sql문을 컴파일한다.

'#{ }': JDBC 준비된 문(준비된 문)의 매개변수 표시자로 구문 분석되고 ' #{ }'는 매개변수 자리 표시자로 구문 분석됩니다.

'${ }'는 순수한 문자열 대체일 뿐이며 변수 대체는 동적 SQL 구문 분석 단계에서 수행됩니다. 사전 컴파일 이전에 이미 변수로 대체

'${ }' 변수의 대체 단계는 동적 SQL 구문 분석 단계에 있는 반면, '#{ }' 변수의 대체는 DBMS에 있습니다.

PreparedStatement와 State의 차이점은 무엇입니까? 중간 재사용이므로 State 개체보다 더 빠르게 쿼리를 생성할 수 있습니다.

2.PreparedStatement는 동적 매개변수화된 쿼리를 작성할 수 있습니다. 3.PreparedStatement는 SQL 주입 공격을 방지할 수 있습니다.

4.PreparedStatement 쿼리 가독성 더 좋습니다. 추가 조건이 매우 지저분합니다

5.PreparedStatement에서는 자리 표시자(?)가 여러 값을 갖는 것을 허용하지 않습니다 ​​

위 내용은 사전 컴파일이 SQL 삽입을 방지하는 이유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.