JDBC中的Statement和PreparedStatement的区别
来源:互联网 发布:越前南次郎的实力数据 编辑:程序博客网 时间:2024/05/28 16:00
1:Statement
每次都会执行SQL语句,相关数据库都要执行SQL语句的编译。Statement为一条Sql语句生成执行计划,如果要执行两条sql语句select colume from table where colume=1;select colume from table where colume=2;会生成两个执行计划一千个查询就生成一千个执行计划!
2: PreparedStatement
用于处理动态SQL语句,在执行前会有一个预编译过程,这个过程是有时间开销的,虽然相对数据库的操作,该时间开销可以忽略不计, 但是PreparedStatement的预编译结果会被缓存,下次执行相同的预编译语句时,就不需要编译,只要将参数直接传入编译过的语句执行代码 中就会得到执行,所以,对于批量处理可以大大提高效率。 (1) PreparedStatement接口继承Statement,PreparedStatement 实例包含已编译的 SQL 语句, 所以其执行速度要快于 Statement 对象。 (2)作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。 三种方法**execute**、 **executeQuery** 和 **executeUpdate** 已被更改以使之不再需要参数
3:应该尽可能以PreparedStatement代替Statement,其原因如下:
(1)代码的可读性和可维护性。从代码比较中就应该能看出来:
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");//stmt是Statement对象实例perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");perstmt.setString(1,var1);perstmt.setString(2,var2);perstmt.setString(3,var3);perstmt.setString(4,var4);perstmt.executeUpdate(); //prestmt是 PreparedStatement 对象实例
(2)PreparedStatement尽最大可能提高性能。
(3)极大的提高了安全性。
恶意SQL语法
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
如果我们把[’ or ‘1’ = ‘1]作为varpasswd传入进来.用户名随意,看看会成为什么?
select * from tb_name = '随意' and passwd = '' or '1' = '1';
因为’1’=’1’肯定成立,所以可以任何通过验证。这算比较委婉的,更有甚者把[‘;drop table tb_name;]作为varpasswd传入进来… 关于数据安全方面的内容这里就不做展开讨论了,总之使用PreparedStatement让执行的SQL更安全。
更有甚者:
把[‘;drop table tb_name;]作为varpasswd传入进来,则:
select * from tb_name = ‘随意’ and passwd = ”;drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.
罗列出PreparedStatement对象在初级开发中几个常用的方法:
1). PreparedStatement.execute()方法:
该语句可以是任何种类的 SQL 语句
execute 方法返回一个 boolean 值,以指示第一个结果的形式。必须调用 getResultSet 或 getUpdateCount 方法来检索结果,并且必须调用 getMoreResults 移动到任何后面的结果。
返回:
如果第一个结果是 ResultSet 对象,则返回 true;如果第一个结果是更新计数或者没有结果,则返回 false
意思就是如果是查询的话返回true,如果是更新或插入的话就返回false了;
2). PreparedStatement.executeQuery()方法:
返回执行查询语句后得到的ResultSet结果集,注意:该结果集永远不能为null。
3). PreparedStatement.executeUpdate()方法:
返回一个int类型的值,该值代表执行INSERT、DELETE以及UPDATE语句后的更新行数。
如果该值为0,则代表SQL语句没有执行成功。
4).PreparedStatement.addBatch(); executeBatch()方法:
将一组参数添加到此 PreparedStatement 对象的批处理命令中。缓存sql语句,然后批量执行!
将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
用法举例:
1、增加、修改、删除都用execute(),也可用executeUpdate(),针对于INSERT、UPDATE 或 DELETE 语句
public int addAirEnvironmentPresent(M_AirEnviromentPresentDTO airDTO){ int index = 1; String sql = "insert into airPresent(airForecastPlace,ForecastTime,TSPvalue,remark) values(?,?,?,?)"; try { ps = conn.prepareStatement(sql); ps.setString(index++, airDTO.getAirForecastPlace()); ps.setString(index++, airDTO.getForecastTime()); ps.setString(index++, airDTO.getTSPvalue()); ps.setString(index++, airDTO.getRemark()); ps.execute(); } catch (SQLException e) { e.printStackTrace(); } return 1; }
2、查询调用execute(),针对于SELECT语句
public List<PoiMsgDBPojo> getPoiMsgListAfterTime(String vin, long createTime) throws SQLException { StringBuffer preparedSQLStringBuffer = new StringBuffer(""); preparedSQLStringBuffer.append("SELECT poi_msg.*,`source`.file_name FROM poi_msg, car, `source`"); preparedSQLStringBuffer.append("WHERE "); preparedSQLStringBuffer.append("poi_msg.wecar_id=car.wecar_id AND "); preparedSQLStringBuffer.append("poi_msg.weixin_openid=car.weixin_openid AND "); preparedSQLStringBuffer.append("poi_msg.`source` = `source`.chn_name AND "); preparedSQLStringBuffer.append("car.vin=? AND "); preparedSQLStringBuffer.append("create_time>? "); preparedSQLStringBuffer.append("ORDER BY create_time DESC limit 20"); List<PoiMsgDBPojo> msgPojoList = new LinkedList<PoiMsgDBPojo>(); Connection connection = null; PreparedStatement statement = null; ResultSet resultSet = null; try { connection = this.dataSource.getConnection(); statement = connection.prepareStatement(preparedSQLStringBuffer.toString()); statement.setString(1, vin); statement.setLong(2, createTime); STD_LOG.info("I'm going to execute [" + statement.toString() + "]"); if (statement.execute()){ resultSet = statement.getResultSet(); while (resultSet.next()) { PoiMsgDBPojo msgDBPojo = new PoiMsgDBPojo(); msgDBPojo.setMsgId(resultSet.getString("id")); msgDBPojo.setWecarId(resultSet.getString("wecar_id")); msgDBPojo.setWeixinOpenId(resultSet.getString("weixin_openid")); msgDBPojo.setCreateTime(resultSet.getLong("create_time")); msgDBPojo.setSource(resultSet.getString("file_name")); msgDBPojo.setName(resultSet.getString("name")); msgDBPojo.setAddress(resultSet.getString("address")); msgDBPojo.setPhone(resultSet.getString("phone")); msgDBPojo.setCity(resultSet.getString("city")); msgDBPojo.setRegion(resultSet.getString("region")); msgDBPojo.setLon(resultSet.getDouble("lon")); msgDBPojo.setLat(resultSet.getDouble("lat")); msgDBPojo.setPrecision(resultSet.getInt("map_precision")); msgPojoList.add(msgDBPojo); } } } catch (SQLException e) { throw e; } finally { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } return msgPojoList; }
3、查询调用executeQuery(),针对于SELECT语句
public ArrayList getAirEnvironmentPresentAll(){ ArrayList list = new ArrayList(); String sql = "select * from airPresent"; try { ps = conn.prepareStatement(sql); rs = ps.executeQuery(); while(rs.next()){ dto = new M_AirEnviromentPresentDTO(); dto.setId(rs.getInt("id")); dto.setAirForecastPlace(rs.getString("airForecastPlace")); dto.setForecastTime(rs.getString("forecastTime")); dto.setTSPvalue(rs.getString("tspvalue")); dto.setRemark(rs.getString("remark")); list.add(dto); } } catch (SQLException e) { e.printStackTrace(); } return list; }
关于PreparedStatement.addBatch()方法
Statement和PreparedStatement的区别就不多废话了,直接说PreparedStatement最重要的addbatch()结构的使用.1.建立链接,(打电话拨号 ) Connection connection =getConnection();2.不自动 Commit (瓜子不是一个一个吃,全部剥开放桌子上,然后一口舔了)connection.setAutoCommit(false); 3.预编译SQL语句,只编译一回哦,效率高啊.(发明一个剥瓜子的方法,以后不要总想怎么剥瓜子好.就这样剥.)PreparedStatement statement = connection.prepareStatement("INSERT INTO TABLEX VALUES(?, ?)"); 4.来一个剥一个,然后放桌子上//记录1statement.setInt(1, 1); statement.setString(2, "Cujo"); statement.addBatch(); //记录2statement.setInt(1, 2); statement.setString(2, "Fred"); statement.addBatch(); //记录3statement.setInt(1, 3); statement.setString(2, "Mark"); statement.addBatch(); //批量执行上面3条语句. 一口吞了,很爽int [] counts = statement.executeBatch(); //Commit it 咽下去,到肚子(DB)里面connection.commit();
stmt.addBatch("update TABLE1 set 题目="盛夏话足部保健1" where id="3407""); stmt.addBatch("update TABLE1 set 题目="夏季预防中暑膳食1" where id="3408""); stmt.addBatch("INSERT INTO TABLE1 VALUES("11","12","13","","")"); stmt.addBatch("INSERT INTO TABLE1 VALUES("12","12","13","","")"); stmt.addBatch("INSERT INTO TABLE1 VALUES("13","12","13","","")"); stmt.addBatch("INSERT INTO TABLE1 VALUES("14","12","13","","")"); stmt.addBatch("INSERT INTO TABLE1 VALUES("15","12","13","","")"); stmt.addBatch("INSERT INTO TABLE1 VALUES("16","12","13","","")"); stmt.addBatch("INSERT INTO TABLE1 VALUES("17","12","13","","")"); stmt.addBatch("INSERT INTO TABLE1 VALUES("18","12","13","","")"); int [] updateCounts=stmt.executeBatch(); cn.commit();例如: public static void execteBatch(Connection conn)throws Exception{ String sql1 = "delete from student where id =3 "; String sql2 = "delete from student where id =5 "; String sql3 = "delete from student where id =6 "; String sql4 = "delete from student where id =7 "; PreparedStatement pstmt = conn.prepareStatement(sql1); pstmt.addBatch(); //addBatch(sql2)该方法为继承statement的方法 pstmt.addBatch(sql2); pstmt.addBatch(sql3); pstmt.addBatch(sql4); pstmt.executeBatch(); };
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC中的Statement和PreparedStatement的区别
- JDBC的Statement和PreparedStatement区别
- JDBC的Statement和PreparedStatement区别
- jdbc中 PreparedStatement 和Statement的区别
- JDBC的Statement和PreparedStatement区别
- JDBC preparedstatement和statement的区别
- Jdbc中的Statement 和PreparedStatement
- JDBC中的Statement和PreparedStatement
- Java并发编程:synchronized
- iOS开发修改UITextField的placeholder的颜色字体大小等
- 【PHP-排序算法】快速排序、堆排序算法时间复杂度比较
- 《组合数学》第二章-排列与组合
- 作业 5
- JDBC中的Statement和PreparedStatement的区别
- Android中两种序列化方式的比较Serializable和Parcelable
- 编程算法
- js 工具库
- python机器学习实战4:Logistic回归
- 如何入门NLP
- 编译Linux-4.9.11内核时遇到:“error : openssl/bio.h :No such file or folder”
- Codeforces Round #408 (Div. 2) E
- 记录一下python中遇到的问题