#处理XML

SQLXML是JDBC 4.0引入的接口,用于在Java应用程序中处理XML数据。

YashanDB中的XML数据以XMLTYPE类型进行存储,YashanDB JDBC实现了一系列方法用于读取和操作YashanDB的XMLTYPE类型数据。

# 接口方法

  1. 使用Connection接口的createSQLXML方法来创建一个空的SQLXML对象。

    类 方法 说明
    java.sql.Connection createSQLXML() 创建一个空的SQLXML对象,用于写入XML数据。
  2. 使用如下接口方法读写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)
  3. 使用如下接口方法读写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)
  4. 使用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:
&lt;?xml version="1.0" encoding="UTF-8"?>&lt;configuration>  &lt;product>    &lt;name>High performance server&lt;/name>    &lt;specs>      &lt;cpu>16 cores&lt;/cpu>      &lt;memory>64GB&lt;/memory>      &lt;storage>1TB&lt;/storage>      &lt;network>10Gbps&lt;/network>    &lt;/specs>  &lt;/product>&lt;/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

edit-icon
反馈
coperate-icon
coperate
合作
communication-icon
communicate
交流