update 执行分页自定义SQL查询,返回数据List

master
yinq 4 months ago
parent 3274c2904d
commit 87ec4772da

@ -145,5 +145,14 @@ public class SysDatabaseLinkController extends BaseController {
return R.ok(sysDatabaseLinkService.querySql(linkId, sql));
}
/**
* SQLList
*/
@SaCheckPermission("system:databaseLink:query")
@PostMapping("/queryPageSql")
public R<Map<String, Object>> queryPageSql(@RequestBody SysDatabaseLinkBo bo) {
return R.ok(sysDatabaseLinkService.queryPageSql(bo));
}
}

@ -90,5 +90,19 @@ public class SysDatabaseLinkBo extends BaseEntity {
*/
private String remark;
/**
*
*/
private Integer pageSize;
/**
*
*/
private Integer pageNum;
/**
* SQL
*/
private String sql;
}

@ -92,4 +92,10 @@ public interface ISysDatabaseLinkService {
* SQLList
*/
List<LinkedHashMap<String, Object>> querySql(Long linkId, String sql);
/**
* SQLList
*/
Map<String, Object> queryPageSql(SysDatabaseLinkBo bo);
}

@ -341,4 +341,138 @@ public class SysDatabaseLinkServiceImpl implements ISysDatabaseLinkService {
}
return resultList;
}
/**
* SQLList
*/
@Override
public Map<String, Object> queryPageSql(SysDatabaseLinkBo bo) {
Long linkId = bo.getLinkId();
String sql = bo.getSql();
Integer pageNum = bo.getPageNum();
Integer pageSize = bo.getPageSize();
// 参数校验
if (pageNum == null || pageNum < 1) {
pageNum = 1;
}
if (pageSize == null || pageSize < 1) {
pageSize = 10;
}
// SQL校验
String sqlTrim = sql.trim().toLowerCase(Locale.ROOT);
if (!(sqlTrim.startsWith("select") || sqlTrim.startsWith("with"))) {
throw new RuntimeException("只允许执行查询SELECT/CTE语句");
}
// 获取数据库连接信息
SysDatabaseLink link = baseMapper.selectById(linkId);
if (link == null) {
throw new RuntimeException("数据库连接信息不存在");
}
String url = link.getJdbcUrl();
String username = link.getUsername();
String password = link.getPassword();
String driverClass = link.getDriverClass();
List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
long total = 0;
try {
Class.forName(driverClass);
// 获取数据库类型
String dbType = getDatabaseType(url);
// 构建分页SQL
String pageSql = buildPageSql(sql, pageNum, pageSize, dbType);
String countSql = buildCountSql(sql, dbType);
try (Connection conn = DriverManager.getConnection(url, username, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(pageSql)) {
// 获取分页数据
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
while (rs.next()) {
LinkedHashMap<String, Object> row = new LinkedHashMap<>();
for (int i = 1; i <= columnCount; i++) {
row.put(metaData.getColumnLabel(i), rs.getObject(i));
}
resultList.add(row);
}
// 获取总记录数
try (ResultSet countRs = stmt.executeQuery(countSql)) {
if (countRs.next()) {
total = countRs.getLong(1);
}
}
}
} catch (Exception e) {
throw new RuntimeException("SQL执行失败: " + e.getMessage(), e);
}
// 构建分页结果
Map<String, Object> result = new LinkedHashMap<>();
result.put("rows", resultList);
result.put("total", total);
result.put("pageNum", pageNum);
result.put("pageSize", pageSize);
result.put("pages", (int) Math.ceil((double) total / pageSize));
return result;
}
/**
* SQL
*/
private String buildPageSql(String originalSql, int pageNum, int pageSize, String dbType) {
int offset = (pageNum - 1) * pageSize;
switch (dbType.toLowerCase()) {
case "mysql":
return originalSql + " LIMIT " + offset + "," + pageSize;
case "oracle":
return "SELECT * FROM (SELECT a.*, ROWNUM rn FROM (" + originalSql +
") a WHERE ROWNUM <= " + (offset + pageSize) + ") WHERE rn > " + offset;
case "postgresql":
case "sqlserver":
return originalSql + " OFFSET " + offset + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
default:
throw new RuntimeException("不支持的数据库类型: " + dbType);
}
}
/**
* SQL
*/
private String buildCountSql(String originalSql, String dbType) {
// 移除原有ORDER BY子句计数查询不需要排序
String sqlWithoutOrder = originalSql.replaceAll("(?i)\\s+ORDER\\s+BY\\s+[^)]+$", "");
return "SELECT COUNT(1) FROM (" + sqlWithoutOrder + ") temp_count_table";
}
/**
* JDBC URL
*/
private String getDatabaseType(String jdbcUrl) {
if (jdbcUrl.contains(":mysql:")) {
return "mysql";
} else if (jdbcUrl.contains(":oracle:")) {
return "oracle";
} else if (jdbcUrl.contains(":postgresql:")) {
return "postgresql";
} else if (jdbcUrl.contains(":sqlserver:") || jdbcUrl.contains(":microsoft:")) {
return "sqlserver";
} else {
throw new RuntimeException("无法识别的数据库类型: " + jdbcUrl);
}
}
}

Loading…
Cancel
Save