# 使用高级数据类型

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

本节中介绍的高级数据类型为关系数据库提供了更多的灵活性，可用作表列的值。例如，列可用于存储`BLOB`（二进制大对象）值，这些值可以将非常大量的数据存储为原始字节。列也可以是`CLOB`类型（字符大对象），它能够以字符格式存储大量数据。

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

*   SQL92 内置类型，包括熟悉的 SQL 列类型，如`CHAR`，`FLOAT`和`DATE`

*   SQL99 内置类型，由 SQL99 添加的类型组成：

    *   `BOOLEAN`：布尔值（true 或 false）

    *   `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（_ 结构化类型 _）`：持久表示驻留在数据库中的结构化类型的实例的指针

    *   `_ 碱基型 _ ARRAY [ _n_ ]` ： _n_ 碱基型元件的数组

*   定位器：作为驻留在数据库服务器上的数据的逻辑指针的实体。 _ 定位器 _ 存在于客户端计算机中，是指向服务器上数据的瞬态逻辑指针。定位器通常指的是太大而无法在客户端上实现的数据，例如图像或音频。 （_ 物化视图 _ 是作为模式对象预先存储或“物化”的查询结果。）在 SQL 级别定义了运算符，以检索由定位符表示的随机访问的数据片段：

    *   `LOCATOR（_ 结构化类型 _）`：服务器中结构化实例的定位器

    *   `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`类型，因为`NUMERIC`映射到 Java 编程语言中的`BigDecimal`。
*   `DATALINK`：`java.net.URL`对象

## 使用高级数据类型

您可以像处理其他数据类型一样检索，存储和更新高级数据类型。你使用 `ResultSet.get _DataType_`或 `CallableStatement.get _DataType_`方法来检索它们， `PreparedStatement.set _DataType_`方法存储它们，而 `ResultSet.update _DataType_`方法更新它们。 （变量 `_DataType_`是映射到高级数据类型的 Java 接口或类的名称。）对高级数据类型执行的操作可能有 90％涉及使用`得到 _DataType_ `，`设置 _DataType_ `，`更新 _DataType_ `方法。下表显示了要使用的方法：

| **高级数据类型** | **`获取 _DataType_ `方法** | **`设置 _DataType_ `方法** | **`更新 _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 数据类型](distinct.html)。

例如，以下代码片段检索 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");

```

变量 `_ 得分 _` 是存储在学生`002238`行中的表`STUDENTS`中的 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();

```

此代码将 `_ 注释 _` 设置为发送到数据库的更新语句中的第一个参数。由 `_ 注释 _` 指定的`Clob`值将存储在`SALES`列中的值小于 1 的每一行的`COMMENTS`列中的`MARKETS`表中百万。