@GetMapping(value = "/derby")
public RestResult<Object> derbyOps(@RequestParam(value = "sql") String sql) {
String selectSign = "select";
String limitSign = "ROWS FETCH NEXT";
String limit = " OFFSET 0 ROWS FETCH NEXT 1000 ROWS ONLY";
try {
if (PropertyUtil.isEmbeddedStorage()) {
LocalDataSourceServiceImpl dataSourceService = (LocalDataSourceServiceImpl) DynamicDataSource
.getInstance().getDataSource();
if (StringUtils.startsWithIgnoreCase(sql, selectSign)) {
if (!StringUtils.containsIgnoreCase(sql, limitSign)) {
sql += limit;
}
JdbcTemplate template = dataSourceService.getJdbcTemplate();
List<Map<String, Object>> result = template.queryForList(sql);
return RestResultUtils.success(result);
}
return RestResultUtils.failed("Only query statements are allowed to be executed");
}
return RestResultUtils.failed("The current storage mode is not Derby");
} catch (Exception e) {
return RestResultUtils.failed(e.getMessage());
}
这段代码定义了一个名为 derbyOps
的方法,该方法用于处理对 Derby 数据库的 SQL 查询操作。以下是详细解释:
-
方法签名:
@GetMapping(value = "/derby") public RestResult<Object> derbyOps(@RequestParam(value = "sql") String sql)
该方法通过
@GetMapping
注解映射到/derby
URL 路径。它接受一个String
类型的参数sql
,这是客户端传递过来的 SQL 查询语句。返回类型是RestResult<Object>
,表示操作结果。 -
定义常量:
String selectSign = "select"; String limitSign = "ROWS FETCH NEXT"; String limit = " OFFSET 0 ROWS FETCH NEXT 1000 ROWS ONLY";
定义了三个字符串常量:
selectSign
表示 SQL 查询语句的前缀;limitSign
表示分页查询的标识;limit
表示默认的分页查询语句,限制返回的记录条数。 -
开始 try 块:
try {
开始一个
try
块,用于捕获和处理可能发生的异常。 -
检查存储模式:
if (PropertyUtil.isEmbeddedStorage()) {
检查当前是否处于嵌入式存储模式。如果是,则继续执行后续操作。
-
获取数据源服务实例:
LocalDataSourceServiceImpl dataSourceService = (LocalDataSourceServiceImpl) DynamicDataSource.getInstance().getDataSource();
使用
DynamicDataSource.getInstance().getDataSource()
方法获取数据源服务实例,并将其转换为LocalDataSourceServiceImpl
类型。 -
检查 SQL 查询语句:
if (StringUtils.startsWithIgnoreCase(sql, selectSign)) {
检查传递的 SQL 语句是否以
select
开头(忽略大小写)。如果是,则继续执行后续操作。 -
添加分页查询语句:
if (!StringUtils.containsIgnoreCase(sql, limitSign)) { sql += limit; }
如果 SQL 语句中不包含分页查询的标识
limitSign
,则将默认的分页查询语句limit
添加到 SQL 语句的末尾,以限制返回的记录条数。 -
执行 SQL 查询:
JdbcTemplate template = dataSourceService.getJdbcTemplate(); List<Map<String, Object>> result = template.queryForList(sql); return RestResultUtils.success(result);
获取
JdbcTemplate
实例,使用queryForList
方法执行 SQL 查询,并将查询结果存储在result
列表中。然后,返回一个包含查询结果的成功RestResult
对象。 -
处理非查询语句:
return RestResultUtils.failed("Only query statements are allowed to be executed");
如果传递的 SQL 语句不是查询语句,则返回一个失败的
RestResult
对象,并包含错误信息 “Only query statements are allowed to be executed”。 -
处理非 Derby 存储模式:
return RestResultUtils.failed("The current storage mode is not Derby");
如果当前存储模式不是 Derby,则返回一个失败的
RestResult
对象,并包含错误信息 “The current storage mode is not Derby”。 -
捕获异常:
} catch (Exception e) { return RestResultUtils.failed(e.getMessage()); }
如果在执行过程中发生异常,捕获异常并返回一个失败的
RestResult
对象,包含异常的错误信息。
未开启鉴权或者1.4.0之前的nacos可以未认证直接访问/derby接口查询数据
issue链接:https://github.com/alibaba/nacos/issues/4463
修复链接:https://github.com/alibaba/nacos/pull/4517/files