小编在敲drp项目的时候,偶遇了prepareStatement和Statement这两对象,看着就觉得这两个对象关系匪浅,的确prepareStatement继承了Statement,所以prepareStatement在Statement的基础肯定扩展了她的方法,而且很具有优势,下面小编就简单的讲讲我对这两个对象的看法:
安全性
效率
开销
可读性
维护性
prepareStatement
高
高,预编译
大
好
容易
Statement
容易发生sql注入
低,每一次编译
小
差
不容易
prepareStatement:
/** * 删除单个用户 * @param userId */ public void delUser(String userId){ String sqldelString="delete from t_user where user_id=?"; Connection connection=null; PreparedStatement psmt=null; try { connection=DbUtil.getConnection(); psmt=connection.prepareStatement(sqldelString); psmt.setString(1, userId); //设置参数 psmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally{ DbUtil.close(psmt); DbUtil.close(connection); } }Statement:
/** * 删除单个用户 * @param userId */ public void delUser(String userId){ String sqldelString="delete from t_user where user_id"+userId; //直接将参数放入sql语句中 Connection connection=null; java.sql.Statement stmt=null; try { connection=DbUtil.getConnection(); stmt=connection.createStatement(); stmt.executeUpdate(sqldelString); } catch (Exception e) { e.printStackTrace(); }finally{ DbUtil.close(stmt); DbUtil.close(connection); } }
单从代码量来看,Statement的确比prepareStatement的少两行,因为有sql参数的设置。但是从可读性和维护性上,prepareStatement的sql的语句类型一旦确定,就不需要过多的修改,参数与sql语句分离,提高维护性。从安全性的角度来说,如果用Statement进行select查询很容易会产生sql注入,把["or '1'='1"]数据传进来,所有的未或注册的用户可以随意访问,很容易泄露。
所以得出的结论是在一般情况下,我们都尽量使用prepareStatement而不是Statement。
-----------------------------------------------------------------------------
PrepareStatement:
/** * 批量删除 * 采用提交一次完成删除 * 采用preparedstatement占位符的方式 * delete from t_user where user_id in(?,?,?); * @param userIds */ public void delUser(String[] userIds) { StringBuilder sBuilder=new StringBuilder(); for (int i = 0; i < userIds.length; i++) { //使用stringbuilder加载占位符。 sBuilder.append("?"); if (i<(userIds.length-1)) { sBuilder.append(","); } } String sqlString="delete from t_user where user_id in ("+sBuilder.toString()+")"; System.out.println(sqlString); Connection connection=null; PreparedStatement stmt=null; try { connection=DbUtil.getConnection(); stmt=connection.prepareStatement(sqlString); //射进来的参数-stringbuiler for (int i = 0; i < userIds.length; i++) { stmt.setString(i+1, userIds[i]); } stmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally{ DbUtil.close(stmt); DbUtil.close(connection); } } Statement:
//{{ void delUser(String[] userIds)+常银玲 /** * 批量删除 * 采用提交一次完成删除——事务-cyl * 采用statement拼串方式 * delete from t_user where user_id in(); * @param userIds */ public void delUser(String[] userIds) { StringBuilder sBuilder=new StringBuilder(); for (int i = 0; i < userIds.length; i++) { //使用stringbuilder加载参数 sBuilder.append("'") .append(userIds[i]) .append("'") .append(","); } String sqlString="delete from t_user where user_id in ("+sBuilder.substring(0,sBuilder.length()-1)+")"; System.out.println(sqlString); Connection connection=null; java.sql.Statement stmt=null; // ResultSet rSet=null; try { connection=DbUtil.getConnection(); stmt=connection.createStatement(); stmt.executeUpdate(sqlString); } catch (Exception e) { e.printStackTrace(); }finally{ //DbUtil.close(rSet); DbUtil.close(stmt); DbUtil.close(connection); } } //}}
其实使用prepareStatement已经成为我们的首选,必定它有着比Statement更多的优势,而且prepareStatement更加体现我们面向对象的一种思想,将sql语句与参数分离,参数的类型已经参数值不会对既定的sql语句产生很大的影响,而且最重要的就它可以进行预编译,对我们程序的性能会有很大的改善,而且可以防止sql注入,提高我们程序的安全性。希望这篇博文让你对prepareStatement有了一些了解,如果有什么偏差,希望可以在谅解的同时提出您的想法!