From 000fec8597a05cf511f42d43228b4ae171e0b283 Mon Sep 17 00:00:00 2001
From: 18867471376 <13272213728ly>
Date: Mon, 19 May 2025 18:37:45 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20solon-ai-load-jdbc?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
__release/solon-ai-bundle1/pom.xml | 1 +
.../solon-ai-load-jdbc/NOTICE | 65 +++++++++
.../solon-ai-load-jdbc/pom.xml | 48 +++++++
.../solon/ai/rag/loader/JdbcLoadConfig.java | 100 ++++++++++++++
.../noear/solon/ai/rag/loader/JdbcLoader.java | 125 ++++++++++++++++++
.../features/ai/load/jdbc/JdbcLoaderTest.java | 61 +++++++++
6 files changed, 400 insertions(+)
create mode 100644 solon-ai-rag-loaders/solon-ai-load-jdbc/NOTICE
create mode 100644 solon-ai-rag-loaders/solon-ai-load-jdbc/pom.xml
create mode 100644 solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoadConfig.java
create mode 100644 solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoader.java
create mode 100644 solon-ai-rag-loaders/solon-ai-load-jdbc/src/test/java/features/ai/load/jdbc/JdbcLoaderTest.java
diff --git a/__release/solon-ai-bundle1/pom.xml b/__release/solon-ai-bundle1/pom.xml
index da6287d1..e4fe4289 100644
--- a/__release/solon-ai-bundle1/pom.xml
+++ b/__release/solon-ai-bundle1/pom.xml
@@ -31,6 +31,7 @@
../../solon-ai-rag-loaders/solon-ai-load-html
../../solon-ai-rag-loaders/solon-ai-load-markdown
../../solon-ai-rag-loaders/solon-ai-load-mysql
+ ../../solon-ai-rag-loaders/solon-ai-load-jdbc
../../solon-ai-rag-loaders/solon-ai-load-pdf
../../solon-ai-rag-loaders/solon-ai-load-ppt
../../solon-ai-rag-loaders/solon-ai-load-word
diff --git a/solon-ai-rag-loaders/solon-ai-load-jdbc/NOTICE b/solon-ai-rag-loaders/solon-ai-load-jdbc/NOTICE
new file mode 100644
index 00000000..784c4678
--- /dev/null
+++ b/solon-ai-rag-loaders/solon-ai-load-jdbc/NOTICE
@@ -0,0 +1,65 @@
+Copyright 2017-2025 noear.org and authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+This project includes:
+ Apache Commons Codec under Apache-2.0
+ Apache Commons Collections under Apache License, Version 2.0
+ Apache Commons Compress under Apache-2.0
+ Apache Commons IO under Apache-2.0
+ Apache Commons Lang under Apache-2.0
+ Apache Commons Math under Apache License, Version 2.0
+ Apache Log4j API under Apache-2.0
+ Apache POI under Apache License, Version 2.0
+ Apache POI - API based on OPC and OOXML schemas under Apache License, Version 2.0
+ Apache POI - Common under Apache License, Version 2.0
+ asm under BSD-3-Clause
+ Byte Buddy (without dependencies) under Apache License, Version 2.0
+ Byte Buddy agent under Apache License, Version 2.0
+ curvesapi under BSD License
+ JavaPoet under Apache 2.0
+ JTokkit under MIT License
+ JUnit Jupiter (Aggregator) under Eclipse Public License v2.0
+ JUnit Jupiter API under Eclipse Public License v2.0
+ JUnit Jupiter Engine under Eclipse Public License v2.0
+ JUnit Jupiter Params under Eclipse Public License v2.0
+ JUnit Platform Commons under Eclipse Public License v2.0
+ JUnit Platform Engine API under Eclipse Public License v2.0
+ mockito-core under The MIT License
+ mockito-junit-jupiter under The MIT License
+ Objenesis under Apache License, Version 2.0
+ org.apiguardian:apiguardian-api under The Apache License, Version 2.0
+ org.opentest4j:opentest4j under The Apache License, Version 2.0
+ reactive-streams under MIT-0
+ SLF4J API Module under MIT License
+ snack3 under The Apache Software License, Version 2.0
+ SnakeYAML under Apache License, Version 2.0
+ solon under The Apache Software License, Version 2.0
+ solon-ai under The Apache Software License, Version 2.0
+ solon-ai-load-excel under The Apache Software License, Version 2.0
+ solon-aot under The Apache Software License, Version 2.0
+ solon-config-plus under The Apache Software License, Version 2.0
+ solon-config-yaml under The Apache Software License, Version 2.0
+ solon-data under The Apache Software License, Version 2.0
+ solon-logging under The Apache Software License, Version 2.0
+ solon-logging-simple under The Apache Software License, Version 2.0
+ solon-mvc under The Apache Software License, Version 2.0
+ solon-net-httputils under The Apache Software License, Version 2.0
+ solon-proxy under The Apache Software License, Version 2.0
+ solon-rx under The Apache Software License, Version 2.0
+ solon-security-vault under The Apache Software License, Version 2.0
+ solon-serialization under The Apache Software License, Version 2.0
+ solon-test under The Apache Software License, Version 2.0
+ SparseBitSet under The Apache Software License, Version 2.0
+ XmlBeans under The Apache Software License, Version 2.0
+
diff --git a/solon-ai-rag-loaders/solon-ai-load-jdbc/pom.xml b/solon-ai-rag-loaders/solon-ai-load-jdbc/pom.xml
new file mode 100644
index 00000000..027cdd3f
--- /dev/null
+++ b/solon-ai-rag-loaders/solon-ai-load-jdbc/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+
+ org.noear
+ solon-ai-parent
+ 3.3.1-SNAPSHOT
+ ../../solon-ai-parent/pom.xml
+
+
+ solon-ai-load-jdbc
+ jar
+
+
+
+ org.noear
+ solon-ai
+
+
+
+ com.zaxxer
+ HikariCP
+ provided
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.33
+ provided
+
+
+
+ org.noear
+ solon-logging-simple
+ test
+
+
+
+ org.noear
+ solon-test
+ test
+
+
+
\ No newline at end of file
diff --git a/solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoadConfig.java b/solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoadConfig.java
new file mode 100644
index 00000000..191ffb22
--- /dev/null
+++ b/solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoadConfig.java
@@ -0,0 +1,100 @@
+package org.noear.solon.ai.rag.loader;
+
+public class JdbcLoadConfig {
+ private String shcemaTableQuerySql;
+ private String shcemaTableQueryAndSchemaSqlTemplate;
+ private String shcemaTableQueryAndTableSqlTemplate;
+ private String shcemaTableQueryResultSchemeNameColumn;
+ private String shcemaTableQueryResultTableNameColumn;
+
+ private String ddlQuerySqlTemplate;
+ private String ddlQueryResultDdlNameColumn;
+
+
+ public JdbcLoadConfig(String shcemaTableQuerySql, String shcemaTableQueryAndSchemaSqlTemplate, String shcemaTableQueryAndTableSqlTemplate, String shcemaTableQueryResultSchemeNameColumn, String shcemaTableQueryResultTableNameColumn, String ddlQuerySqlTemplate, String ddlQueryResultDdlNameColumn) {
+ this.shcemaTableQuerySql = shcemaTableQuerySql;
+ this.shcemaTableQueryAndSchemaSqlTemplate = shcemaTableQueryAndSchemaSqlTemplate;
+ this.shcemaTableQueryAndTableSqlTemplate = shcemaTableQueryAndTableSqlTemplate;
+ this.shcemaTableQueryResultSchemeNameColumn = shcemaTableQueryResultSchemeNameColumn;
+ this.shcemaTableQueryResultTableNameColumn = shcemaTableQueryResultTableNameColumn;
+ this.ddlQuerySqlTemplate = ddlQuerySqlTemplate;
+ this.ddlQueryResultDdlNameColumn = ddlQueryResultDdlNameColumn;
+ }
+
+ public static class Builder {
+ private String shcemaTableQuerySql;
+ private String shcemaTableQueryAndSchemaSqlTemplate;
+ private String shcemaTableQueryAndTableSqlTemplate;
+ private String shcemaTableQueryResultSchemeNameColumn;
+ private String shcemaTableQueryResultTableNameColumn;
+ private String ddlQuerySqlTemplate;
+ private String ddlQueryResultDdlNameColumn;
+
+ public Builder shcemaTableQuerySql(String shcemaTableQuerySql) {
+ this.shcemaTableQuerySql = shcemaTableQuerySql;
+ return this;
+ }
+
+ public Builder shcemaTableQueryAndSchemaSqlTemplate(String shcemaTableQueryAndSchemaSqlTemplate) {
+ this.shcemaTableQueryAndSchemaSqlTemplate = shcemaTableQueryAndSchemaSqlTemplate;
+ return this;
+ }
+
+ public Builder shcemaTableQueryAndTableSqlTemplate(String shcemaTableQueryAndTableSqlTemplate) {
+ this.shcemaTableQueryAndTableSqlTemplate = shcemaTableQueryAndTableSqlTemplate;
+ return this;
+ }
+
+ public Builder shcemaTableQueryResultSchemeNameColumn(String shcemaTableQueryResultSchemeNameColumn) {
+ this.shcemaTableQueryResultSchemeNameColumn = shcemaTableQueryResultSchemeNameColumn;
+ return this;
+ }
+
+ public Builder shcemaTableQueryResultTableNameColumn(String shcemaTableQueryResultTableNameColumn) {
+ this.shcemaTableQueryResultTableNameColumn = shcemaTableQueryResultTableNameColumn;
+ return this;
+ }
+
+ public Builder ddlQuerySqlTemplate(String ddlQuerySqlTemplate) {
+ this.ddlQuerySqlTemplate = ddlQuerySqlTemplate;
+ return this;
+ }
+
+ public Builder ddlQueryResultDdlNameColumn(String ddlQueryResultDdlNameColumn) {
+ this.ddlQueryResultDdlNameColumn = ddlQueryResultDdlNameColumn;
+ return this;
+ }
+
+ public JdbcLoadConfig build() {
+ return new JdbcLoadConfig(this.shcemaTableQuerySql, this.shcemaTableQueryAndSchemaSqlTemplate, this.shcemaTableQueryAndTableSqlTemplate, this.shcemaTableQueryResultSchemeNameColumn, this.shcemaTableQueryResultTableNameColumn, this.ddlQuerySqlTemplate, this.ddlQueryResultDdlNameColumn);
+ }
+ }
+
+ public String getShcemaTableQuerySql() {
+ return shcemaTableQuerySql;
+ }
+
+ public String getShcemaTableQueryAndSchemaSqlTemplate() {
+ return shcemaTableQueryAndSchemaSqlTemplate;
+ }
+
+ public String getShcemaTableQueryAndTableSqlTemplate() {
+ return shcemaTableQueryAndTableSqlTemplate;
+ }
+
+ public String getShcemaTableQueryResultSchemeNameColumn() {
+ return shcemaTableQueryResultSchemeNameColumn;
+ }
+
+ public String getShcemaTableQueryResultTableNameColumn() {
+ return shcemaTableQueryResultTableNameColumn;
+ }
+
+ public String getDdlQuerySqlTemplate() {
+ return ddlQuerySqlTemplate;
+ }
+
+ public String getDdlQueryResultDdlNameColumn() {
+ return ddlQueryResultDdlNameColumn;
+ }
+}
diff --git a/solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoader.java b/solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoader.java
new file mode 100644
index 00000000..55ae7398
--- /dev/null
+++ b/solon-ai-rag-loaders/solon-ai-load-jdbc/src/main/java/org/noear/solon/ai/rag/loader/JdbcLoader.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2017-2025 noear.org and authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.noear.solon.ai.rag.loader;
+
+import java.io.*;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.noear.snack.core.utils.StringUtil;
+import org.noear.solon.ai.rag.Document;
+import org.noear.solon.lang.Preview;
+
+import javax.sql.DataSource;
+
+/**
+ * JDBC表结构 加载器
+ *
+ * 读取表结构DDL,并转换为文本
+ *
+ *
+ * @author 刘颜
+ * @since 3.3
+ */
+@Preview("3.3")
+public class JdbcLoader extends AbstractOptionsDocumentLoader {
+ private DataSource dataSource;
+ private JdbcLoadConfig jdbcLoadConfig;
+
+ public JdbcLoader(DataSource dataSource) {
+ this.dataSource = dataSource;
+ //默认支持mysql
+ this.jdbcLoadConfig = new JdbcLoadConfig.Builder()
+ .shcemaTableQuerySql(" select TABLE_SCHEMA, TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA not in ('mysql', 'sys', 'information_schema') ")
+ .shcemaTableQueryAndSchemaSqlTemplate(" and TABLE_SCHEMA = '%s' ")
+ .shcemaTableQueryAndTableSqlTemplate(" and TABLE_SCHEMA = '%s' and TABLE_NAME = '%s' ")
+ .shcemaTableQueryResultSchemeNameColumn("TABLE_SCHEMA")
+ .shcemaTableQueryResultTableNameColumn("TABLE_NAME")
+ .ddlQuerySqlTemplate(" SHOW CREATE TABLE `%s`.`%s` ")
+ .ddlQueryResultDdlNameColumn("Create Table").build();
+ options = new Options();
+ }
+
+ public JdbcLoader(DataSource dataSource, JdbcLoadConfig jdbcLoadConfig) {
+ this.dataSource = dataSource;
+ this.jdbcLoadConfig = jdbcLoadConfig;
+ options = new Options();
+ }
+
+ @Override
+ public List load() throws IOException {
+ List documents = new ArrayList<>();
+
+ String targetSchema = options.targetSchema;
+ String targetTable = options.targetTable;
+
+ try (Connection connection = dataSource.getConnection()) {
+ String sql = this.jdbcLoadConfig.getShcemaTableQuerySql();
+ if (StringUtil.isEmpty(targetSchema)) {
+ //全库全表
+ } else if (StringUtil.isEmpty(targetTable)) {
+ //单库全表
+ sql = sql.concat(String.format(this.jdbcLoadConfig.getShcemaTableQueryAndSchemaSqlTemplate(), targetSchema));
+ } else {
+ //单库单表
+ sql = sql.concat(String.format(this.jdbcLoadConfig.getShcemaTableQueryAndTableSqlTemplate(), targetSchema, targetTable));
+ }
+ try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
+ ResultSet rowSet = preparedStatement.executeQuery();
+ while (rowSet.next()) {
+ //每张表单独转化
+ String tableSchema = rowSet.getString(this.jdbcLoadConfig.getShcemaTableQueryResultSchemeNameColumn());
+ String tableName = rowSet.getString(this.jdbcLoadConfig.getShcemaTableQueryResultTableNameColumn());
+ String showddl = String.format(this.jdbcLoadConfig.getDdlQuerySqlTemplate(), tableSchema, tableName);
+ try (PreparedStatement showddlPrepareStatement = connection.prepareStatement(showddl)) {
+ ResultSet showddlResultSet = showddlPrepareStatement.executeQuery();
+ if (showddlResultSet.next()) {
+ String tableddl = showddlResultSet.getString(this.jdbcLoadConfig.getDdlQueryResultDdlNameColumn());
+ String fullDDL = "CREATE TABLE `" + tableSchema + "`.`" + tableName + "` " + tableddl.substring(tableddl.indexOf("("));
+ Document doc = new Document(fullDDL).metadata(this.additionalMetadata);
+ documents.add(doc);
+ }
+ }
+ }
+ }
+ } catch (RuntimeException | SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ return documents;
+ }
+
+ /**
+ * 选项
+ */
+ public static class Options {
+ private String targetSchema;
+ private String targetTable;
+
+ /**
+ * targetSchema为null,不管targetTable是否为null,则是全库全表加载
+ * targetSchema不为null,targetTable为null则是单库全表加载
+ * targetSchema不为null,targetTable不为null则是单库单表加载
+ * 否则默认是全库全表加载
+ */
+ public Options loadOptions(String targetSchema, String targetTable) {
+ this.targetSchema = targetSchema;
+ this.targetTable = targetTable;
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/solon-ai-rag-loaders/solon-ai-load-jdbc/src/test/java/features/ai/load/jdbc/JdbcLoaderTest.java b/solon-ai-rag-loaders/solon-ai-load-jdbc/src/test/java/features/ai/load/jdbc/JdbcLoaderTest.java
new file mode 100644
index 00000000..432b2682
--- /dev/null
+++ b/solon-ai-rag-loaders/solon-ai-load-jdbc/src/test/java/features/ai/load/jdbc/JdbcLoaderTest.java
@@ -0,0 +1,61 @@
+package features.ai.load.jdbc;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.junit.jupiter.api.Test;
+import org.noear.solon.ai.rag.Document;
+import org.noear.solon.ai.rag.loader.JdbcLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
+import java.util.List;
+
+public class JdbcLoaderTest {
+ private static final Logger log = LoggerFactory.getLogger(JdbcLoaderTest.class);
+
+ private static DataSource ds;
+
+ public JdbcLoaderTest() {
+ String url = "jdbc:mysql://127.0.0.1:3306/test";
+ String username = "root";
+ String password = "root";
+
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl(url);
+ config.setUsername(username);
+ config.setPassword(password);
+
+ ds = new HikariDataSource(config);
+ }
+
+ @Test
+ public void test1() throws Exception {
+ //全库全表
+ JdbcLoader loader = new JdbcLoader(ds);
+ List docs = loader.load();
+ System.out.println(docs.size());
+ assert docs.size() > 0;
+ }
+
+ @Test
+ public void test2() throws Exception {
+ //单库全表
+ JdbcLoader loader = new JdbcLoader(ds);
+ loader.options(opt -> opt.loadOptions("zt", null));
+ List docs = loader.load();
+ System.out.println(docs.size());
+ assert docs.size() > 0;
+ }
+
+ @Test
+ public void test3() throws Exception {
+ //单库单表
+ JdbcLoader loader = new JdbcLoader(ds);
+ loader.options(opt -> opt.loadOptions("zt", "location"));
+ List docs = loader.load();
+ System.out.println(docs);
+ System.out.println(docs.size());
+ assert docs.size() > 0;
+ }
+}
\ No newline at end of file
--
Gitee