#java.sql.SQLData

# 描述

java.sql.SQLData接口用于创建自定义类并将其与UDT的Object类型进行映射。核心作用是:让开发者自定义Java类与数据库中的自定义类型(如SQL的STRUCT类型、Oracle的对象类型、PostgreSQL的复合类型)之间的映射规则,实现该接口的Java类,能将数据库自定义类型的字段转换为Java对象的属性,也能将Java对象的属性反向写入数据库的自定义类型字段,是处理数据库复杂自定义类型与Java对象转换的标准方式。

详细接口说明请参考JDBC官方网站 (opens new window)。

# 方法

java.sql.SQLData包含的方法如下:

方法 返回类型 备注
getSQLTypeName() String 返回对应的UDT类型名称,必须是schema.name全名称。
readSQL (SQLInput stream, String typeName) void 从给定的输入流中读取SQL类型的每个属性或元素,设置UDT类型名称。
writeSQL (SQLOutput stream) void 将SQL类型的每个属性写入给定的输出流。

Note:

SQLData需要用户在自定义类时实现,只有正确实现SQLData里面的三个方法才能完成UDT类型与自定义类的映射。

# 示例

以下示例使用实现SQLData接口的Java类读写数据库中的UDT对象,完整演示getSQLTypeName()、writeSQL()和readSQL()三个方法的配合使用。

# 定义UDT对象和Java映射类

CREATE OR REPLACE TYPE UDT_OBJECT AS OBJECT (
    age INTEGER,
    name VARCHAR(32)
);

CREATE TABLE UDT_TABLE (
    id INTEGER PRIMARY KEY,
    person UDT_OBJECT
);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLData;
import java.sql.SQLInput;
import java.sql.SQLOutput;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class SQLDataExample {
    private static final String URL =
            "jdbc:yasdb://192.168.1.2:1688/yasdb";
    private static final String USER = "username";
    private static final String PASSWORD = "passwd";

    public static void main(String[] args) throws Exception {
        Class.forName("com.yashandb.jdbc.Driver");
        try (Connection connection =
                     DriverManager.getConnection(URL, USER, PASSWORD)) {
            String fullTypeName = connection.getMetaData().getUserName()
                    .toUpperCase() + ".UDT_OBJECT";
            TypeHolder.setSQLTypeName(fullTypeName);

            insertUDT(connection);
            readUDT(connection, fullTypeName);
        }
    }

    private static void insertUDT(Connection connection) throws SQLException {
        TypeHolder person = new TypeHolder(23, "Bob");
        try (PreparedStatement statement = connection.prepareStatement(
                "INSERT INTO UDT_TABLE (id, person) VALUES (?, ?)")) {
            statement.setInt(1, 1);
            // 驱动在绑定并写入UDT对象时调用getSQLTypeName()和writeSQL()。
            statement.setObject(2, person);
            System.out.println("Inserted rows: " + statement.executeUpdate());
        }
    }

    private static void readUDT(
            Connection connection, String fullTypeName) throws SQLException {
        Map<String, Class<?>> typeMap = new HashMap<>();
        typeMap.put(fullTypeName, TypeHolder.class);
        try (PreparedStatement statement = connection.prepareStatement(
                "SELECT person FROM UDT_TABLE WHERE id = ?")) {
            statement.setInt(1, 1);
            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    // 驱动在映射查询结果时调用readSQL()。
                    TypeHolder person =
                            (TypeHolder) resultSet.getObject(1, typeMap);
                    System.out.println("Mapped UDT: age=" + person.getAge()
                            + ", name=" + person.getName());
                    System.out.println("SQL type name: "
                            + person.getSQLTypeName());
                }
            }
        }
    }

    public static class TypeHolder implements SQLData {
        private static String sqlTypeName;
        private int age;
        private String name;

        public TypeHolder() {
        }

        public TypeHolder(int age, String name) {
            this.age = age;
            this.name = name;
        }

        public static void setSQLTypeName(String typeName) {
            sqlTypeName = typeName;
        }

        public int getAge() {
            return age;
        }

        public String getName() {
            return name;
        }

        @Override
        public String getSQLTypeName() throws SQLException {
            return sqlTypeName;
        }

        @Override
        public void readSQL(SQLInput input, String typeName)
                throws SQLException {
            sqlTypeName = typeName;
            age = input.readInt();
            name = input.readString();
        }

        @Override
        public void writeSQL(SQLOutput output) throws SQLException {
            output.writeInt(age);
            output.writeString(name);
        }
    }
}

程序输出如下:

Inserted rows: 1
Mapped UDT: age=23, name=Bob
SQL type name: USERNAME.UDT_OBJECT
pdf-btn 下载文档 copy-btn 复制链接
edit-icon
反馈
coperate-icon
coperate
合作
communication-icon
communicate
交流