1.每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.
2.PreparedStatement在conn.prepareStatement(sql)时就把sql语句传给它,这样它会在数据库端进行预编译(包含占位符),下次execute或者executeQuery时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行。其实这并不是说只有一个Connection中多次执行的预编译语句被缓存,这是PreparedStatement借助数据库的编译sql语句的原理来实现的优先做法而已。
Statement在conn.createStatement()时不传sql语句,而是在execute或者executeQuery时传过去死的sql语句。这样使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.
3.使用Statement要给它传死的拼接的sql语句,其实这样做是很不安全的,有发生恶意sql语句注入的危险。比如:
String sql="select * from t_user where name='zhangs' and passwd='zhangs123'"
而我恶意给你注入一个"or 1=1",就成了
String sql="select * from t_user where name='zhangs' and passwd='zhangs123' or 1=1"
这样,你的密码就失去了功效。
String sql="select * from t_user where name='zhangs' and passwd='zhangs123'"
而我恶意给你注入一个"or 1=1",就成了
String sql="select * from t_user where name='zhangs' and passwd='zhangs123' or 1=1"
这样,你的密码就失去了功效。
1 、 PreparedStatement 能防止 SQL 注入问题,而 Statement 是动态拼出 SQL ,因此不 能解决;
2 、 PreparedStatement 对 SQL 进行预编译,因此如果我们采用绑定变量的 SQL (语句 类似,数据不同)数据库只需解析一次(生成执行计划),因此效率要高;
3 、 Statement 由于没有采用绑定变量,因此可能每次都需要编译(生成执行计划),因 此对于那种语句类似但数据不同的 SQL 每次都需要编译,效率低;
4 、 PreparedStatement 开销要比 Statement 高, 因此如果 SQL 只执行一次,应该使用 Statement 。
5 、在大多数情况下都应该使用 PreparedStatement 。