【1】PreparedStatement
PreparedStatement
接口提供了三种执行 SQL 语句的方法:executeQuery
、executeUpdate
和 execute
。
使用哪一个方法由 SQL 语句所产生的内容决定。一般的使用习惯Select语句使用executeQuery()方法执行,Delete、Update、Insert语句使用executeUpdate()方法执行,而Create和Drop语句使用execute()方法执行,当然也可以使用executeUpdate()方法。
① executeQuery
用于产生单个结果集的语句,例如 SELECT 语句。 被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。
② executeUpdate
用于执行 INSERT
、UPDATE
或 DELETE
语句以及 SQL DDL
(数据定义语言)语句,例如 CREATE TABLE
和 DROP TABLE
。
INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。
对于 CREATE TABLE 或 DROP TABLE 等不操作行的句,executeUpdate 的返回值总为零。
使用executeUpdate方法是因为在 createTable 中的 SQL 语句是 DDL (数据定义语言)语句。创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 用于更新表的时间更多,因为表只需要创建一次,但经常被更新。
③ 方法execute
用于执行返回多个结果集、多个更新计数或二者组合的语句。也可用于执行 INSERT、UPDATE 或 DELETE 语句。
④ 用法举例
① 增加、修改、删除都用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; }
② 查询调用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; }
【2】批处理
JDBC使用Statement和PreparedStatement实现批处理功能。
① PreparedStatement
步骤如下:
- 根据connection和SQL得到PreparedStatement;
- 设置参数并 addBatch();
- 重复第二步直到所有需要执行的SQL参数设置完;
- executeBatch()将一批SQL提交给数据库来执行。
② Statement
步骤如下:
- 根据connection得到Statement;
- addBatch(String sql)在批处理缓存中加入一条sql语句;
重复第二步直到所有需要执行的SQL添加完;
executeBatch()将一批SQL提交给数据库来执行。
注意:PreparedStatement中使用批量更新时,要先设置好参数后再使用addBatch()方法加入缓存。批量更新中只能使用更改、删除或插入语句,不能有select语句。
① 批量插入
① 使用Statement
实例如下:
/* *1,首先把Auto commit设置为false,不让它自动提交 *2,进行手动提交(commit) *3,提交完成后回复现场将Auto commit,还原为true, *4,当异常发生执行catch中SQLException时,记得要rollback(回滚); **/ public static void main(String args[]) { Connection con = null; Statement stm = null; try { con = JDBTools.getConnection(); stm = con.createStatement(); con.setAutoCommit(false); // 若不出现异常,则继续执行到try语句完,否则跳转到catch语句中 stm.addBatch("insert into student values(1,'jane','高数',100)"); stm.addBatch("insert into student values(2,'lily','c#',98)"); stm.addBatch("insert into student values(3,'lucy','java',90)"); stm.addBatch("insert into student values(4,'tom','英语',89)"); stm.addBatch("insert into student values(5,'jack','java',63)"); /* * int[] executeBatch() throws * SQLException将一批命令提交给数据库来执行,如果全部命令执行成功, * 则返回更新计数组成的数组。 */ stm.executeBatch(); System.out.println("插入成功!"); // commit:若成功执行完所有的插入操作,则正常结束 con.commit(); System.out.println("提交成功!"); con.setAutoCommit(true); } catch (SQLException e) { e.printStackTrace(); try { //rollback: 若出现异常,对数据库中所有已完成的操作全部撤销,则回滚到事务开始状态 if (!con.isClosed()) { con.rollback(); System.out.println("提交失败,回滚!"); con.setAutoCommit(true); } } catch (SQLException e1) { e1.printStackTrace(); } finally { JDBTools.closeStatement(stm); JDBTools.closeConnection(con); } } }
② 使用PreparedStatement
实例如下:
public static void main(String args[]) { Connection con = null; PreparedStatement pstm = null; try { // 1. 建立与数据库的连接 con = JDBTools.getConnection(); // 2. 准备并添加批量处理sql语句 // 1)创建PreparedStatement语句(发送slq请求): pstm = con.prepareStatement("insert into student values(?,?,?,?)"); //首先把Auto commit设置为false,不让它自动提交 con.setAutoCommit(false); // 2) 设置sql语句1参数 pstm.setInt(1, 33); pstm.setString(2,"wangqin"); pstm.setString(3, "c++"); pstm.setDouble(4, 78.5); // 3) 添加到此 PreparedStatement 对象的批处理命令中。 pstm.addBatch(); //设置sql语句2 pstm.setInt(1, 34); pstm.setString(2,"wuytun"); pstm.setString(3, "c"); pstm.setDouble(4, 77); // 添加到此 PreparedStatement 对象的批处理命令中。 pstm.addBatch(); // 设置sql语句3 pstm.setInt(1, 31); pstm.setString(2,"tetet"); pstm.setString(3, "c++"); pstm.setDouble(4, 90); //添加到此 PreparedStatement 对象的批处理命令中。 pstm.addBatch(); // 将一批sql提交给数据库来执行,如果全部命令执行成功, //则返回更新计数组成的数组。 pstm.executeBatch(); System.out.println("插入成功!"); // 若成功执行完所有的插入操作,则正常结束 //进行手动提交(commit) con.commit(); System.out.println("提交成功!"); //提交完成后回复现场将Auto commit,还原为true, con.setAutoCommit(true); } catch (SQLException e) { e.printStackTrace(); try { // 若出现异常,对数据库中所有已完成的操作全部撤销,则回滚到事务开始状态 if(!con.isClosed()){ con.rollback(); System.out.println("插入失败,回滚!"); con.setAutoCommit(true); } } catch (SQLException e1) { e1.printStackTrace(); } }finally{ JDBTools.closePreparedStatement(pstm); JDBTools.closeConnection(con); } }
② 批量删除
使用PreparedStatement实例
public void deleteBat(Integer[] catNo){ try { Connection con=JDBTools.getConnection(); String sql="delete from cat where catno=?"; con.setAutoCommit(false); PreparedStatement ps=con.prepareStatement(sql); for (Integer in : catNo) { ps.setInt(1, in); ps.addBatch(); } int[] result=ps.executeBatch(); con.commit(); for (int i : result) { System.out.println(i); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }
其实无论插入,删除和更新,核心思想都一样,都是博文片头的步骤。