Java 中文官方教程 2022 版(三十六)(1)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Java 中文官方教程 2022 版(三十六)

使用高级数据类型

原文:docs.oracle.com/javase/tutorial/jdbc/basics/sqltypes.html

本节介绍的高级数据类型使关系数据库在表列值方面更加灵活。例如,列可以用于存储 BLOB(二进制大对象)值,可以以原始字节形式存储非常大量的数据。列也可以是 CLOB(字符大对象)类型,能够以字符格式存储非常大量的数据。

ANSI/ISO SQL 标准的最新版本通常被称为 SQL:2003。该标准指定了以下数据类型:

  • SQL92 内置类型,包括熟悉的 SQL 列类型,如 CHARFLOATDATE
  • SQL99 内置类型,包括 SQL99 添加的类型:
  • BOOLEAN: 布尔(真或假)值
  • BLOB: 二进制大对象
  • CLOB: 字符大对象
  • SQL:2003 添加的新内置类型:
  • XML: XML 对象
  • 用户定义类型:
  • 结构化类型: 用户定义类型; 例如:
CREATE TYPE PLANE_POINT
AS (X FLOAT, Y FLOAT) NOT FINAL
  • DISTINCT 类型: 基于内置类型的用户定义类型; 例如:
CREATE TYPE MONEY
AS NUMERIC(10,2) FINAL
  • 构造类型: 基于给定基本类型的新类型:
  • REF(*structured-type*): 持久地指示驻留在数据库中的结构化类型实例的指针
  • *base-type* ARRAY[*n*]: n 个基本类型元素的数组
  • 定位器: 逻辑指针,指向驻留在数据库服务器上的数据。定位器存在于客户端计算机上,是对服务器上数据的瞬时、逻辑指针。定位器通常指向无法在客户端上具体化的数据,如图像或音频。(具体化视图是事先存储或“具体化”为模式对象的查询结果。) 在 SQL 级别定义了操作符,用于检索由定位器指示的数据的随机访问部分:
  • LOCATOR(*structured-type*): 服务器中结构化实例的定位器
  • LOCATOR(*array*): 服务器中数组的定位器
  • LOCATOR(*blob*): 服务器中二进制大对象的定位器
  • LOCATOR(*clob*): 服务器中字符大对象的定位器
  • Datalink: 用于管理数据源外部数据的类型。Datalink 值是 SQL MED(管理外部数据)的一部分,是 SQL ANSI/ISO 标准规范的一部分。

映射高级数据类型

JDBC API 为 SQL:2003 标准指定的高级数据类型提供了默认映射。以下列表列出了数据类型及其映射到的接口或类:

  • BLOB: Blob 接口
  • CLOB: Clob 接口
  • NCLOB: NClob 接口
  • ARRAY: Array 接口
  • XML: SQLXML 接口
  • 结构化类型: Struct 接口
  • REF(structured type): Ref 接口
  • ROWID: RowId 接口
  • DISTINCT: 基础类型映射的类型。例如,基于 SQL NUMERIC 类型的 DISTINCT 值映射到 java.math.BigDecimal 类型,因为在 Java 编程语言中,NUMERIC 映射到 BigDecimal
  • DATALINKjava.net.URL 对象

使用高级数据类型

检索、存储和更新高级数据类型的方式与处理其他数据类型的方式相同。您可以使用 ResultSet.get*DataType*CallableStatement.get*DataType* 方法来检索它们,PreparedStatement.set*DataType* 方法来存储它们,以及 ResultSet.update*DataType* 方法来更新它们。(变量 *DataType* 是映射到高级数据类型的 Java 接口或类的名称。)大概有 90% 的高级数据类型操作涉及使用 get*DataType*set*DataType*update*DataType* 方法。以下表格显示了要使用哪些方法:

高级数据类型 get*DataType* 方法 set*DataType* 方法 update*DataType* 方法
BLOB getBlob setBlob updateBlob
CLOB getClob setClob updateClob
NCLOB getNClob setNClob updateNClob
ARRAY getArray setArray updateArray
XML getSQLXML setSQLXML updateSQLXML
Structured type getObject setObject updateObject
REF(structured type) getRef setRef updateRef
ROWID getRowId setRowId updateRowId
DISTINCT getBigDecimal setBigDecimal updateBigDecimal
DATALINK getURL setURL updateURL

