• 技术文章 >常见问题

    为什么预编译可以防止sql注入

    (*-*)浩(*-*)浩2020-09-15 17:55:56原创5656

    预编译可以防止sql注入的原因:允许数据库做参数化查询。在使用参数化查询的情况下,数据库不会将参数的内容视为SQL执行的一部分,而是作为一个字段的属性值来处理,这样就算参数中包含破环性语句(or ‘1=1’)也不会被执行。

    PreparedStatement为什么能在一定程度上防止SQL注入?

    PreparedStatement会对SQL进行了预编译,在第一次执行SQL前数据库会进行分析、编译和优化,同时执行计划同样会被缓存起来,它允许数据库做参数化查询。在使用参数化查询的情况下,数据库不会将参数的内容视为SQL执行的一部分,而是作为一个字段的属性值来处理,这样就算参数中包含破环性语句(or ‘1=1’)也不会被执行。

    推荐课程:Java教程

    怎么使用PreparedStatement?如何避免SQL注入式攻击?PreparedStatement与Statement有什么区别,有什么样的优势?

    一个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语句。通常通过Statement实例实现。

    2、执行动态SQL语句。通常通过PreparedStatement实例实现。

    3、执行数据库存储过程。通常通过CallableStatement实例实现。

    #’和‘$’的区别

    sql 预编译指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。

    ‘#{ }’:解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,一个‘ #{ }’ 被解析为一个参数占位符 ? 。

    ‘${ }’ 仅仅为一个纯粹的 string 替换,在动态 SQL 解析阶段将会进行变量替换。在预编译之前已经被变量替换了

    ‘${ }’变量的替换阶段是在动态 SQL 解析阶段,而’#{ }’变量的替换是在 DBMS 中。

    PreparedStatement与Statement有什么区别

    1.PreparedStatement能预编译,这条预编译的SQL查询语句能在将来的查询中重用,这样一来,它比Statement对象生成的查询速度更快。

    2.PreparedStatement可以写动态参数化的查询

    3.PreparedStatement可以防止SQL注入式攻击

    4.PreparedStatement查询可读性更好,追加条件的语句很乱

    5.PreparedStatement不允许一个占位符(?)有多个值

    以上就是为什么预编译可以防止sql注入的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:sql
    上一篇:pdf怎么转jpg 下一篇:c语言学会了能干什么

    相关文章推荐

    • sql注入攻击如何实现• sql与mysql区别与联系• c#如何防止sql注入?• sql语言容易学吗?

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网