使用高级数据类型
原文:
docs.oracle.com/javase/tutorial/jdbc/basics/sqltypes.html
本节介绍的高级数据类型使关系数据库在表列值方面更加灵活。例如,列可以用于存储 BLOB
(二进制大对象)值,可以以原始字节形式存储非常大量的数据。列也可以是 CLOB
(字符大对象)类型,能够以字符格式存储非常大量的数据。
ANSI/ISO SQL 标准的最新版本通常被称为 SQL:2003。该标准指定了以下数据类型:
- SQL92 内置类型,包括熟悉的 SQL 列类型,如
CHAR
、FLOAT
和DATE
- 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
: 基础类型映射的类型。例如,基于 SQLNUMERIC
类型的DISTINCT
值映射到java.math.BigDecimal
类型,因为在 Java 编程语言中,NUMERIC
映射到BigDecimal
。DATALINK
:java.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
值将存储在表 MARKETS
的 COMMENTS
列中,在该列中的值小于一百万的每一行中。
使用大对象
Blob
、Clob
和NClob
Java 对象的一个重要特性是,您可以在不将所有数据从数据库服务器传输到客户端计算机的情况下对它们进行操作。一些实现使用定位器(逻辑指针)来表示这些类型的实例,指向实例所代表的数据库中的对象。由于BLOB
、CLOB
或NCLOB
SQL 对象可能非常大,使用定位器可以显著提高性能。但是,其他实现会在客户端计算机上完全实现大对象。
如果要将BLOB
、CLOB
或NCLOB
SQL 值的数据传输到客户端计算机,请使用为此目的提供的Blob
、Clob
和NClob
Java 接口中的方法。这些大对象类型对象将它们所代表的对象的数据实现为流。
以下主题涵盖:
- 向数据库添加大对象类型对象
- 检索 CLOB 值
- 添加和检索 BLOB 对象
- 释放大对象占用的资源
向数据库添加大对象类型对象
以下摘录自ClobSample.addRowToCoffeeDescriptions
向COFFEE_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();
下一行检索一个流(在本例中为名为clobWriter
的Writer
对象),用于将一系列字符写入Clob
Java 对象myClob
。ClobSample.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.retrieveExcerpt
从COFFEE_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 值。
释放大对象所持有的资源
Blob
、Clob
和NClob
Java 对象在它们被创建的事务持续时间内至少保持有效。这可能导致应用程序在长时间运行的事务中耗尽资源。应用程序可以通过调用它们的free
方法来释放Blob
、Clob
和NClob
资源。
在以下摘录中,调用方法Clob.free
来释放先前创建的Clob
对象所持有的资源:
Clob aClob = con.createClob(); int numWritten = aClob.setString(1, val); aClob.free();
使用 SQLXML 对象
Connection
接口支持使用 createSQLXML
方法创建 SQLXML
对象。创建的对象不包含任何数据。可以通过在 SQLXML
接口上调用 setString
、setBinaryStream
、setCharacterStream
或 setResult
方法向对象添加数据。
下面涵盖了以下主题:
- 创建 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
数据类型类似于更基本的内置类型。可以通过在 ResultSet
或 CallableStatement
接口中调用 getSQLXML
方法来检索 SQLXML
值。
例如,以下摘录从 ResultSet
rs 的第一列检索一个 SQLXML
值:
SQLXML xmlVar = rs.getSQLXML(1);
SQLXML
对象在创建它们的事务持续时间内至少保持有效,除非调用它们的 free
方法。
访问 SQLXML 对象数据
SQLXML
接口提供了 getString
、getBinaryStream
、getCharacterStream
和 getSource
方法来访问其内部内容。以下摘录使用 getString
方法检索 SQLXML
对象的内容:
SQLXML xmlVal= rs.getSQLXML(1); String val = xmlVal.getString();
可以使用 getBinaryStream
或 getCharacterStream
方法获取可直接传递给 XML 解析器的 InputStream
或 Reader
对象。以下摘录从 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
方法可用于更新可更新结果集中的列值。
如果在调用setSQLXML
或updateSQLXML
之前未关闭SQLXML
对象的java.xml.transform.Result
、Writer
或OutputStream
对象,将抛出SQLException
。
初始化 SQLXML 对象
SQLXML
接口提供了setString
、setBinaryStream
、setCharacterStream
或setResult
方法来初始化通过调用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); }
同样地,SQLXML
的setString
方法可用于初始化一个SQLXML
对象。
如果尝试在先前初始化过的SQLXML
对象上调用setString
、setBinaryStream
、setCharacterStream
和setResult
方法,将抛出SQLException
。如果对同一SQLXML
对象多次调用setBinaryStream
、setCharacterStream
和setResult
方法,则会抛出SQLException
,并且先前返回的javax.xml.transform.Result
、Writer
或OutputStream
对象不受影响。
释放 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。
使用数组对象
注意: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 大对象接口(Blob
,Clob
,NClob
)一样,您可以操作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*
可用于在服务器上操作数组。
在以下行中,getArray
是Array.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