PreparedStatement和Statement的关系

    今天在开发的过程中遇到这个问题,不知道到底该创建那个对象,在网上看了下才恍然大悟,果然还是DB的基础知识太薄弱了啊。

    首先,PreparedStatement是Statement的子类,前者继承了后者的所有方法,并且很好的,execute、executequery、executeupdate这三个方法已经被优化,因此不需要任何参数。下面说说,PreparedStatement相比Statement,拥有哪些优点。

    1、PreparedStatement的代码阅读性很好,比如写一个插入语句:

        Statement:

 Statement stmt = dhConn.CreateStatement();
 stmt.execute("insert into tablename (para1,para2,para3) values ("+value1+","+value2+","+value3+")");

        PreparedStatement:

 String Sql = "insert into tablename (para1,para2,para3) values (?,?,?) ";
 pstmt = dhConn.preparedStatement(Sql);
 pstmt.setString(1,value1);
 pstmt.setString(1,value2);
 pstmt.setString(1,value3);
 pstmt.executeUpdate();

    明显后者看起来更简洁,并且参数显眼

    2、PreparedStatement是提供预编译的,意思就是你写好一句Sql后,在DB中编译后,它会被缓存(ps:1),就有点像Java里面的静态方法(ps:2),放在哪里等待调用,当你这句语句再执行的时候,语句还没被编译,DB就会去缓存里面匹配,匹配成功的话, 直接将参数传入缓存的语句执行代码。所以速度方面快很多。(ps1:并不是所有的语句都会被缓存,或者说接着缓存,DB会根据自身的策略,选择是否缓存(继续缓存),这个就像Java的垃圾回收机制,在不需要的时候,释放内存)

    3、PrepaerStatement是一种安全的DB处理方法,一般的SQL注入攻击:

 String SQL = "select * from tablename t where t.id='id' and t.pwd='pwd'";

    假如用户输入的id: 'or 1=1',pwd: 'or 1=1' 那么这个查询将等价于:

select * from tablename ;

  甚至,当id : ' or 1=1;drop tablename;' 这将带来什么后果?

当然这些只对Statement有效,因为PreparedStatement在编译预编译语句的时候,禁止改变查询语句的结构,所以也就防止了SQL注入了。

    既然说到 1=1,1=1是永真的,但是它的妙用就是可以动态构建SQL语句,比如多条件查询,假如不加 1=1,你是到底写不写“and”呢?

你可能感兴趣的:(statement,防注入)