Introduction to the JDBC RowSet Interface in Java – Java中的JDBC RowSet接口介绍

最后修改: 2017年 12月 2日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we’re reviewing the JDBC RowSet interface. A JDBC RowSet object holds tabular data in a style that makes it more adaptable and simpler to use than a result set.

在这篇文章中,我们将回顾JDBC的RowSet接口。JDBC RowSet 对象以一种风格保存表格数据,这使得它比结果集更具适应性,使用起来更简单。

Oracle has defined five RowSet interfaces for the most frequent uses of a RowSet:

Oracle为RowSet的最频繁使用定义了五个RowSet接口:。

  • JdbcRowSet
  • CachedRowSet
  • WebRowSet
  • JoinRowSet
  • FilteredRowSet

In this tutorial, we’ll review how to use these RowSet interfaces.

在本教程中,我们将回顾如何使用这些RowSet接口。

2. JdbcRowSet

2.JdbcRowSet

Let’s start with the JdbcRowSet – we’ll simply create one by passing a Connection object to the JdbcRowSetImpl:

让我们从JdbcRowSet开始–我们将通过向JdbcRowSetImpl传递一个Connection对象来简单创建一个。

JdbcRowSet jdbcRS = new JdbcRowSetImpl(conn);
jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
String sql = "SELECT * FROM customers";
jdbcRS.setCommand(sql);
jdbcRS.execute();
jdbcRS.addRowSetListener(new ExampleListener());
while (jdbcRS.next()) {
    // each call to next, generates a cursorMoved event
    System.out.println("id = " + jdbcRS.getString(1));
    System.out.println("name = " + jdbcRS.getString(2));
}

In the above example, jdbcRs contained no data until we defined the SQL statement with the method setCommand and then ran the method execute.

在上面的例子中, jdbcRs不包含任何数据,直到我们用方法setCommand定义了SQL语句,然后运行方法execute

Also notice how, in order to perform event handling, we added a RowSetListener into the JdbcRowSet.

还请注意,为了执行事件处理,我们在JdbcRowSet.中添加了一个RowSetListener

JdbcRowSet is different than the other four RowSet implementations – because it’s always connected to the database and because of this it’s most similar to the ResultSet object.

JdbcRowSet与其他四个RowSet实现不同–因为它总是连接到数据库,正因为如此,它与ResultSet对象最为相似。

3. CachedRowSet

3.CachedRowSet

A CachedRowSet object is unique because it can operate without being connected to its data source. We call this a “disconnected RowSet object”.

CachedRowSet对象是独一无二的,因为它可以在不连接到数据源的情况下运行。我们将其称为 “断开连接的RowSet对象”。

CachedRowSet gets its name due to the fact it caches its data in memory so that it can operate on its own data instead of the data stored in a database.

CachedRowSet之所以被称为CachedRowSet,是因为它在内存中缓存了数据,这样它就可以对自己的数据而不是存储在数据库中的数据进行操作。

As CachedRowSet interface is the super interface for all disconnected RowSet objects, the code we review below is also applicable to a WebRowSet, JoinRowSet, or FilteredRowSet just as well:

由于CachedRowSet接口是所有断开连接的RowSet对象的超级接口,我们下面回顾的代码也适用于WebRowSet、JoinRowSetFilteredRowSet。

CachedRowSet crs = new CachedRowSetImpl();
crs.setUsername(username);
crs.setPassword(password);
crs.setUrl(url);
crs.setCommand(sql);
crs.execute();
crs.addRowSetListener(new ExampleListener());
while (crs.next()) {
    if (crs.getInt("id") == 1) {
        System.out.println("CRS found customer1 and will remove the record.");
        crs.deleteRow();
        break;
    }
}

4. WebRowSet

4.WebRowSet

Next, let’s have a look at the WebRowSet.

接下来,让我们看一下WebRowSet

This is also unique because, in addition to offering the capabilities of a CachedRowSet object, it can write itself to an XML document and can also read that XML document to convert itself back to a WebRowSet:

这也是独一无二的,因为除了提供CachedRowSet对象的功能外,它可以将自己写入一个XML文档t,也可以读取该XML文档,将自己转换回WebRowSet