注意DISTINCT 数据类型与其他高级 SQL 数据类型的行为不同。作为一个基于已存在内置类型的用户定义类型,它在 Java 编程语言中没有接口。因此,您需要使用与 DISTINCT 数据类型基础的 Java 类型对应的方法。请参阅使用 DISTINCT 数据类型获取更多信息。

例如,以下代码片段检索了一个 SQL ARRAY 值。在此示例中,假设表 STUDENTS 中的列 SCORES 包含 ARRAY 类型的值。变量 *stmt* 是一个 Statement 对象。

ResultSet rs = stmt.executeQuery(
    "SELECT SCORES FROM STUDENTS " +
    "WHERE ID = 002238");
rs.next();
Array scores = rs.getArray("SCORES");

变量 *scores* 是指向存储在表 STUDENTS 中学生 002238 行中的 SQL ARRAY 对象的逻辑指针。

如果要将值存储在数据库中,可以使用相应的 set 方法。例如,以下代码片段中,*rs* 是一个 ResultSet 对象,存储了一个 Clob 对象:

Clob notes = rs.getClob("NOTES");
PreparedStatement pstmt =
    con.prepareStatement(
        "UPDATE MARKETS SET COMMENTS = ? " +
        "WHERE SALES < 1000000");
pstmt.setClob(1, notes);
pstmt.executeUpdate();

此代码将 *notes* 设置为发送到数据库的更新语句的第一个参数。由 *notes* 指定的 Clob 值将存储在表 MARKETSCOMMENTS 列中,在该列中的值小于一百万的每一行中。

使用大对象

原文:docs.oracle.com/javase/tutorial/jdbc/basics/blob.html

BlobClobNClob Java 对象的一个重要特性是,您可以在不将所有数据从数据库服务器传输到客户端计算机的情况下对它们进行操作。一些实现使用定位器(逻辑指针)来表示这些类型的实例,指向实例所代表的数据库中的对象。由于BLOBCLOBNCLOB SQL 对象可能非常大,使用定位器可以显著提高性能。但是,其他实现会在客户端计算机上完全实现大对象。

如果要将BLOBCLOBNCLOB SQL 值的数据传输到客户端计算机,请使用为此目的提供的BlobClobNClob Java 接口中的方法。这些大对象类型对象将它们所代表的对象的数据实现为流。

以下主题涵盖:

  • 向数据库添加大对象类型对象
  • 检索 CLOB 值
  • 添加和检索 BLOB 对象
  • 释放大对象占用的资源

向数据库添加大对象类型对象

以下摘录自ClobSample.addRowToCoffeeDescriptionsCOFFEE_DESCRIPTIONS表中添加CLOB SQL 值。Clob Java 对象myClob包含由fileName指定的文件的内容。

public void addRowToCoffeeDescriptions(String coffeeName,
                                         String fileName) throws SQLException {
    String sql = "INSERT INTO COFFEE_DESCRIPTIONS VALUES(?,?)";
    Clob myClob = this.con.createClob();
    try (PreparedStatement pstmt = this.con.prepareStatement(sql);
      Writer clobWriter = myClob.setCharacterStream(1);){
      String str = this.readFile(fileName, clobWriter);
      System.out.println("Wrote the following: " + clobWriter.toString());
      if (this.settings.dbms.equals("mysql")) {
        System.out.println("MySQL, setting String in Clob object with setString method");
        myClob.setString(1, str);
      }
      System.out.println("Length of Clob: " + myClob.length());
      pstmt.setString(1, coffeeName);
      pstmt.setClob(2, myClob);
      pstmt.executeUpdate();
    } catch (SQLException sqlex) {
      JDBCTutorialUtilities.printSQLException(sqlex);
    } catch (Exception ex) {
      System.out.println("Unexpected exception: " + ex.toString());
    }
  }

下一行创建一个Clob Java 对象:

Clob myClob = this.con.createClob();

下一行检索一个流(在本例中为名为clobWriterWriter对象),用于将一系列字符写入Clob Java 对象myClobClobSample.readFile方法写入这些字符流;流来自由String fileName指定的文件。方法参数1表示Writer对象将从Clob值的开头开始写入字符流:

