#处理XML
SQLXML是JDBC 4.0引入的接口,用于在Java应用程序中处理XML数据。
YashanDB中的XML数据以XMLTYPE类型进行存储,YashanDB JDBC实现了一系列方法用于读取和操作YashanDB的XMLTYPE类型数据。
# 接口方法
使用Connection接口的createSQLXML方法来创建一个空的SQLXML对象。
类 方法 说明 java.sql.Connection createSQLXML() 创建一个空的SQLXML对象,用于写入XML数据。 使用如下接口方法读写SQLXML对象:
类 方法 java.sql.ResultSet getSQLXML(int index)
getSQLXML(String columnName)java.sql.ResultSet getObject(int index)
getObject(String columnName)java.sql.PreparedStatement setSQLXML(int index, SQLXML xmlObject) 使用如下接口方法读写SQLXML对象中的XML数据:
类 方法 java.sql.SQLXML getString() java.sql.SQLXML setString(String value) java.sql.SQLXML getCharacterStream() java.sql.SQLXML setCharacterStream() java.sql.SQLXML getBinaryStream() java.sql.SQLXML setBinaryStream() java.sql.SQLXML getSource(Class<T> sourceClass) java.sql.SQLXML setResult(Class<T> resultClass) 使用SQLXML接口的free方法释放SQLXML对象关联的资源。
上述读写SQLXML对象以及读写SQLXML对象中的数据的使用规则为:
新创建的SQLXML对象只能用于写入XML数据,不可读取。
通过get方法返回的SQLXML对象只能用于读取XML数据,不可写入。
一次创建或读取的SQLXML对象只可进行一次的写或读操作,之后的读写操作均无效。
# 创建SQLXML对象实践
需要通过JDBC接口构造XML数据时,可以调用Connection.createSQLXML()创建一个空的SQLXML对象。新创建的对象处于可写状态,可以通过setString、setCharacterStream、setBinaryStream或setResult写入XML内容,再通过PreparedStatement.setSQLXML将其绑定到XMLTYPE列。
以下示例只演示对象的创建和释放,不向数据库写入数据。程序成功执行后,将输出SQLXML对象的实现类;使用完毕后调用free()释放对象关联的资源。
package quickstart;
import java.sql.*;
import java.util.Properties;
public class SQLXMLCreationExample {
public static void main(String[] args) {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
// Username
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
// 加载驱动
try {
Class.forName("com.yashandb.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
return;
}
Connection conn = null;
try {
conn = DriverManager.getConnection(url, info);
// 创建SQLXML对象
SQLXML sqlXml = conn.createSQLXML();
System.out.println("Created SQLXML object successfully");
// 释放资源
sqlXml.free();
} catch (SQLException e) {
System.out.println("Error creating SQLXML: " + e.getMessage());
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
正常情况下,程序输出如下:
Created SQLXML object successfully
# 读写SQLXML数据
以下示例演示XML数据的基本写入和查询流程。程序首先创建包含XMLTYPE列的XML_DATA1表,然后通过PreparedStatement.setString绑定XML字符串,并使用XMLPARSE(DOCUMENT ?)将字符串转换为XML文档后写入数据库。
写入完成后,程序根据主键查询该记录并读取XML_CONTENT列。示例在执行前会删除ID=1001的已有记录,因此可以重复运行;正常情况下,插入语句影响1行,查询返回对应的ID、名称和XML数据。
package quickstart;
import java.sql.*;
import java.util.Properties;
public class SQLXMLReadWriteExample {
public static void main(String[] args) {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
try {
// 加载YashanDB驱动
Class.forName("com.yashandb.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
return;
}
try (Connection conn = DriverManager.getConnection(url, info)) {
// 先创建表(如果不存在)
String createTableSql = "CREATE TABLE IF NOT EXISTS XML_DATA1 (" +
"ID INT PRIMARY KEY," +
"NAME VARCHAR(100)," +
"XML_CONTENT XMLTYPE" +
")";
try (Statement stmt = conn.createStatement()) {
stmt.execute(createTableSql);
System.out.println("Table created or already exists");
// 删除旧数据以便重新测试
stmt.execute("DELETE FROM XML_DATA1 WHERE ID = 1001");
} catch (SQLException e) {
System.out.println("Create table info: " + e.getMessage());
}
// 使用XMLPARSE函数插入XML数据
String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<configuration>" +
" <product>" +
" <name>High performance server</name>" +
" <specs>" +
" <cpu>16 cores</cpu>" +
" <memory>64GB</memory>" +
" <storage>1TB</storage>" +
" <network>10Gbps</network>" +
" </specs>" +
" </product>" +
"</configuration>";
String insertSql = "INSERT INTO XML_DATA1 (ID, NAME, XML_CONTENT) VALUES (1001, 'test', XMLPARSE(DOCUMENT ?))";
try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
pstmt.setString(1, xmlContent);
int affectedRows = pstmt.executeUpdate();
System.out.println("Inserted " + affectedRows + " rows");
// 查询并读取XML数据
String querySql = "SELECT id, name, XML_CONTENT FROM XML_DATA1 WHERE id = 1001";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(querySql)) {
if (rs.next()) {
String id = rs.getString("ID");
String name = rs.getString("NAME");
// 获取SQLXML对象,再读取XML文本内容。
SQLXML sqlxml = rs.getSQLXML("XML_CONTENT");
String content = "";
if (sqlxml != null) {
try {
content = sqlxml.getString();
} finally {
sqlxml.free();
}
}
System.out.println("Retrieved data:");
System.out.println("ID: " + id);
System.out.println("Name: " + name);
System.out.println("XML Length: " + content.length());
System.out.println("XML Content:");
System.out.println(content);
}
}
} catch (SQLException e) {
System.out.println("Error reading XML data: " + e.getMessage());
e.printStackTrace();
}
} catch (SQLException e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
正常情况下,程序输出如下:
Table created or already exists
Inserted 1 rows
Retrieved data:
ID: 1001
Name: test
XML Length: 266
XML Content:
<?xml version="1.0" encoding="UTF-8"?><configuration> <product> <name>High performance server</name> <specs> <cpu>16 cores</cpu> <memory>64GB</memory> <storage>1TB</storage> <network>10Gbps</network> </specs> </product></configuration>
# 使用PreparedStatement处理XML
需要一次写入多条结构相同的XML数据时,可以复用同一个PreparedStatement并使用批处理。以下示例将ID、名称和XML内容分别绑定到占位符,其中XML字符串通过XMLPARSE(DOCUMENT ?)转换为XMLTYPE数据。
程序依次调用addBatch()添加3条记录,再通过executeBatch()统一执行,并在执行成功后提交事务。正常情况下,返回的批处理结果包含3个更新计数,总影响行数为3;任一操作失败时,应回滚当前事务。
package quickstart;
import java.sql.*;
import java.util.Properties;
public class SQLXMLWithPreparedStatementExample {
public static void main(String[] args) {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
// 先加载驱动
try {
Class.forName("com.yashandb.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
return;
}
Connection conn = null;
try {
conn = DriverManager.getConnection(url, info);
conn.setAutoCommit(false);
// 先创建表(如果不存在)
String createTableSql = "CREATE TABLE IF NOT EXISTS XML_DATA1 (" +
"ID INT PRIMARY KEY," +
"NAME VARCHAR(100)," +
"XML_CONTENT XMLTYPE" +
")";
try (Statement stmt = conn.createStatement()) {
stmt.execute(createTableSql);
System.out.println("Table created or already exists");
} catch (SQLException e) {
System.out.println("Create table info: " + e.getMessage());
}
// 批量插入XML数据
String sql = "INSERT INTO XML_DATA1 (id, name, xml_content) " +
"VALUES (?, ?, XMLPARSE(DOCUMENT ?))";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 准备多条XML记录
String[] names = {"product A", "product B", "product C"};
int[] quantities = {100, 200, 150};
for (int i = 0; i < names.length; i++) {
// 设置参数
pstmt.setInt(1, 2000 + i);
pstmt.setString(2, names[i]);
// 创建XML内容
String xmlContent = String.format(
"<product>" +
" <name>%s</name>" +
" <quantity>%d</quantity>" +
"</product>",
names[i], quantities[i]);
// 使用setString设置XML内容
pstmt.setString(3, xmlContent);
// 添加到批处理
pstmt.addBatch();
System.out.println("Added " + names[i] + " to batch");
}
// 执行批处理
int[] updateCounts = pstmt.executeBatch();
int totalAffected = java.util.Arrays.stream(updateCounts).sum();
System.out.println("Batch insert completed, total affected: " + totalAffected);
// 提交事务
conn.commit();
} catch (SQLException e) {
System.out.println("Error in batch processing: " + e.getMessage());
e.printStackTrace();
}
} catch (SQLException e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
正常情况下,程序输出如下:
Table created or already exists Added product A to batch Added product B to batch Added product C to batch Batch insert completed, total affected: 3
# 更新XML数据
更新已有XML数据时,可以将新的XML内容和目标记录主键同时作为参数绑定。以下示例先准备ID=1001的初始记录,再使用XMLPARSE(DOCUMENT ?)把新的XML字符串转换为XML文档并更新XML_CONTENT列。
executeUpdate()返回实际更新的行数。目标记录存在时应返回1;返回0通常表示WHERE条件未匹配记录,应检查前置数据和绑定参数。更新成功后,程序提交事务以持久化修改。
package quickstart;
import java.sql.*;
import java.util.Properties;
public class SQLXMLUpdateExample {
public static void main(String[] args) {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
// 加载驱动
try {
Class.forName("com.yashandb.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
return;
}
Connection conn = null;
try {
conn = DriverManager.getConnection(url, info);
conn.setAutoCommit(false);
// 首先创建表并插入初始数据
Statement stmt = conn.createStatement();
try {
stmt.execute("CREATE TABLE IF NOT EXISTS XML_DATA1(id INT PRIMARY KEY, name VARCHAR(100), xml_content XMLTYPE)");
} catch (SQLException e) {
System.out.println("Table info: " + e.getMessage());
}
// 插入初始数据(如果不存在)
try {
stmt.execute("DELETE FROM XML_DATA1 WHERE id = 1001");
stmt.execute("INSERT INTO XML_DATA1 (id, name, xml_content) VALUES (1001, 'test', XMLPARSE(DOCUMENT '<product><name>servers</name></product>'))");
} catch (SQLException e) {
System.out.println("Insert initial data info: " + e.getMessage());
}
stmt.close();
// 准备更新语句 - 使用XMLPARSE将字符串转换为XML
String sql = "UPDATE XML_DATA1 SET xml_content = XMLPARSE(DOCUMENT ?) WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 准备更新的XML内容
String updatedContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<product>" +
" <name>update servers</name>" +
" <specs>" +
" <cpu>32 cores</cpu>" +
" <memory>128GB</memory>" +
" <storage>2TB</storage>" +
" <network>20Gbps</network>" +
" </specs>" +
"</product>";
// 设置参数
pstmt.setString(1, updatedContent);
pstmt.setInt(2, 1001);
// 执行更新
int affectedRows = pstmt.executeUpdate();
System.out.println("Updated " + affectedRows + " row(s)");
// 提交事务
conn.commit();
} catch (SQLException e) {
System.out.println("Error updating XML data: " + e.getMessage());
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
正常情况下,程序输出如下:
Updated 1 row(s)
# XML类型转换
当应用程序持有XML字符串,而数据库列类型为XMLTYPE时,可以在SQL中使用XMLPARSE(DOCUMENT ?)完成从字符数据到XML文档的转换。这样应用程序仍使用标准的setString()绑定参数,XML语法解析和类型构造由数据库完成。
以下示例更新XML_DATA1表中ID=1001的记录。运行前应确保该记录已经存在;正常情况下,executeUpdate()返回1。传入内容不是格式正确的XML文档时,数据库将返回XML解析错误。
package quickstart;
import java.sql.*;
import java.util.Properties;
public class XMLConversionExample {
public static void main(String[] args) {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
// 加载驱动
try {
Class.forName("com.yashandb.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
return;
}
Connection conn = null;
try {
conn = DriverManager.getConnection(url, info);
// 查询并更新XML数据
String updateSql = "UPDATE XML_DATA1 SET xml_content = XMLPARSE(DOCUMENT ?) WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(updateSql)) {
String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<product>" +
" <name>Conversion Test</name>" +
"</product>";
pstmt.setString(1, xmlContent);
pstmt.setInt(2, 1001);
int affectedRows = pstmt.executeUpdate();
System.out.println("Updated " + affectedRows + " row(s)");
System.out.println("XML conversion example completed");
} catch (SQLException e) {
System.out.println("Error in XML conversion: " + e.getMessage());
e.printStackTrace();
}
} catch (SQLException e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
正常情况下,程序输出如下:
Updated 1 row(s) XML conversion example completed
# 删除XML数据
删除包含XML数据的记录与删除普通关系数据相同,可以使用带绑定参数的DELETE语句。XML对象不需要单独删除;记录被删除后,其XMLTYPE列数据随记录一并删除。
以下示例先创建XML_DATA1表并准备一条ID=2000的XML记录,然后使用PreparedStatement删除该记录并提交事务。示例会先清理相同ID的已有数据,因此可以重复运行;正常情况下,删除操作影响1行。
package quickstart;
import java.sql.*;
import java.util.Properties;
public class SQLXMLDeletionExample {
public static void main(String[] args) {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
// 加载驱动
try {
Class.forName("com.yashandb.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
return;
}
Connection conn = null;
try {
conn = DriverManager.getConnection(url, info);
conn.setAutoCommit(false);
// 创建测试表,并准备ID为2000的待删除记录。
try (Statement stmt = conn.createStatement()) {
stmt.execute(
"CREATE TABLE IF NOT EXISTS XML_DATA1 ("
+ "ID INT PRIMARY KEY, "
+ "NAME VARCHAR(100), "
+ "XML_CONTENT XMLTYPE)");
stmt.executeUpdate(
"DELETE FROM XML_DATA1 WHERE ID = 2000");
stmt.executeUpdate(
"INSERT INTO XML_DATA1 (ID, NAME, XML_CONTENT) "
+ "VALUES (2000, 'delete_test', "
+ "XMLPARSE(DOCUMENT "
+ "'<product><name>delete</name></product>'))");
}
// 删除XML数据
String sql = "DELETE FROM XML_DATA1 WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 删除ID为2000的记录
pstmt.setInt(1, 2000);
int affectedRows = pstmt.executeUpdate();
System.out.println("Deleted " + affectedRows + " record(s)");
// 提交事务
conn.commit();
} catch (SQLException e) {
System.out.println("Error in deletion: " + e.getMessage());
e.printStackTrace();
}
} catch (SQLException e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
正常情况下,程序输出如下:
Deleted 1 record(s)
# 流式XML处理
处理较大的XML文件时,可以使用PreparedStatement.setCharacterStream将Reader绑定到SQL参数,避免应用程序先将整个文件读取为String。查询XML数据时,可以通过SQLXML.getCharacterStream按字符流读取。
package quickstart;
import java.io.BufferedReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLXML;
import java.sql.Statement;
import java.util.Properties;
public class StreamingXMLExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Path xmlPath = Paths.get("C:/data/config.xml");
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
// 加载YashanDB JDBC驱动。
Class.forName("com.yashandb.jdbc.Driver");
try (Connection conn = DriverManager.getConnection(url, info)) {
conn.setAutoCommit(false);
// 创建测试表,并清理同一主键的数据以便重复运行。
try (Statement stmt = conn.createStatement()) {
stmt.execute(
"CREATE TABLE IF NOT EXISTS XML_DATA1 ("
+ "ID INT PRIMARY KEY, "
+ "NAME VARCHAR(100), "
+ "XML_CONTENT XMLTYPE)");
stmt.executeUpdate(
"DELETE FROM XML_DATA1 WHERE ID = 3000");
}
String insertSql =
"INSERT INTO XML_DATA1 (ID, NAME, XML_CONTENT) "
+ "VALUES (?, ?, XMLPARSE(DOCUMENT ?))";
// Reader中的字符按需传递给驱动,无需先读取为完整字符串。
try (BufferedReader xmlReader = Files.newBufferedReader(
xmlPath, StandardCharsets.UTF_8);
PreparedStatement pstmt =
conn.prepareStatement(insertSql)) {
pstmt.setInt(1, 3000);
pstmt.setString(2, "stream_test");
pstmt.setCharacterStream(3, xmlReader);
System.out.println(
"Inserted rows: " + pstmt.executeUpdate());
}
String querySql =
"SELECT XML_CONTENT FROM XML_DATA1 WHERE ID = ?";
try (PreparedStatement pstmt =
conn.prepareStatement(querySql)) {
pstmt.setInt(1, 3000);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
SQLXML sqlxml = rs.getSQLXML(1);
try (Reader xmlReader =
sqlxml.getCharacterStream()) {
char[] buffer = new char[8192];
while (xmlReader.read(buffer) != -1) {
// 分块处理XML数据。
}
} finally {
sqlxml.free();
}
}
}
}
conn.commit();
}
}
}
正常情况下,程序输出如下:
Inserted rows: 1
setCharacterStream使应用程序不必在绑定前将完整XML文件加载到内存。驱动是否对数据进行分块编码和网络发送,由驱动实现及数据长度决定。
# SQLXML数据源
XML内容可能来自本地文件、远程服务或其他输入源。应用程序读取XML内容后,可以使用Connection.createSQLXML()创建对象,通过SQLXML写入方法设置内容,再调用PreparedStatement.setSQLXML()将对象绑定到数据库的XMLTYPE列。
SQLXML对象使用完毕后应调用free()。对于较大的输入,不应先拼接为完整字符串,可参考前文的流式XML处理方式,通过字符流读取和绑定。
# 从文件创建SQLXML
以下示例从本地XML文件读取字符内容,调用SQLXML.setString()写入新创建的SQLXML对象,然后通过PreparedStatement.setSQLXML()保存到数据库。
示例使用C:/data/config.xml作为输入文件;文件不存在时会创建一份示例内容。运行前需要准备config_data表,且接收setSQLXML()参数的xml_content列应使用XMLTYPE。如果目标列为CLOB,应改用setString()、setCharacterStream()或setClob()。
package quickstart;
import java.sql.*;
import java.util.Properties;
import java.io.*;
import java.net.*;
public class SQLXMLFromFileExample {
public static void main(String[] args) {
// 数据库连接参数
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
Connection conn = null;
PreparedStatement pstmt = null;
FileReader reader = null;
SQLXML sqlXml = null;
try {
// 加载YashanDB JDBC驱动
Class.forName("com.yashandb.jdbc.Driver");
// 获取数据库连接
conn = DriverManager.getConnection(url, info);
// 创建表(如果不存在)
Statement stmt = conn.createStatement();
try {
stmt.execute("CREATE TABLE IF NOT EXISTS config_data(id INTEGER, name VARCHAR(100), xml_content XMLTYPE)");
} catch (SQLException e) {
System.out.println("Table info: " + e.getMessage());
}
stmt.close();
// 读取XML文件内容
String filePath = "C:/data/config.xml";
StringBuilder xmlContent = new StringBuilder();
// 创建示例XML文件(如果不存在)
try {
java.io.File file = new java.io.File(filePath);
if (!file.exists()) {
file.getParentFile().mkdirs();
java.io.FileWriter fw = new java.io.FileWriter(file);
fw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<config><setting>value</setting></config>");
fw.close();
}
} catch (Exception e) {
System.out.println("File creation info: " + e.getMessage());
}
reader = new FileReader(filePath);
int ch;
while ((ch = reader.read()) != -1) {
xmlContent.append((char) ch);
}
reader.close();
reader = null;
// 创建SQLXML对象
sqlXml = conn.createSQLXML();
sqlXml.setString(xmlContent.toString());
// 插入到数据库
String sql = "INSERT INTO config_data (id, name, xml_content) " +
"VALUES (?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 2000);
// 名称
pstmt.setString(2, "system configuration");
pstmt.setSQLXML(3, sqlXml);
int affectedRows = pstmt.executeUpdate();
System.out.println("Inserted config data, affected rows: " + affectedRows);
// 释放资源
if (sqlXml != null) {
sqlXml.free();
}
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
e.printStackTrace();
} catch (SQLException e) {
System.out.println("Database error: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
e.printStackTrace();
} finally {
// 关闭资源
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
正常情况下,程序输出如下:
Inserted config data, affected rows: 1
# 从URL创建SQLXML
远程XML的处理流程与本地文件相同:先从URL获取XML内容,再将内容写入SQLXML对象,最后通过setSQLXML()绑定到XMLTYPE列。实际应用应设置连接和读取超时,并妥善关闭URL返回的输入流。
以下代码使用内置XML字符串模拟从URL获取到的内容,便于在没有外部网络的环境中运行;变量xmlUrl仅表示数据来源。示例依赖已经创建的config_data表,并将ID=3000作为测试记录主键。
package quickstart;
import java.sql.*;
import java.util.Properties;
import java.io.*;
import java.net.*;
public class SQLXMLFromURLExample {
public static void main(String[] args) {
// 数据库连接参数
String url = "jdbc:yasdb://192.168.1.2:1688/yasdb";
Properties info = new Properties();
info.setProperty("user", "username");
info.setProperty("password", "passwd");
Connection conn = null;
PreparedStatement pstmt = null;
InputStream is = null;
SQLXML sqlXml = null;
try {
// 加载YashanDB JDBC驱动
Class.forName("com.yashandb.jdbc.Driver");
// 获取数据库连接
conn = DriverManager.getConnection(url, info);
// 从URL读取XML
String xmlUrl = "https://example.com/config.xml";
// 创建示例XML内容(因为网络URL可能无法访问)
String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<config><setting>sample</setting></config>";
// 创建SQLXML对象
sqlXml = conn.createSQLXML();
sqlXml.setString(xmlContent);
System.out.println("Created SQLXML from sample content");
// 直接使用已设置的xmlContent
// 插入到数据库
String sql = "INSERT INTO config_data (id, name, xml_content) " +
"VALUES (?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 3000);
// 远程配置名称
pstmt.setString(2, "remote_config");
pstmt.setSQLXML(3, sqlXml);
int affectedRows = pstmt.executeUpdate();
System.out.println("Inserted remote config, affected rows: " + affectedRows);
// 释放资源
if (sqlXml != null) {
sqlXml.free();
}
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
e.printStackTrace();
// 捕获并处理SQLException异常
} catch (SQLException e) {
System.out.println("Database error: " + e.getMessage());
e.printStackTrace();
} finally {
// 关闭资源
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
正常情况下,程序输出如下:
Created SQLXML from sample content Inserted remote config, affected rows: 1

