这些Java教程是针对JDK 8编写的。本页面描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及后续版本中更新的语言功能的概述。
请参阅JDK发布说明,了解所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息。
JoinRowSet
实现允许您在RowSet
对象未连接到数据源时创建SQLJOIN
。这很重要,因为它节省了创建一个或多个连接的开销。
以下主题将被讨论:
JoinRowSet
接口是CachedRowSet
接口的子接口,因此继承了CachedRowSet
对象的功能。这意味着JoinRowSet
对象是一个断开连接的RowSet
对象,可以在不始终连接到数据源的情况下操作。
JoinRowSet
对象用作SQLJOIN
的容器。以下来自JoinSample.java
的示例显示了如何创建JoinRowSet
对象:
RowSetFactory factory = RowSetProvider.newFactory(); try (CachedRowSet coffees = factory.createCachedRowSet(); CachedRowSet suppliers = factory.createCachedRowSet(); JoinRowSet jrs = factory.createJoinRowSet()) { coffees.setCommand("SELECT * FROM COFFEES"); // 为CachedRowSet coffees设置连接参数 coffees.execute(); suppliers.setCommand("SELECT * FROM SUPPLIERS"); // 为CachedRowSet suppliers设置连接参数 suppliers.execute(); jrs.addRowSet(coffees, "SUP_ID"); jrs.addRowSet(suppliers, "SUP_ID"); // ...
变量jrs
在添加RowSet
对象之前不包含任何内容。
任何RowSet
对象都可以添加到JoinRowSet
对象中,只要它可以成为SQLJOIN
的一部分。一个总是连接到其数据源的JdbcRowSet
对象可以被添加,但通常它通过直接与数据源操作而不是通过添加到JoinRowSet
对象来成为JOIN
的一部分。提供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
的代码片段创建了两个 CachedRowSet
对象:coffees
从表 COFFEES
中获取数据,suppliers
从表 SUPPLIERS
中获取数据。为了执行命令并获取数据,coffees
和 suppliers
对象必须连接到数据库,但在完成后,它们不必再次连接以形成一个 JOIN
。
try (CachedRowSet coffees = factory.createCachedRowSet(); CachedRowSet suppliers = factory.createCachedRowSet(); JoinRowSet jrs = factory.createJoinRowSet()) { coffees.setCommand("SELECT * FROM COFFEES"); coffees.setUsername(settings.userName); coffees.setPassword(settings.password); coffees.setUrl(settings.urlString); coffees.execute(); 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 的咖啡是哥伦比亚和哥伦比亚脱咖啡因咖啡。两个表的信息可以通过它们共有的列 SUP_ID
进行连接。在 JDBC RowSet
技术中,基于 JOIN
的列 SUP_ID
被称为 匹配列。
添加到 JoinRowSet
对象的每个 RowSet
对象必须有一个匹配列,即基于该列进行 JOIN
。有两种方法可以为 RowSet
对象设置匹配列。第一种方法是将匹配列传递给 JoinRowSet
的 addRowSet
方法,如下面的代码所示:
jrs.addRowSet(coffees, "SUP_ID");
这行代码将coffees
CachedRowSet
添加到jrs
对象中,并将coffees
的SUP_ID
列设置为匹配列。
此时,jrs
中只有coffees
。下一个添加到jrs
中的RowSet
对象必须能够与coffees
进行JOIN
,对于suppliers
来说是成立的,因为两个表都有SUP_ID列。以下行代码将suppliers
添加到jrs
中,并将SUP_ID列设置为匹配列。
jrs.addRowSet(suppliers, "SUP_ID");
现在,jrs
包含了coffees
和suppliers
之间的JOIN
,从中所有者可以获取由Acme, Inc.供应的咖啡的名称。因为代码没有设置JOIN
的类型,所以jrs
持有内连接(inner JOIN),这是默认的。换句话说,jrs
中的一行将coffees
中的一行和suppliers
中的一行组合在一起。它包含coffees
中的列以及与COFFEES.SUP_ID
列的值匹配SUPPLIERS.SUP_ID
的suppliers
中的列。以下代码打印出由Acme, Inc.供应的咖啡的名称,其中String
类型的supplierName
等于Acme, Inc.
请注意,这是可能的,因为suppliers
的SUP_NAME
列和coffees
的COF_NAME
列现在都包含在JoinRowSet
对象jrs
中。
System.out.println("从" + supplierName + "购买的咖啡:"); while (jrs.next()) { if (jrs.getString("SUP_NAME").equals(supplierName)) { String coffeeName = jrs.getString(1); System.out.println(" " + coffeeName); } }
这将产生类似以下的输出:
从Acme, Inc.购买的咖啡: Colombian Colombian_Decaf
JoinRowSet
接口提供了用于设置将要形成的JOIN
类型的常量,但目前只实现了JoinRowSet.INNER_JOIN
。