一.概念
Statement陈述对象:
提供在基层已经建立连接的基础上运行SQL语句,实际有三种Statement对象
1.Statement:用于执行不带参数的简单 SQL 语句。
2.PreparedStatement(它从 Statement 继承而来,包含其中的所有方法):于执行带或不带参数的预编译 SQL 语句。
3.CallableStatement(它从 PreparedStatement 继承而来):用于执行对数据库已存储过程的调用。
Statement执行流程:每次执行SQL语句,数据库都要执行sql语句的编译命令,所以当有查询一次并返回结果的情形,使用Statement比PreparedStatement效率更高,但是存在sql注入的风险。
PreparedStatement:
PreparedStatement是Statement的子接口,功能一样但是解决了多次执行同一个SQL语句时的性能还有效率问题
优点:
提高代码的可读性,维护性,操作性:
Statement中执行的sql语句是拼接在一起的,对于代码的整洁性,和可读性而言效果很差,也不便于在程序开发完成后的调试工作,在使用日期时如果是Statement 则需要输入适当格式的日期,使用preparedstatement可以自动解决。
性能的提升:
statement在执行每一条语句的时候因为数据的不同都需要重新编译之后在运行。
预编译语句有可能会被程序重复调用,所以数据库对预编译语句提升了很大的性能优化,当语句被DB的编译器编译过后会被缓存下来,下次如果遇到相同操作的预编译语句就不需要再次编译,只是将新的参数数据传入到之前的语句中,在整个数据库中只要预编译中的语句与缓存中的相对应,就不再需要再次编译而可以直接运行。
提高了安全性:
很重要的一点就是提高了代码的安全性,因为statement使用的是${}拼接成sql语句,而preparedStatement使用的是#{}可以将参数先替换成?占位符,所以预防了SQL注入。(详情请观看#{}与 ${}的区别?)
代码的对比:
Statement:
statement.executeUpdate("insert into user(name,sex,age)values('"+var1+"','"+var2+"',"+var3+"'')");
PreparedStatement:
String sql = "update user set name=?,sex=?,age=?,phone=?,province=? where id=?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, person.getName());
preparedStatement.setString(2, person.getSex());
preparedStatement.setString(3, person.getAge());
preparedStatement.setString(4, person.getPhone());
preparedStatement.setString(5, person.getProvince());
result = preparedStatement.executeUpdate();