DynamicNl2SqlService.java
3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package com.xly.service;
import com.alibaba.fastjson2.JSON;
import com.xly.agent.DynamicTableNl2SqlAiAgent;
import com.xly.entity.DynamicNl2SqlRequest;
import com.xly.entity.Nl2SqlResult;
import com.xly.util.SqlExecuteUtil;
import com.xly.util.SqlValidateUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* 动态表结构的NL2SQL业务服务层
* 适配任意表结构、多业务场景
*/
@Service
public class DynamicNl2SqlService {
private static final Logger log = LoggerFactory.getLogger(DynamicNl2SqlService.class);
@Resource
private DynamicTableNl2SqlAiAgent dynamicTableNl2SqlAiAgent;
@Resource
private SqlExecuteUtil sqlExecuteUtil;
/**
* 执行动态表结构的NL2SQL全流程
* @param request 动态表结构请求(含db名、表名、表结构、用户问题)
* @return 结构化NL2SQL结果
*/
public Nl2SqlResult executeDynamicNl2Sql(DynamicNl2SqlRequest request) {
log.info("开始执行动态表结构NL2SQL流程,请求:{}", JSON.toJSONString(request));
// 1. 入参非空校验(重点校验表结构和用户问题)
if (request.getTableStruct() == null || request.getTableStruct().trim().isEmpty()
|| request.getQuestion() == null || request.getQuestion().trim().isEmpty()) {
throw new IllegalArgumentException("表结构和用户查询问题不能为空");
}
// 补全默认值(如数据库名默认取配置中的值)
String tableNames = request.getTableNames() == null ? "" : request.getTableNames().trim();
String rawSql = "select * from " + tableNames + " where 1=1 ";
// 2. 调用AI服务生成SQL(传入所有动态参数)
// String rawSql = dynamicTableNl2SqlAiAgent.generateMysqlSql(
// tableNames,
// request.getTableStruct().trim(),
// request.getQuestion().trim()
// );
// if (rawSql == null || rawSql.trim().isEmpty()) {
// throw new SqlGenerateException("AI服务生成SQL失败,返回结果为空");
// }
// log.info("AI服务生成原始SQL:{}", rawSql);
// 3. 清理SQL多余符号 + 生产级强校验(核心安全保障,不可省略)
String cleanSql = SqlValidateUtil.cleanSqlSymbol(rawSql);
SqlValidateUtil.validateMysqlSql(cleanSql);
log.info("SQL清理并强校验通过,可执行SQL:{}", cleanSql);
// 4. 执行SQL获取结构化结果
List<Map<String, Object>> sqlResult = sqlExecuteUtil.executeSelectSql(cleanSql);
log.info("MySQL SQL执行完成,返回结果条数:{}", sqlResult.size());
String resultExplain ="";
// 5. 调用AI服务生成自然语言解释(传入表结构,让解释更贴合业务)
String resultJson = JSON.toJSONString(sqlResult);
// String resultExplain = dynamicTableNl2SqlAiAgent.explainSqlResult(
// request.getQuestion().trim(),
// cleanSql,
// request.getTableStruct().trim(),
// resultJson
// );
// 6. 封装结果返回
Nl2SqlResult nl2SqlResult = new Nl2SqlResult();
nl2SqlResult.setGenerateSql(cleanSql);
nl2SqlResult.setSqlResult(sqlResult);
nl2SqlResult.setResultExplain(resultExplain);
log.info("动态表结构NL2SQL流程执行完成");
return nl2SqlResult;
}
}