magic-api查询sql返回复杂json
时间: 2025-05-25 13:19:15 浏览: 17
### 关于 magic-api 查询 SQL 返回复杂 JSON 的处理方式
在 `magic-api` 中,当查询 SQL 需要返回复杂的 JSON 数据结构时,可以通过自定义结果集的方式实现。以下是具体的解决思路:
#### 自定义返回结果
通过实现 `ResultProvider` 接口来自定义返回的结果格式。此接口允许开发者灵活控制最终的 JSON 输出形式[^1]。
```java
@Component
public class CustomJsonValueProvider implements ResultProvider {
/**
* 定义通用返回结果,默认返回 JsonBean 结构
*/
@Override
public Object buildResult(RequestEntity requestEntity, int code, String message, Object data) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("status", code);
resultMap.put("message", message);
// 判断数据类型并转换为复杂 JSON 格式
if (data instanceof List<?>) {
resultListToComplexJson((List<Map<String, Object>>) data, resultMap);
} else {
resultMap.put("data", data);
}
return resultMap;
}
private void resultListToComplexJson(List<Map<String, Object>> dataList, Map<String, Object> resultMap) {
List<Object> complexData = new ArrayList<>();
for (Map<String, Object> row : dataList) {
Map<String, Object> complexRow = new HashMap<>();
// 假设某些字段需要特殊处理(如嵌套对象)
for (Map.Entry<String, Object> entry : row.entrySet()) {
if ("nestedField".equals(entry.getKey())) {
complexRow.put("customNestedKey", parseNestedObject(entry.getValue()));
} else {
complexRow.put(entry.getKey(), entry.getValue());
}
}
complexData.add(complexRow);
}
resultMap.put("complexData", complexData);
}
private Object parseNestedObject(Object nestedValue) {
// 对嵌套对象进行解析逻辑
return nestedValue.toString(); // 示例简化处理
}
/**
* 处理分页结果
*/
@Override
public Object buildPageResult(RequestEntity requestEntity, Page page, long total, List<Map<String, Object>> data) {
Map<String, Object> pageResult = new HashMap<>();
pageResult.put("totalRecords", total);
// 转换分页数据为复杂 JSON 格式
List<Object> complexData = new ArrayList<>();
for (Map<String, Object> rowData : data) {
Map<String, Object> complexRow = new HashMap<>(rowData);
complexData.add(complexRow);
}
pageResult.put("rows", complexData);
return pageResult;
}
}
```
以上代码展示了如何将简单的数据库查询结果转化为更复杂的 JSON 格式。对于嵌套的对象或其他特定需求,可以在 `buildResult` 方法中加入额外的逻辑来满足业务场景的要求[^1]。
---
#### 使用 JSON 参数传递复杂数据
如果涉及复杂的数据操作,比如更新或删除多个记录,则可以采用 JSON 格式的参数传递[^2]。例如,在执行批量插入时,可设计如下 API 请求体:
```json
{
"items": [
{"name": "item1"},
{"name": "item2"}
]
}
```
对应的 SQL 插入语句可通过动态拼接完成:
```java
return db.insert("""
insert into test(name) values
${#foreach(items as item)}
(#${item.name})
${if not last} , ${endif}
${#end}
""");
```
这种方式能够有效应对多条记录的操作需求[^2]。
---
#### 综合示例:查询带嵌套关系的复杂 JSON
假设有一个表 `orders` 和关联表 `order_items`,希望返回订单及其对应的商品列表作为 JSON 格式输出。SQL 可写为:
```sql
SELECT o.id AS orderId,
o.customer_name AS customerName,
GROUP_CONCAT(CONCAT('{"itemId":"', oi.item_id, '","quantity":', oi.quantity, '}') SEPARATOR ',') AS itemsJson
FROM orders o
LEFT JOIN order_items oi ON o.id = oi.order_id
GROUP BY o.id;
```
随后在 Java 层面进一步加工这些原始数据,将其转为标准的 JSON 格式:
```java
@Override
public Object buildResult(RequestEntity requestEntity, int code, String message, Object data) {
List<Map<String, Object>> rawResults = (List<Map<String, Object>>) data;
List<Map<String, Object>> processedOrders = new ArrayList<>();
for (Map<String, Object> row : rawResults) {
Map<String, Object> order = new HashMap<>();
order.put("orderId", row.get("orderId"));
order.put("customerName", row.get("customerName"));
try {
// 将字符串形式的 JSON 数组解析为实际对象
List<Map<String, Object>> items = objectMapper.readValue(
"[" + row.get("itemsJson").toString() + "]",
new TypeReference<List<Map<String, Object>>>() {}
);
order.put("items", items);
} catch (Exception e) {
throw new RuntimeException("Failed to process itemsJson field.", e);
}
processedOrders.add(order);
}
return processedOrders;
}
```
上述代码实现了从数据库中的扁平化数据到层次化的 JSON 表达形式的转化过程。
---
### 注意事项
- **性能优化**:对于大数据量的情况,应考虑分页加载以及减少不必要的列读取。
- **安全性**:防止 SQL 注入攻击,推荐使用预编译语句或框架内置的安全机制。
- **扩展性**:保持代码模块化以便未来新增更多定制功能。
---
阅读全文
相关推荐


















