Más contenido relacionado
La actualidad más candente (20)
Similar a Row Set初步学习V1.1 (20)
Row Set初步学习V1.1
- 1. RowSet 初步学习
Zianed Hou
zianed@live.cn
0、javax.sql.RowSet接口
1、JdbcRowSet
2、CachedRowSet
3、WebRowSet
4、JoinRowSet
5、FilteredRowSet
6、数据更新以及事务
7、事件注册监听
8、tomcat自带的连接池,使用dbcp配置
Zianed Version 1.1 1
- 2. 0、javax.sql.RowSet接口
javax.sql.rowset 包在 jdk1.4 的 javax.sql 包中有一个 RowSet 接口; jdk1.5 后引
入了 javax.sql.rowset 包中的五个子接口和 com.sun.rowset 包中对应的五个实现
类。jdk1.5 中 RowSet 的五个子接口分别是
JdbcRowSet,CachedRowSet,WebRowSet,JoinRowSet 和 FilteredRowSet。
RowSet 对象可分为两类:有连接的和无连接的。JdbcRowSet 是唯一一个有
连接的实现, 和传统的 ResultSet 一个样, 有连接的实现是基于 Jdbc 驱动的连接,
数据库的连接是贯穿整个对数据库的操作。而无连接的实现是基于 Reader 和
Writer 流的连接,在需要读取数据和写入数据的时候才建立连接,在整个操作过
程中都是断开连接的,后面四个接口都是无连接的实现(Disconnected RowSet) 。
1、JdbcRowSet
JdbcRowSet 是唯一一个有连接的实现,和传统的 ResultSet 一样,基于 Jdbc
驱动的连接。
JdbcRowSet 继承了 javax.sql.RowSet 接口,RowSet 接口继承自 ResultSet 接口;
。
JdbcRowSet 也继承了 javax.sql.rowset.Joinable 可连接的接口。
JdbcRowSet 只是增加了几个方法,它对结果集的操作方法和 ResultSet 都是一样
的 , 他 基 本 上 和 ResultSet 有 类 似 的 功 能 , 它 的 结 果 集 默 认 是
ResultSet.TYPE_SCROLL_INSENSITIVE
和 ResultSet.CONCUR_UPDATABLE 的,即可上下滚动和可更新的。得到该对象
之后就可以使用相应的方法对数据进行遍历,更新,插入或者删除。
它同样也可以链接数据源进行相应操作。
注:虽然 JdbcRowSet 默认是可滚动和可更新的,但需要数据库驱动支持的,如 MySql 驱动
就不支持更新结果集,需要注意文档。
1)采用设置结果集的方式
String url = "jdbc:mysql://127.0.0.1:3306/zianed";
String login = "root";
String password = "";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection(url, login, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from person");
JdbcRowSet rowSet = new JdbcRowSetImpl(rs);
2)采用设置 URLusernamepasswordcommand 进行执行
// JdbcRowSet
Zianed Version 1.1 2
- 3. Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
JdbcRowSet rowSet = new JdbcRowSetImpl();
rowSet.setUrl(url);
rowSet.setUsername(username);
rowSet.setPassword(password);
rowSet.setCommand(empSql);
rowSet.execute();
printRowSet(rowSet, "JdbcRowSet");
rowSet.close();
3)绑定到数据源
容器是 tomcat 环境
JNDI 名字是 java:comp/env/jdbc/linary 的话
JdbcRowSet jrs=new JdbcRowSetImpl();
jrs.setDataSourceName("java:comp/env/jdbc/linary");
jrs.setCommand("select * from emp");
jrs.execute();
int numcols = jrs.getMetaData().getColumnCount();
System.out.println("JdbcRowSet Result:");
out.print("JdbcRowSet Result<br/>");
while (jrs.next()) {
for (int i = 1; i <= numcols; i++) {
out.print(jrs.getString(i) + "t");
}
out.print("<br/>");
}
jrs.close();
2、CachedRowSet
CachedRowSet 继承于 RowSet 接口,读入数据保存在缓存进行相应的操作。
JdbcRowSet 也继承了 javax.sql.rowset.Joinable 可连接的接口。
创建接口对象就是在构造方法里面传递一个 SyncProvider。CachedRowSet 对象可以使用任
何已向 SyncFactory 单件注册的 SyncProvider 实现。无连接的 RowSet 都是基于流读写的,
那么这里所说的 SyncProvider 就是提供了特定的 Reader 和 Writer。
jdk1.5 文档的 Sample Coder 有这样的实现:
String provider= "com.fred.providers.HighAvailabilityProvider";
CachedRowSet crs=new CachedRowSetImpl(provider);
为 RowSet 设置了特定的 Reader 和 Writer。
Zianed Version 1.1 3
- 4. 默认的 SyncProvider,CachedRowSet 对象的属性设置为 BaseRowSet 对象的默认属性,此
外,它将 RIOptimisticProvider 对象作为其同步提供者。RIOptimisticProvider(RI 中包含的
两个 SyncProvider 实现之一) 是在没有指定同步提供者时, SyncFactory 单件 (singleton) 将
提供的默认提供者。 。
CachedRowSet 提供分页功能。
crs.setPageSize(5);
设置每页显示的行数。在 Reader 读取数据的时候就只读取指定的行数的数据即可。
测试代码:
// CachedRowSet
CachedRowSet crs = new CachedRowSetImpl();
crs.setUrl(url);
crs.setUsername(username);
crs.setPassword(password);
crs.setCommand(empSql);
crs.setPageSize(5);
crs.execute();
System.out.println("CachedRowSet Result:");
while (crs.nextPage())
{
System.out.println("Next page:");
while (crs.next())
{
System.out.println(crs.getString(1) + "t"
+ crs.getString(2));
}
}
crs.close();
3、WebRowSet
WebRowSet 继承自 CachedRowSet.
封装了读写 XML 的方法, 可以把数据库的数据持久化到 XML 文件或者从 XML 文件读
取数据写入数据库中。
1) 属性
XML Schema 定义的公共标示符
public static String PUBLIC_XML_SCHEMA =
"--//Sun Microsystems, Inc.//XSD Schema//EN";
标准的 WebRowSet XML 模式定义位于以下 URI 中:
public static String SCHEMA_SYSTEM_ID =
"http://java.sun.com/xml/ns/jdbc/webrowset.xsd";
Zianed Version 1.1 4
- 5. 2)写入到文件或流中:通过以下方法
public void writeXml(ResultSet rs, java.io.Writer writer)
public void writeXml(ResultSet rs, java.io.OutputStream oStream)
public void writeXml(java.io.Writer writer)
public void writeXml(java.io.OutputStream oStream)
写入到 XML 文件的方法是 wrs.writeXML(new FileOutputStream("data.xml"));把内存中行集数
据写入到文件 data.xml 中。该文件记录了以下三类数据:
properties:包括 setXXX()方法所有的属性,没有设置的就是默认属性
metadata: 包括数据库表的相关元数据, 对应 ResultSetMetaData 里的信息。 包括 column-count
和 column-definition
data:结果集的全部数据。包括 currentRow 的数据
3)从文件或流中读入到 WebRowSet 中
public void readXml(java.io.Reader reader)
public void readXml(java.io.InputStream iStream)
从 xml 文件读取数据装载到 WebRowSet 的方法是 readXML(…);只要是按照规范的格式写的
xml 都可以装载进来。
测试代码:
// WebRowSet
WebRowSet wrs = new WebRowSetImpl();
wrs.setUrl(url);
wrs.setUsername(username);
wrs.setPassword(password);
wrs.setCommand(empSql);
wrs.execute();
wrs.writeXml(new FileOutputStream("c:emp.xml"));
wrs.beforeFirst();
printRowSet(wrs, "WebRowSet");
wrs.close();
// WebRowSet File
WebRowSet wrs2 = new WebRowSetImpl();
wrs2.readXml(new FileInputStream("c:emp.xml"));
printRowSet(wrs2, "WebRowSet File");
wrs2.close();
4、JoinRowSet
在无连接的状态下直接对结果集进行 Join。
JoinRowSet 继承于 WebRowSet 接口
Zianed Version 1.1 5
- 6. 默认的 Join 是 inner join 的,还支持 cross join,full join,left outer join 和 right outer join,使用
setJoinType()方法来进行设置,但是需要数据库的支持。
五种联合方式
判断是否支持的方法(返回
联合方式 对应的常数
布尔值)
内连接(INNER JOIN)JoinRowSet.INNER_JOIN supportsInnerJoin()
左外连接(LEFT
JoinRowSet.LEFT_OUTER_JOIN supportsLeftOuterJoin()
OUTER JOIN)
右外连接(RIGHT
JoinRowSet.RIGHT_OUTER_JOINsupportsRightOuterJoin()
OUTER JOIN)
全外连接(FULL
JoinRowSet.FULL_JOIN supportsFullJoin()
OUTER JOIN)
交叉连接(CROSS
JoinRowSet.CROSS_JOIN supportsCrossJoin()
JOIN)
设置匹配列的另外的方法:
jdbcRS.setMatchColumn(“ID”);
joinRS.addRowSet(jdbcRS);
测试代码:
// JoinRowSet
CachedRowSet crs1 = new CachedRowSetImpl();
crs1.setUrl(url);
crs1.setUsername(username);
crs1.setPassword(password);
crs1.setCommand(empSql);
crs1.execute();
CachedRowSet crs2 = new CachedRowSetImpl();
crs2.setUrl(url);
crs2.setUsername(username);
crs2.setPassword(password);
crs2.setCommand(deptSql);
crs2.execute();
JoinRowSet jrs = new JoinRowSetImpl();
jrs.setJoinType(JoinRowSet.INNER_JOIN);
jrs.addRowSet(crs1, "deptno");
jrs.addRowSet(crs2, "deptno");
printRowSet(jrs, "JoinRowSet");
crs1.close();
crs2.close();
jrs.close();
Zianed Version 1.1 6
- 7. 5、FilteredRowSet
采用实现 Predicate 来实现在无连接的情况下的 RowSet 的过滤,仅显示某些满足条件的数
据。
FilteredRowSet 继承于 WebRowSet 接口
增加了两个方法:
public void setFilter(Predicate p)
public Predicate getFilter()
设置和取得过滤条件。
Javax.sql.rowset.Predicate 接口的三个未实现方法
public boolean evaluate(RowSet rs)
public boolean evaluate(Object value, int column)
public boolean evaluate(Object value, String columnName)
evaluate(RowSet rs)方法:
此方法通常称为 FilteredRowSet 对象内部方法(非公共),它控制 RowSet 对象的指针
从一行移动到下一行。此外,如果此内部方法将指针移动到一个已删除的行上,则其将继续
移动指针,直到找到一个有效行为止。
evaluate(Object value, int column)方法和 public boolean evaluate(Object
value, String columnName)方法判断插入时,插入的数据是否在有效的 RowSet 范围之
内。
测试代码:
// FilteredRowSet
FilteredRowSet frsRowSet = new FilteredRowSetImpl();
frsRowSet.setUrl(url);
frsRowSet.setUsername(username);
frsRowSet.setPassword(password);
frsRowSet.setCommand(empSql);
frsRowSet.execute();
frsRowSet.beforeFirst();
frsRowSet.setFilter(new Filter());
System.out.println("FilteredRowSet Result:");
int index = 1;
while (frsRowSet.next())
{
System.out.println(frsRowSet.getString(1) + "t"
+ frsRowSet.getString(2) + "t"
+ frsRowSet.getString(4));
index++;
}
Zianed Version 1.1 7
- 8. System.out.println("FilteredRowSet Result " + index + "
rows.");
frsRowSet.close();
Filter 类如下进行数据过滤操作:
class Filter implements Predicate {
public Filter() {
}
public boolean evaluate(RowSet rs) {
// 此判断是必须的,否则在循环中,有时间到最后一个的时间会报错
//
if (rs == null) {
return false;
}
FilteredRowSet frs = (FilteredRowSet) rs;
boolean evaluation = false;
try {
int columnValue = frs.getInt(4);
if (columnValue >= 2000) {
evaluation = true;
}
return evaluation;
} catch (SQLException e) {
//此处抛出异常是正常行为
//不必进行处理,直接返回flase即可
e.printStackTrace();
return false;
}
}
@Override
public boolean evaluate(Object value, int column) throws SQLException
{
return false;
}
@Override
public boolean evaluate(Object value, String columnName)
throws SQLException {
return false;
}
Zianed Version 1.1 8
- 9. }
6、数据更新以及事务
insertRow()、deleteRow()、updateRow()只是在内存中更新了该行,同步到数据库需
要调用方法 acceptChanges() 或 acceptChanges(Connection)。如果 CachedRowSet
中保存着原数据库连接信息,则可以调用 acceptChanges();否则,则应该传入可用的
数据库连接或重新设置数据库连接参数。
增加
cachedRS.last();
cachedRS.moveToInsertRow();//转到要增加的那一行
cachedRS.updateInt(1, 3);
cachedRS.updateString(2, "Bob"); //$NON-NLS-1$
cachedRS.updateString(3, "A new user"); //$NON-NLS-1$
cachedRS.insertRow();//只是在内存中处理
cachedRS.moveToCurrentRow();
cachedRS.acceptChanges();//在数据库中更改
更新
cachedRS.next();//找到要更新的数据
cachedRS.updateString(2, "Terry");//更新数据
cachedRS.updateRow();//只是在内存中处理
conn.setAutoCommit(false);
try {
cachedRS.acceptChanges(conn);//在数据库中更改
cachedRS.commit();
} catch (SyncProviderException e) {
// expected
cachedRS.rollback();
}
删除
cachedRS.absolute(2);//删除第二行数据
cachedRS.deleteRow();//只是在内存中处理
cachedRS.acceptChanges();//在数据库中更改
处理事务,在不成功时回滚数据。
cachedRS.updateRow();
conn.setAutoCommit(false);
try {
cachedRS.acceptChanges(conn);
cachedRS.commit();
} catch (SyncProviderException e) {
Zianed Version 1.1 9
- 10. // expected
cachedRS.rollback();
}
conn.setAutoCommit(true);
7、事件注册监听
一个监听器需要实现 RowSetListener 接口。RowSetListener 支持三种事件监听:cursor
moved、row changed 和 rowSet changed。
Javax.sql.RowSetListener
public interface RowSetListener extends java.util.EventListener
给 RowSet 注册事件:RowSet.addRowSetListener
以通过相应的处理来监控对数据的操作。
监控三种事件
void rowSetChanged(RowSetEvent event);//监控rowSet的改变
void rowChanged(RowSetEvent event);//监控row的改变
void cursorMoved(RowSetEvent event);//监控游标的移动
CachedRowSet 中会触发监听器的方法
cursor moved row changed rowSet changed
absolute() √
relative() √
next() √
previous() √
first() √
last() √
beforeFirst() √
afterLast() √
updateRow() √
deleteRow() √
insertRow() √
undoDelete() √
undoUpdate() √
undoInsert() √
populate() √
acceptChanges() √
acceptChanges(Connection) √
execute() √
execute(Connection) √
nextPage() √
previousPage() √
Zianed Version 1.1 10
- 11. restoreOriginal() √
release() √
8、tomcat自带的连接池,使用dbcp配置
Tomcat6 本身集成了 dbcp 连接池${CATALINA_HOME}libtomcat-dbcp.jar,
通过该包可以构造 dbcp 连接池。如下所示:
测试代码:
public static DataSource initDataSource(String url, String username,
String password)
{
BasicDataSource bds = new BasicDataSource();
bds.setUrl(url);
bds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
bds.setUsername(username);
bds.setPassword(password);
bds.setMaxActive(5);
return bds;
}
public static void closeDataSource(DataSource ds) throws SQLException
{
BasicDataSource bds = (BasicDataSource) ds;
bds.close();
}
/**
* @param args
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException
{
String url = "jdbc:oracle:thin:@testdb:1521:orcl";
String username = "scott";
String password = "tiger";
String empSql = "select empno,ename,mgr,sal,deptno from emp";
String deptSql = "select deptno,dname,loc from dept";
Zianed Version 1.1 11
- 12. // 创建BasicDataSource
DataSource dataSource = initDataSource(url, username, password);
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
// 创建JDBC对象
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try
{
conn = dataSource.getConnection();
st = conn.createStatement();
rs = st.executeQuery(empSql);
System.out.println("ResultSet Results:");
int numcols = rs.getMetaData().getColumnCount();
while (rs.next())
{
for (int i = 1; i <= numcols; i++)
{
System.out.print(rs.getString(i) + "t");
}
System.out.println();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{
try
{
if (rs != null)
{
rs.close();
}
if (st != null)
{
st.close();
}
Zianed Version 1.1 12
- 13. if (conn != null)
{
conn.close();
}
if (dataSource != null)
{
closeDataSource(dataSource);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
} }
References
Rowset
http://www.ibm.com/developerworks/cn/java/j-lo-java6rowset/
http://hi.baidu.com/li_zhongnan/blog/item/52f43b9460aaa818d31b705f.html
http://blog.csdn.net/zglluck/archive/2008/10/25/3144793.aspx
Dbcp
http://commons.apache.org/dbcp/
Apache-SVN
http://svn.apache.org/viewvc/
Zianed Version 1.1 13