首先说一下在代码上的不同
1、
Statement是调用Connection对象的createStatement()方法获取Statement对象。
Statement stm = con.createStatement();
PreparedStatement是调用Connection对象的preparedStatement()方法获取PreparedStatement对象。
PreparedStatement pstm = con.preparedStatement(sql);
2、
执行查询和增删改的语句是:
stm.executeQuery(sql);
stm.executeUpdate(sql);
pstm.executeQuery();
pstm.executeUpdate();
3、
在写sql语句的时候不一样。
这里以表名为student为例,number(int),name(String)。以向数据库表插入数据为例。
Statement:
sql="insert into student (stunumber,stuname) values ('"+number+"','"+name+"')";
PreparedStatement:
sql="insert into student (stunumber,stuname) values (?,?)";
pstm.setInt(1,number);
pstm.setString(2,name);
然后除了在代码上有不同外,在代码可读性上和性能和安全上也有不同。
代码可读性上:
可以很清楚的看到,当使用Statement时,从数据库表中存取的字段很多时,双引号单引号多的爆炸。容易搞混。
而preparedStatement直接用问号代替,然后用setXXX的方法来存取。
性能上:
目前我粗浅的理解是:PreparedStatement是预编译的,对批处理可以提高效率。而一次性的操作时,PreparedStatement消耗比Statement大。所以我目前的结论是:只需要执行一次sql语句的时候,可以用Statement,多次的时候用preparedStatement。
安全上:
安全很重要。PreparedStatement可以防止sql注入。原因就是在它们写sql语句上的不同所带来的影响。
比如Statement的sql语句是用加号连接起来的。如果一个程序可以通过用户名和密码登陆的话,那么就可以在用户名和密码处填写部分sql语句。这样就会改变整个sql语句的内容,然后非法登陆。
以用户名为 tom,密码为 123 为例。当你输入tom和123之后会登陆成功。
可如果你输入的语句使得sql语句为 "select * from user where username='a' or password' and password='or '1'='1' " 也可以登陆成功。
上面的sql语句中 username后的单引号 我写的是 (a' or password) password后的单引号 我写的是 (or '1'=1)
所以PreparedStatement更加的安全。