三种不同的Statement:Statement、PreparedStatement、CallableStatement
(1)最普通的Statement:Connection.createStatement()
(2)可以灵活指定SQL语句中的变量PreparedStatement
pstmt = Connection.prepareStatement("insert into sample values(?,?,?)") (?为占位符)
pstmt.executeUpdate()执行。
(3)对存储过程进行调用CallableStatement:cstmt = Connection.prepareCall("{call p(?,?,?,?)}")
调用存储过程需要指定存储过程中参数的类型,假设存储过程p要四个参数,第1、2个参数为输入参数,第3、4个参数为输出参数
- cstmt.registerOutParameter(3, java.sql.Types.INTEGER);
- cstmt.registerOutParameter(4, java.sql.Types.INTEGER);
- cstmt.setInt(1,3);
- cstmt.setString(2,"123");
- cstmt.execute();
JDBC进行批处理,一次执行多条SQL语句 Batch:
Statement的做法:
- String[] sql = {"insert into sample values(1001,'tt',22)",
- "insert into sample values(1002,'yy',21)",
- "insert into sample values(1003,'qq',20)"};
- for(int i=0; i<sql.length; i++) {
- stmt.addBatch();
- }
- stmt.executeBatch();
preparedStatement的做法:
- pstmt = Connection.prepareStatement("insert into sample values(?,?,?)");
- pstmt.setInt(1, 1001);
- pstmt.setString(2, "tt");
- pstmt.setInt(3, 22);
- pstmt.addBatch();
- pstmt.setInt(1, 1002);
- pstmt.setString(2, "yy");
- pstmt.setInt(3, 22);
- pstmt.addBatch();
- pstmt.setInt(1, 1001);
- pstmt.setString(2, "qq");
- pstmt.setInt(3, 22);
- pstmt.addBatch();
- pstmt.executeBatch();
事务Transaction,银行转账 事务回滚:
默认状态DML语句会自动提交这样如果上一条语句执行成功的时候,下一条语句没有成功,会出现脏数据,这样的情况是不允许出现的,事务就是解决这种问题的。
- try {
- conn.setAutoCommit(false); //设置不自动提交
- stmt = conn.createStatement();
- String[] sql = {"insert into sample values(1001,'tt',22)",
- "insert into sample values(1002,'yy',21)",
- "insert into sample values(1003,'qq',20)"};
- for(int i=0; i<sql.length; i++) {
- stmt.addBatch();
- }
- stmt.executeBatch();
- conn.commit(); //手动提交
- conn.setAutoCommit(true); //恢复现场
- } catch(SQLException e) {
- System.out.println("执行sql语句时出现异常,操作将被撤销!");
- try {
- if(onn != null) {
- conn.rollback();
- conn.setAutoCommit(true); //恢复现场
- }
- } catch(SQLException e) {
- e.printStackTrace();
- }
- } finally {
- //关闭操作
- }
可滚动的结果集 Movable ResultSet:
- stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
- ResultSet rs = stmt.executeQuery("select * from sample");
- rs.next();
- rs.last(); //往最后一条记录滚
- rs.previous();
- rs.absolute(6); //定位到第6条记录
- rs.getRow(); //返回记录总数
可更新的结果集 Updatable ResultSet:
- stmt = conn.createStatement(ResultSet.Type_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
- rs = stmt.executeQuery("select * from sample");
- rs.next();
- rs.updateString("xxxx", "AAAA"); //更新某个字段
- rs.updateRow(); //和上一句同时使用得到更新
- //插入新行
- rs.moveToInsertRow();
- rs.updateXXX(); //为新插入的行更新数据
- rs.insertRow();
- //将光标移动到新行
- rs.moveToCurrentRow();
- //删除行
- rs.absolute(5);
- rs.deleteRow();
- //取消更新
- rs.cancelRowUpdates();
说明:rs是一个结果集,它应该是一个指针(Java中没有指针的显示概念),我们在做操作的时候,首先要对其进行定位,然后才可以执行操作。
JDBC的更新:
DataSource和RowSet
DriverManager -> DataSource
ResultSet -> RowSet