Writer clobWriter = myClob.setCharacterStream(1);

ClobSample.readFile方法逐行读取由文件fileName指定的文件,并将其写入由writerArg指定的Writer对象:

private String readFile(String fileName, Writer writerArg) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
      String nextLine = "";
      StringBuffer sb = new StringBuffer();
      while ((nextLine = br.readLine()) != null) {
        System.out.println("Writing: " + nextLine);
        writerArg.write(nextLine);
        sb.append(nextLine);
      }
      // Convert the content into to a string
      String clobData = sb.toString();
    // Return the data.
      return clobData;
  }
  }

以下摘录创建一个PreparedStatement对象pstmt,将Clob Java 对象myClob插入COFFEE_DESCRIPTIONS中:

String sql = "INSERT INTO COFFEE_DESCRIPTIONS VALUES(?,?)";
    Clob myClob = this.con.createClob();
    try (PreparedStatement pstmt = this.con.prepareStatement(sql);
      // ...
      ) {
      // ...
      pstmt.setString(1, coffeeName);
      pstmt.setClob(2, myClob);
      pstmt.executeUpdate();
      // ...

检索 CLOB 值

方法ClobSample.retrieveExcerptCOFFEE_DESCRIPTIONS表中COF_NAME列的值等于coffeeName参数指定的String值的行中检索存储在COF_DESC列中的CLOB SQL 值:

public String retrieveExcerpt(String coffeeName,
                                int numChar) throws SQLException {
    String description = null;
    Clob myClob = null;
    String sql = "select COF_DESC from COFFEE_DESCRIPTIONS where COF_NAME = ?";
    try (PreparedStatement pstmt = this.con.prepareStatement(sql)) {
      pstmt.setString(1, coffeeName);
      ResultSet rs = pstmt.executeQuery();
      if (rs.next()) {
        myClob = rs.getClob(1);
        System.out.println("Length of retrieved Clob: " + myClob.length());
      }
      description = myClob.getSubString(1, numChar);
    } catch (SQLException sqlex) {
      JDBCTutorialUtilities.printSQLException(sqlex);
    } catch (Exception ex) {
      System.out.println("Unexpected exception: " + ex.toString());
    }
    return description;
  }

下一行从ResultSet对象rs中检索Clob Java 值:

myClob = rs.getClob(1);

以下行从myClob对象中检索子字符串。子字符串从myClob值的第一个字符开始,最多有numChar指定的连续字符数,其中numChar是一个整数。

description = myClob.getSubString(1, numChar);

添加和检索 BLOB 对象

添加和检索BLOB SQL 对象类似于添加和检索CLOB SQL 对象。使用Blob.setBinaryStream方法检索一个OutputStream对象,以写入调用该方法的Blob Java 对象(表示BLOB SQL 值)的BLOB SQL 值。

释放大对象所持有的资源

BlobClobNClob Java 对象在它们被创建的事务持续时间内至少保持有效。这可能导致应用程序在长时间运行的事务中耗尽资源。应用程序可以通过调用它们的free方法来释放BlobClobNClob资源。

在以下摘录中,调用方法Clob.free来释放先前创建的Clob对象所持有的资源:

Clob aClob = con.createClob();
int numWritten = aClob.setString(1, val);
aClob.free();

使用 SQLXML 对象

原文:docs.oracle.com/javase/tutorial/jdbc/basics/sqlxml.html

Connection 接口支持使用 createSQLXML 方法创建 SQLXML 对象。创建的对象不包含任何数据。可以通过在 SQLXML 接口上调用 setStringsetBinaryStreamsetCharacterStreamsetResult 方法向对象添加数据。

下面涵盖了以下主题:

  • 创建 SQLXML 对象
  • 在 ResultSet 中检索 SQLXML 值
  • 访问 SQLXML 对象数据
  • 存储 SQLXML 对象
  • 初始化 SQLXML 对象
  • 释放 SQLXML 资源
  • 示例代码

创建 SQLXML 对象

在以下摘录中,使用 Connection.createSQLXML 方法创建一个空的 SQLXML 对象。使用 SQLXML.setString 方法将数据写入创建的 SQLXML 对象。

Connection con = DriverManager.getConnection(url, props);
SQLXML xmlVal = con.createSQLXML();
xmlVal.setString(val);

在 ResultSet 中检索 SQLXML 值

SQLXML 数据类型类似于更基本的内置类型。可以通过在 ResultSetCallableStatement 接口中调用 getSQLXML 方法来检索 SQLXML 值。

例如,以下摘录从 ResultSet rs 的第一列检索一个 SQLXML 值:

SQLXML xmlVar = rs.getSQLXML(1);

SQLXML 对象在创建它们的事务持续时间内至少保持有效,除非调用它们的 free 方法。

访问 SQLXML 对象数据

SQLXML 接口提供了 getStringgetBinaryStreamgetCharacterStreamgetSource 方法来访问其内部内容。以下摘录使用 getString 方法检索 SQLXML 对象的内容:

SQLXML xmlVal= rs.getSQLXML(1);
String val = xmlVal.getString();

可以使用 getBinaryStreamgetCharacterStream 方法获取可直接传递给 XML 解析器的 InputStreamReader 对象。以下摘录从 SQLXML 对象获取一个 InputStream 对象,然后使用 DOM(文档对象模型)解析器处理流:

SQLXML sqlxml = rs.getSQLXML(column);
InputStream binaryStream = sqlxml.getBinaryStream();
DocumentBuilder parser = 
    DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document result = parser.parse(binaryStream);

getSource 方法返回一个 javax.xml.transform.Source 对象。源用作 XML 解析器和 XSLT 转换器的输入。

以下摘录使用通过调用 getSource 方法返回的 SAXSource 对象从 SQLXML 对象中检索和解析数据:

SQLXML xmlVal= rs.getSQLXML(1);
SAXSource saxSource = sqlxml.getSource(SAXSource.class);
XMLReader xmlReader = saxSource.getXMLReader();
xmlReader.setContentHandler(myHandler);
xmlReader.parse(saxSource.getInputSource());

存储 SQLXML 对象

SQLXML 对象可以像其他数据类型一样作为输入参数传递给 PreparedStatement 对象。setSQLXML 方法使用 SQLXML 对象设置指定的 PreparedStatement 参数。

在以下摘录中,authorData 是一个 java.sql.SQLXML 接口的实例,其数据先前已初始化。

PreparedStatement pstmt = conn.prepareStatement("INSERT INTO bio " +
                              "(xmlData, authId) VALUES (?, ?)");
pstmt.setSQLXML(1, authorData);
pstmt.setInt(2, authorId);

updateSQLXML 方法可用于更新可更新结果集中的列值。

如果在调用setSQLXMLupdateSQLXML之前未关闭SQLXML对象的java.xml.transform.ResultWriterOutputStream对象,将抛出SQLException

初始化 SQLXML 对象

SQLXML接口提供了setStringsetBinaryStreamsetCharacterStreamsetResult方法来初始化通过调用Connection.createSQLXML方法创建的SQLXML对象的内容。

以下摘录使用setResult方法返回一个SAXResult对象以填充一个新创建的SQLXML对象:

SQLXML sqlxml = con.createSQLXML();
SAXResult saxResult = sqlxml.setResult(SAXResult.class);
ContentHandler contentHandler = saxResult.getXMLReader().getContentHandler();
contentHandler.startDocument();
// set the XML elements and
// attributes into the result
contentHandler.endDocument();

以下摘录使用setCharacterStream方法获取一个java.io.Writer对象以初始化一个SQLXML对象:

SQLXML sqlxml = con.createSQLXML();
Writer out= sqlxml.setCharacterStream();
BufferedReader in = new BufferedReader(new FileReader("xml/foo.xml"));
String line = null;
while((line = in.readLine() != null) {
    out.write(line);
}

同样地,SQLXMLsetString方法可用于初始化一个SQLXML对象。

如果尝试在先前初始化过的SQLXML对象上调用setStringsetBinaryStreamsetCharacterStreamsetResult方法,将抛出SQLException。如果对同一SQLXML对象多次调用setBinaryStreamsetCharacterStreamsetResult方法,则会抛出SQLException,并且先前返回的javax.xml.transform.ResultWriterOutputStream对象不受影响。

释放 SQLXML 资源

SQLXML对象在创建它们的事务持续时间内至少保持有效。这可能导致应用程序在长时间运行的事务中耗尽资源。应用程序可以通过调用它们的free方法释放SQLXML资源。

在以下摘录中,调用method SQLXML.free来释放先前创建的SQLXML对象所持有的资源。

SQLXML xmlVar = con.createSQLXML();
xmlVar.setString(val);
xmlVar.free();

示例代码

MySQL 和 Java DB 及其各自的 JDBC 驱动程序并不完全支持本节中描述的SQLXML JDBC 数据类型。然而,示例RSSFeedsTable.java演示了如何处理 MySQL 和 Java DB 中的 XML 数据。

The Coffee Break 的所有者关注来自各种网站的几个 RSS 订阅源,涵盖餐厅和饮料行业新闻。RSS(真正简单的聚合或富站点摘要)订阅源是一个包含一系列文章和相关元数据的 XML 文档,如每篇文章的发布日期和作者。所有者希望将这些 RSS 订阅源存储到数据库表中,包括 The Coffee Break 博客的 RSS 订阅源。

文件rss-the-coffee-break-blog.xml是 The Coffee Break 博客的一个示例 RSS 订阅源。文件rss-coffee-industry-news.xml是(虚构的)Coffee Industry News 的一个示例 RSS 订阅源。

在 MySQL 中处理 XML 数据

示例RSSFeedsTable将 RSS 订阅源存储在名为RSS_FEEDS的表中,该表是使用以下命令创建的:

create table RSS_FEEDS
    (RSS_NAME varchar(32) NOT NULL,
    RSS_FEED_XML longtext NOT NULL,
    PRIMARY KEY (RSS_NAME));

MySQL 不支持 XML 数据类型。相反,此示例将 XML 数据存储在类型为 LONGTEXT 的列中,这是一种 CLOB SQL 数据类型。MySQL 有四种 CLOB 数据类型;LONGTEXT 数据类型在这四种类型中包含的字符数量最多。

方法 RSSFeedsTable.addRSSFeed 将一个 RSS 订阅添加到 RSS_FEEDS 表中。此方法的第一条语句将 RSS 订阅(在此示例中表示为 XML 文件)转换为类型为 org.w3c.dom.Document 的对象,该对象表示 DOM(文档对象模型)文档。这个类以及包含在 javax.xml 包中的类和接口包含了使您能够操作 XML 数据内容的方法。例如,以下语句使用 XPath 表达式从 Document 对象中检索 RSS 订阅的标题:

Node titleElement =
    (Node)xPath.evaluate("/rss/channel/title[1]",
        doc, XPathConstants.NODE);

XPath 表达式 /rss/channel/title[1] 检索第一个 <title> 元素的内容。对于文件 rss-the-coffee-break-blog.xml,这是字符串 The Coffee Break Blog

以下语句将 RSS 订阅添加到表 RSS_FEEDS 中:

// For databases that support the SQLXML
// data type, this creates a
// SQLXML object from
// org.w3c.dom.Document.
System.out.println("Adding XML file " + fileName);
String insertRowQuery =
    "insert into RSS_FEEDS " +
    "(RSS_NAME, RSS_FEED_XML) values " +
    "(?, ?)";
insertRow = con.prepareStatement(insertRowQuery);
insertRow.setString(1, titleString);
System.out.println("Creating SQLXML object with MySQL");
rssData = con.createSQLXML();
System.out.println("Creating DOMResult object");
DOMResult dom = (DOMResult)rssData.setResult(DOMResult.class);
dom.setNode(doc);
insertRow.setSQLXML(2, rssData);
System.out.println("Running executeUpdate()");
insertRow.executeUpdate();

方法 RSSFeedsTable.viewTable 检索 RSS_FEEDS 的内容。对于每一行,该方法创建一个名为 doc 的类型为 org.w3c.dom.Document 的对象,用于存储列 RSS_FEED_XML 中的 XML 内容。该方法检索 XML 内容并将其存储在名为 rssFeedXML 的类型为 SQLXML 的对象中。rssFeedXML 的内容被解析并存储在 doc 对象中。

在 Java DB 中处理 XML 数据

注意:有关在 Java DB 中处理 XML 数据的更多信息,请参阅 Java DB 开发人员指南 中的 “XML 数据类型和运算符” 部分。

示例 RSSFeedsTable 将 RSS 订阅存储在表 RSS_FEEDS 中,该表是使用以下命令创建的:

create table RSS_FEEDS
    (RSS_NAME varchar(32) NOT NULL,
    RSS_FEED_XML xml NOT NULL,
    PRIMARY KEY (RSS_NAME));

Java DB 支持 XML 数据类型,但不支持 SQLXML JDBC 数据类型。因此,您必须将任何 XML 数据转换为字符格式,然后使用 Java DB 运算符 XMLPARSE 将其转换为 XML 数据类型。

方法 RSSFeedsTable.addRSSFeed 将一个 RSS 订阅添加到 RSS_FEEDS 表中。此方法的第一条语句将 RSS 订阅(在此示例中表示为 XML 文件)转换为类型为 org.w3c.dom.Document 的对象。这在 在 MySQL 中处理 XML 数据 部分中有描述。

RSSFeedsTable.addRSSFeed 方法使用方法 JDBCTutorialUtilities.convertDocumentToString 将 RSS 订阅转换为 String 对象。

Java DB 有一个名为XMLPARSE的操作符,将字符字符串表示解析为 Java DB XML 值,以下摘录演示了这一点:

String insertRowQuery =
    "insert into RSS_FEEDS " +
    "(RSS_NAME, RSS_FEED_XML) values " +
    "(?, xmlparse(document cast " +
    "(? as clob) preserve whitespace))";

XMLPARSE操作符要求您将 XML 文档的字符表示转换为 Java DB 识别的字符串数据类型。在本例中,它将其转换为CLOB数据类型。有关 Apache Xalan 和 Java DB 要求的更多信息,请参阅入门指南和 Java DB 文档。

方法RSSFeedsTable.viewTable检索RSS_FEEDS的内容。因为 Java DB 不支持 JDBC 数据类型SQLXML,您必须将 XML 内容检索为字符串。Java DB 有一个名为XMLSERIALIZE的操作符,将 XML 类型转换为字符类型:

String query =
    "select RSS_NAME, " +
    "xmlserialize " +
    "(RSS_FEED_XML as clob) " +
    "from RSS_FEEDS";

XMLPARSE操作符一样,XMLSERIALIZE操作符要求在您的 Java 类路径中列出 Apache Xalan。

使用数组对象

原文:docs.oracle.com/javase/tutorial/jdbc/basics/array.html

注意:MySQL 和 Java DB 目前不支持ARRAY SQL 数据类型。因此,没有可用的 JDBC 教程示例来演示Array JDBC 数据类型。

下面的主题包括:

  • 创建数组对象
  • 检索和访问 ResultSet 中的数组值
  • 存储和更新数组对象
  • 释放数组资源

创建数组对象

使用方法Connection.createArrayOf创建Array对象。

例如,假设您的数据库包含一个名为REGIONS的表,该表已经通过以下 SQL 语句创建并填充;请注意,这些语句的语法将根据您的数据库而变化:

create table REGIONS
    (REGION_NAME varchar(32) NOT NULL,
    ZIPS varchar32 ARRAY[10] NOT NULL,
    PRIMARY KEY (REGION_NAME));
insert into REGIONS values(
    'Northwest',
    '{"93101", "97201", "99210"}');
insert into REGIONS values(
    'Southwest',
    '{"94105", "90049", "92027"}');
Connection con = DriverManager.getConnection(url, props);
String [] northEastRegion = { "10022", "02110", "07399" };
Array anArray = con.createArrayOf("VARCHAR", northEastRegion);

Oracle 数据库 JDBC 驱动程序使用oracle.sql.ARRAY类实现java.sql.Array接口。

在 ResultSet 中检索和访问数组值

与 JDBC 4.0 大对象接口(BlobClobNClob)一样,您可以操作Array对象,而无需将所有数据从数据库服务器传输到客户端计算机。Array对象将其表示的 SQL ARRAY作为结果集或 Java 数组实现。

以下摘录检索列ZIPS中的 SQL ARRAY值,并将其赋给java.sql.Array对象z对象。摘录检索z的内容并将其存储在zips中,zips是一个包含String类型对象的 Java 数组。摘录遍历zips数组并检查每个邮政(邮编)代码是否有效。此代码假定类ZipCode已经在先前定义,并且具有方法isValid,如果给定的邮政编码与有效邮政编码主列表中的一个匹配,则返回true

ResultSet rs = stmt.executeQuery(
    "SELECT region_name, zips FROM REGIONS");
while (rs.next()) {
    Array z = rs.getArray("ZIPS");
    String[] zips = (String[])z.getArray();
    for (int i = 0; i < zips.length; i++) {
        if (!ZipCode.isValid(zips[i])) {
            // ...
            // Code to display warning
        }
    }
}

在以下语句中,ResultSet方法getArray将当前行的列ZIPS中存储的值作为java.sql.Array对象z返回:

Array z = rs.getArray("ZIPS");

变量*z*包含一个定位器,这是指向服务器上 SQL ARRAY的逻辑指针;它不包含ARRAY本身的元素。作为逻辑指针,*z*可用于在服务器上操作数组。

在以下行中,getArrayArray.getArray方法,而不是前一行中使用的ResultSet.getArray方法。因为Array.getArray方法在 Java 编程语言中返回一个Object,并且每个邮政编码都是一个String对象,所以在分配给变量zips之前,结果被转换为String对象的数组。

String[] zips = (String[])z.getArray();

Array.getArray方法将 SQL ARRAY元素在客户端作为String对象数组实现。因为实际上变量*zips*包含数组的元素,所以可以在for循环中遍历zips,查找无效的邮政编码。

Java 中文官方教程 2022 版(三十六)(2)https://developer.aliyun.com/article/1488070

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
7月前
|
JavaScript NoSQL Java
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
363 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
|
3月前
|
Oracle Java 关系型数据库
java 编程基础入门级超级完整版教程详解
这份文档是针对Java编程入门学习者的超级完整版教程,涵盖了从环境搭建到实际项目应用的全方位内容。首先介绍了Java的基本概念与开发环境配置方法,随后深入讲解了基础语法、控制流程、面向对象编程的核心思想,并配以具体代码示例。接着探讨了常用类库与API的应用,如字符串操作、集合框架及文件处理等。最后通过一个学生成绩管理系统的实例,帮助读者将理论知识应用于实践。此外,还提供了进阶学习建议,引导学员逐步掌握更复杂的Java技术。适合初学者系统性学习Java编程。资源地址:[点击访问](https://pan.quark.cn/s/14fcf913bae6)。
306 2
|
8月前
|
消息中间件 Java 数据库
自研Java框架 Sunrays-Framework使用教程「博客之星」
### Sunrays-Framework:助力高效开发的Java微服务框架 **Sunrays-Framework** 是一款基于 Spring Boot 构建的高效微服务开发框架,深度融合了 Spring Cloud 生态中的核心技术组件。它旨在简化数据访问、缓存管理、消息队列、文件存储等常见开发任务,帮助开发者快速构建高质量的企业级应用。 #### 核心功能 - **MyBatis-Plus**:简化数据访问层开发,提供强大的 CRUD 操作和分页功能。 - **Redis**:实现高性能缓存和分布式锁,提升系统响应速度。 - **RabbitMQ**:可靠的消息队列支持,适用于异步
自研Java框架 Sunrays-Framework使用教程「博客之星」
|
9月前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
8415 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
8月前
|
Java 数据库连接 数据处理
探究Java异常处理【保姆级教程】
Java 异常处理是确保程序稳健运行的关键机制。它通过捕获和处理运行时错误,避免程序崩溃。Java 的异常体系以 `Throwable` 为基础,分为 `Error` 和 `Exception`。前者表示严重错误,后者可细分为受检和非受检异常。常见的异常处理方式包括 `try-catch-finally`、`throws` 和 `throw` 关键字。此外,还可以自定义异常类以满足特定需求。最佳实践包括捕获具体异常、合理使用 `finally` 块和谨慎抛出异常。掌握这些技巧能显著提升程序的健壮性和可靠性。
133 4
|
8月前
|
存储 移动开发 算法
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
145 1
|
9月前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
556 26
|
8月前
|
前端开发 Java 开发工具
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
415 0
|
9月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
9月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)

热门文章

最新文章