本章目标
了解JDBC 2.0提供的主要新特性
了解可滚动结果集的操作
了解结果集的增加、修改、删除操作
掌握批处理操作

 

JDBC 2.0操作
之前所讲解的大部分操作都是属于最基本的JDBC操作,在JDBC 2.0之后为了方便操作者进行数据库的开发提供了许多更加方便的操作,包括,可滚动的结果集,以及使用结果集直接更新数据库,如果要使用这样的特性则就必须依靠ResultSet。

 

JDBC 2.0对ResultSet的支持

JDBC 2.0操作_结果集


JDBC 2.0操作_结果集_02


 

可滚动的结果集
如果现在想取结果集中任意位置的数据,则就必须使用可滚动的结果集,可滚动的结果集操作本身并不难理解,只是在创建数据库操作对象时加入若干参数即可,如下所示:
  conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
  pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
  ResultSet.CONCUR_READ_ONLY);   // 实例化对象
  rs = pstmt.executeQuery() ;  // 实例化ResultSet对象

让结果集滚动起来
第二条数据:
——rs.absolute(1) ;
第一条数据:
——rs.beforeFirst() ;
第三条数据:
——rs.afterLast() ;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBC20ReadDemo {
	public static void main(String[] args) throws Exception {
		Connection conn=null; //数据库连接
		PreparedStatement pstmt = null;//数据库操作
		ResultSet rs = null;//保存查询结果
		String sql ="select id, name, age, sex, birthday from consumer";
		Class.forName("oracle.jdbc.driver.OracleDriver");  //加载驱动程序
		//连接数据库
		conn=DriverManager.getConnection("jdbc:oracle:thin:gome/gome@localhost:1521:oracle11");  
		//实例化对象
		pstmt = conn.prepareCall(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
		//实例化 ResultSet 对象
		rs = pstmt.executeQuery();
		System.out.println("第 2 条数据:");
		rs.absolute(1);
		print(rs, 1);
		System.out.println("第 1 条数据:");
		rs.beforeFirst();
		print(rs, 1);
		System.out.println("第 3 条数据:");
		rs.afterLast();
		print(rs, -1);
		rs.close();//关闭结果集
		pstmt.close();//操作关闭
		conn.close();  //数据库关闭
	}
	public static void print(ResultSet rs, int re) throws Exception{
		if(re >0){
			rs.next();//由前向后输出
		}else{
			rs.previous();//由后向前输出
		}
		int id = rs.getInt("id");//取得 id 内容
		String name = rs.getString("name");//取得 name 内容
		int age = rs.getInt("age");//取得 age 内容
		String sex =rs.getString("sex");//取得 sex 内容
		java.util.Date birthday = rs.getDate("birthday");//取得 birthday 内容
		System.out.print("编号:"+id+"; ");//输出编号
		System.out.print("姓名:"+name+"; ");//输出姓名
		System.out.print("年龄:"+age+"; ");//输出年龄
		System.out.print("性别:"+sex+"; ");//输出性别
		System.out.print("生日:"+birthday);//输出生日
		System.out.println("\n-----------------------------");//换行
	}
/* 结果:
 * 第 2 条数据:
 * 编号:2; 姓名:chaoyi; 年龄:30; 性别:男; 生日:2014-07-03
 * -----------------------------
 * 第 1 条数据:
 * 编号:1; 姓名:yike; 年龄:30; 性别:男; 生日:2014-07-03
 * -----------------------------
 * 第 3 条数据:
 * 编号:3; 姓名:chaoyv; 年龄:30; 性别:男; 生日:2014-07-03
 * -----------------------------
 * */
}

 

使用结果集插入数据
在JDBC 2.0中,如果要想进行数据库的更新操作,则在创建PreparedStatement对象的时候必须指定结果集是可以更新数据库的,如下所示:
  pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
  ResultSet.CONCUR_UPDATABLE);   // 实例化对象

 