WebRowSet wrs = new WebRowSetImpl();
wrs.setUsername(username);
wrs.setPassword(password);
wrs.setUrl(url);
wrs.setCommand(sql);
wrs.execute();
FileOutputStream ostream = new FileOutputStream("customers.xml");
wrs.writeXml(ostream);

Using the writeXml method, we write the current state of a WebRowSet object to an XML document.

使用 writeXml方法,我们将WebRowSet对象的当前状态写入一个XML文档中。

By passing the writeXml method an OutputStream object, we write in bytes instead of characters, which can be quite helpful to handle all forms of data.

通过向writeXml方法传递一个OutputStream对象,我们用字节而不是字符来写,这对处理所有形式的数据都很有帮助。

5. JoinRowSet

5.JoinRowSet

JoinRowSet lets us create a SQL JOIN between RowSet objects when these are in memory. This is significant because it saves us the overhead of having to create one or more connections:

JoinRowSet让我们在RowSet对象之间创建一个SQLJOIN,当这些对象处于内存中时。这很重要,因为它为我们节省了创建一个或多个连接的开销。

CachedRowSetImpl customers = new CachedRowSetImpl();
// configuration of settings for CachedRowSet
CachedRowSetImpl associates = new CachedRowSetImpl();
// configuration of settings for this CachedRowSet            
JoinRowSet jrs = new JoinRowSetImpl();
jrs.addRowSet(customers,ID);
jrs.addRowSet(associates,ID);

Because each RowSet object added to a JoinRowSet object needs a match column, the column on which the SQL JOIN is based, we specify “id” in the addRowSet method.

因为每个添加到JoinRowSet对象的RowSet对象都需要一个匹配列,即SQL JOIN所基于的列,我们在addRowSet方法中指定“id”

Note that, rather than using the column name, we could have also used the column number.

请注意,与其使用列名,我们还可以使用列号。

6. FilteredRowSet

6.FilteredRowSet(过滤行集)

Finally, the FilteredRowSet lets us cut down the number of rows that are visible in a RowSet object so that we can work with only the data that is relevant to what we are doing.

最后,FilteredRowSet 让我们减少RowSet对象中可见的行的数量,以便我们可以只处理与我们正在做的事情相关的数据。

We decide how we want to “filter” the data using an implementation of the Predicate interface:

我们使用Predicate接口的实现来决定我们要如何 “过滤 “数据。

public class FilterExample implements Predicate {
    
    private Pattern pattern;
    
    public FilterExample(String regexQuery) {
        if (regexQuery != null && !regexQuery.isEmpty()) {
            pattern = Pattern.compile(regexQuery);
        }
    }
 
    public boolean evaluate(RowSet rs) {
        try {
            if (!rs.isAfterLast()) {
                String name = rs.getString("name");
                System.out.println(String.format(
                  "Searching for pattern '%s' in %s", pattern.toString(),
                  name));
                Matcher matcher = pattern.matcher(name);
                return matcher.matches();
            } else
                return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    // methods for handling errors
}

Now we apply that filter to a FilteredRowSet object:

现在我们将该过滤器应用于FilteredRowSet对象。

RowSetFactory rsf = RowSetProvider.newFactory();
FilteredRowSet frs = rsf.createFilteredRowSet();
frs.setCommand("select * from customers");
frs.execute(conn);
frs.setFilter(new FilterExample("^[A-C].*"));
            
ResultSetMetaData rsmd = frs.getMetaData();
int columncount = rsmd.getColumnCount();
while (frs.next()) {
    for (int i = 1; i <= columncount; i++) {
        System.out.println(
          rsmd.getColumnLabel(i)
          + " = "
          + frs.getObject(i) + " ");
        }
    }

7. Conclusion

7.结语

This quick tutorial covered the five standard implementations of the RowSet interface available in the JDK.

这个快速教程涵盖了JDK中可用的RowSet接口的五个标准实现。

We discussed the configuration of each implementation and mentioned the differences between them.

我们讨论了每个实施方案的配置,并提到了它们之间的差异。

As we pointed out, only one of the RowSet implementations is a connected RowSet object – the JdbcRowSet. The other four are disconnected RowSet objects.

正如我们所指出的,只有一个RowSet实现是连接的RowSet对象 – JdbcRowSet。其他四个是断开连接的RowSet对象。

And, as always, the full code for this article can be found over on Github.

而且,像往常一样,本文的完整代码可以在Github上找到over