#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