直接在 consumer 表中增加数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBC20InsertDemo {
	public static void main(String[] args) throws Exception {
		Connection conn=null; //数据库连接
		PreparedStatement pstmt = null;//数据库操作
		ResultSet rs = null;//保存查询结果
		//此处不需要设置任何内容
		String sql ="select id, name, age, sex, birthday from consumer";
		Class.forName("oracle.jdbc.driver.OracleDriver");  //加载驱动程序
		//连接数据库
		conn=DriverManager.getConnection("jdbc:oracle:thin:gome/gome@localhost:1521:oracle11");  
		//实例化对象
		pstmt = conn.prepareCall(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
		//实例化 ResultSet 对象
		rs = pstmt.executeQuery();
		rs.moveToInsertRow();//移动到可以插入的数据行
		rs.updateInt("id", 6);//设置要插入的id
		rs.updateString("name", "chaoyi77");//设置要插入的姓名
		rs.updateInt("age", 23);//设置要插入的 age
		rs.updateString("sex", "男");//设置要插入的 sex
		//将今天的日期设置为生日
		rs.updateDate("birthday", new java.sql.Date(new java.util.Date().getTime()));
		rs.insertRow();//插入数据
		rs.close();//关闭结果集
		pstmt.close();//操作关闭
		conn.close();  //数据库关闭
	}
/* 结果:向数据库增加一条数据
 * */
}

 

使用结果集更新数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBC20UpdateDemo {
	public static void main(String[] args) throws Exception {
		Connection conn=null; //数据库连接
		PreparedStatement pstmt = null;//数据库操作
		ResultSet rs = null;//保存查询结果
		//此处使用预处理操作
		String sql ="select id, name, age, sex, birthday from consumer where id=?";
		Class.forName("oracle.jdbc.driver.OracleDriver");  //加载驱动程序
		//连接数据库
		conn=DriverManager.getConnection("jdbc:oracle:thin:gome/gome@localhost:1521:oracle11");  
		//实例化对象
		pstmt = conn.prepareCall(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
		pstmt.setInt(1, 4);//更新 4 号用户
		//实例化 ResultSet 对象
		rs = pstmt.executeQuery();
		rs.last();//移动到最后一行
		rs.updateString("name", "chaoyi");//设置要插入的姓名
		rs.updateInt("age", 23);//设置要插入的 age
		rs.updateString("sex", "男");//设置要插入的 sex
		//将今天的日期设置为生日
		rs.updateDate("birthday", new java.sql.Date(new java.util.Date().getTime()));
		rs.updateRow();//更新数据
		rs.close();//关闭结果集
		pstmt.close();//操作关闭
		conn.close();  //数据库关闭
	}
/* 结果:使用结果集更新
 * */
}

 

更新取消
在执行updateRow()方法前,如果发现数据库更新有错误,则可以使用cancelRowUpdates()方法取消掉之前的更新,这样就算再执行updateRow()方法,也不会去更新数据库,如下所示:
——rs.cancelRowUpdates() ;  // 取消更新
——rs.updateRow() ;  // 更新数据

 

使用结果集删除数据
  ...
  pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
  ResultSet.CONCUR_UPDATABLE);   // 实例化对象
  pstmt.setInt(1, 2) ;  // 删除2号用户
  rs = pstmt.executeQuery() ;  // 实例化ResultSet对象
  rs.last() ;  // 移动到最后一行
  rs.deleteRow() ;  // 删除数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBC20DeleteDemo {
	public static void main(String[] args) throws Exception {
		Connection conn=null; //数据库连接
		PreparedStatement pstmt = null;//数据库操作
		ResultSet rs = null;//保存查询结果
		//此处使用预处理操作
		String sql ="select id, name, age, sex, birthday from consumer where id=?";
		Class.forName("oracle.jdbc.driver.OracleDriver");  //加载驱动程序
		//连接数据库
		conn=DriverManager.getConnection("jdbc:oracle:thin:gome/gome@localhost:1521:oracle11");  
		//实例化对象
		pstmt = conn.prepareCall(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
		pstmt.setInt(1, 6);//更新 6 号用户
		//实例化 ResultSet 对象
		rs = pstmt.executeQuery();
		rs.last();//移动到最后一行
		rs.deleteRow();//删除数据
		rs.close();//关闭结果集
		pstmt.close();//操作关闭
		conn.close();  //数据库关闭
	}
/* 结果:删除指定编号的数据
 * */
}

 
批处理
在JDBC 2.0之中,最重要的概念就应该是批处理操作了。使用批处理可以一次性的插入多条SQL语句,如果要完成批处理操作,则要使用addBatch()加入要执行的一条SQL命令以及executeBatch()执行全部命令两个方法完成。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class CopyOfJDBC20BatchDemo {
	public static void main(String[] args) throws Exception {
		Connection conn=null; //数据库连接
		PreparedStatement pstmt = null;//数据库操作
		//此处使用预处理操作
		String sql ="insert into consumer (ID, NAME, AGE, SEX, BIRTHDAY)" +
				"values (id_seq.nextval, ?, ?, ?, to_date(?, 'yyyy-mm-dd'))";
		Class.forName("oracle.jdbc.driver.OracleDriver");  //加载驱动程序
		//连接数据库
		conn=DriverManager.getConnection("jdbc:oracle:thin:gome/gome@localhost:1521:oracle11");  
		//实例化对象
		pstmt = conn.prepareCall(sql);
		for(int i=0; i<10; i++){
			pstmt.setString(1, "chaoyi");
			pstmt.setInt(2, 30);
			pstmt.setString(3, "男");
			pstmt.setString(4, "1991-10-16");
			pstmt.addBatch();//加入批处理等待执行
		}
		int temp[] =pstmt.executeBatch();//批量执行
		System.out.println("更新了"+temp.length+"条数据");
		pstmt.close();//操作关闭
		conn.close();  //数据库关闭
	}
/* 结果:批量插入数据
 * 更新了10条数据
 * */
}