# 使用 JoinRowSet 对象

> 原文： [https://docs.oracle.com/javase/tutorial/jdbc/basics/joinrowset.html](https://docs.oracle.com/javase/tutorial/jdbc/basics/joinrowset.html)

`JoinRowSet`实现允许您在`RowSet`对象未连接到数据源时创建 SQL `JOIN`。这很重要，因为它节省了必须创建一个或多个连接的开销。

涵盖以下主题：

*   [创建 JoinRowSet 对象](#creating-joinrowset-object)
*   [添加 RowSet 对象](#adding-rowset-objects)
*   [管理匹配列](#managing-match-columns)

`JoinRowSet`接口是`CachedRowSet`接口的子接口，因此继承了`CachedRowSet`对象的功能。这意味着`JoinRowSet`对象是断开连接的`RowSet`对象，可以在不始终连接到数据源的情况下运行。

`JoinRowSet`对象充当 SQL `JOIN`的持有者。以下代码行显示创建`JoinRowSet`对象：

```
JoinRowSet jrs = new JoinRowSetImpl();

```

变量`jrs`在添加`RowSet`对象之前不会保留任何内容。

**注意**：或者，您可以使用 JDBC 驱动程序的`JoinRowSet`实现中的构造函数。但是，`RowSet`接口的实现将与参考实现不同。这些实现将具有不同的名称和构造函数。例如，Oracle JDBC 驱动程序的`JoinRowSet`接口实现名为`oracle.jdbc.rowset.OracleJoinRowSet`。

任何`RowSet`对象都可以添加到`JoinRowSet`对象中，只要它可以是 SQL `JOIN`的一部分即可。可以添加`JdbcRowSet`对象，该对象始终连接到其数据源，但通常通过直接操作数据源而不是成为`JOIN`的一部分而成为`JOIN`的一部分。 `JoinRowSet`对象。提供`JoinRowSet`实现的目的是使断开的`RowSet`对象成为`JOIN`关系的一部分成为可能。

The Coffee Break 连锁咖啡馆的老板想要获得他从 Acme，Inc。购买的咖啡清单。为了做到这一点，店主必须从两个表格`COFFEES`和`SUPPLIERS`获取信息。在`RowSet`技术之前的数据库世界中，程序员会将以下查询发送到数据库：

```
String query =
    "SELECT COFFEES.COF_NAME " +
    "FROM COFFEES, SUPPLIERS " +
    "WHERE SUPPLIERS.SUP_NAME = Acme.Inc. " +
    "and " +
    "SUPPLIERS.SUP_ID = COFFEES.SUP_ID";

```

在`RowSet`技术的世界中，您无需向数据源发送查询即可完成相同的结果。您可以将包含两个表中数据的`RowSet`对象添加到`JoinRowSet`对象。然后，因为所有相关数据都在`JoinRowSet`对象中，您可以对其执行查询以获取所需数据。

来自 [`JoinSample.testJoinRowSet`](gettingstarted.html) 的以下代码片段创建两个`CachedRowSet`对象，`coffees`填充表`COFFEES`中的数据，`suppliers`填充表`SUPPLIERS`中的数据。 `coffees`和`suppliers`对象必须连接到数据库以执行其命令并填充数据，但在此之后，它们不必再次重新连接以形成`JOIN`。

```
coffees = new CachedRowSetImpl();
coffees.setCommand("SELECT * FROM COFFEES");
coffees.setUsername(settings.userName);
coffees.setPassword(settings.password);
coffees.setUrl(settings.urlString);
coffees.execute();

suppliers = new CachedRowSetImpl();
suppliers.setCommand("SELECT * FROM SUPPLIERS");
suppliers.setUsername(settings.userName);
suppliers.setPassword(settings.password);
suppliers.setUrl(settings.urlString);
suppliers.execute(); 

```

查看`SUPPLIERS`表，您会看到 Acme，Inc。的识别号码是 101.表`COFFEES`中咖啡与供应商识别号码 101 是 Colombian 和 Colombian_Decaf。可以从两个表中连接信息，因为这两个表具有`SUP_ID in common`列。在 JDBC `RowSet`技术中，`JOIN`所在的列`SUP_ID`称为 _ 匹配列 _。

添加到`JoinRowSet`对象的每个`RowSet`对象必须具有匹配列，即`JOIN`所基于的列。有两种方法可以为`RowSet`对象设置匹配列。第一种方法是将匹配列传递给`JoinRowSet`方法`addRowSet`，如下面的代码行所示：

```
jrs.addRowSet(coffees, 2);

```

这行代码将`coffees` `CachedRowSet`添加到`jrs`对象，并将`coffees`（`SUP_ID`）的第二列设置为匹配列。代码行也可以使用列名而不是列号。

```
jrs.addRowSet(coffees, "SUP_ID");

```

此时，`jrs`中只有`coffees`。添加到`jrs`的下一个`RowSet`对象必须能够与`coffees`形成`JOIN`，这与`suppliers`相同，因为两个表都有 SUP_ID 列。以下代码行将`suppliers`添加到`jrs`并将列 SUP_ID 设置为匹配列。

```
jrs.addRowSet(suppliers, 1);

```

现在`jrs`在`coffees`和`suppliers`之间包含`JOIN`，所有者可以从中获取 Acme，Inc。提供的咖啡的名称。因为代码没有设置`JOIN`的类型，`jrs`保持内部 JOIN，这是默认值。换句话说，`jrs`中的行组合`coffees`中的行和`suppliers`中的行。它保存`coffees`中的列加上`suppliers`中的列，其中`COFFEES.SUP_ID`列中的值与`SUPPLIERS.SUP_ID`中的值匹配。以下代码打印出 Acme，Inc。提供的咖啡名称，其中`String` `supplierName`等于`Acme, Inc.`请注意，这是可能的，因为`SUP_NAME`列来自`suppliers`，来自`coffees`的`COF_NAME`现在都包含在`JoinRowSet`对象`jrs`中。

```
System.out.println("Coffees bought from " + supplierName + ": ");

while (jrs.next()) {
    if (jrs.getString("SUP_NAME").equals(supplierName)) {
        String coffeeName = jrs.getString(1);
        System.out.println("     " + coffeeName);
    }
}

```

这将产生类似于以下的输出：

```
Coffees bought from Acme, Inc.:
     Colombian
     Colombian_Decaf

```

`JoinRowSet`接口提供用于设置将要形成的`JOIN`类型的常量，但是目前唯一实现的类型是`JoinRowSet.INNER_JOIN`。