Skip to content

Commit 1c63658

Browse files
authored
feat: implement model-driven data API with dynamic SQL operations (#290)
1 parent 4222f27 commit 1c63658

File tree

13 files changed

+1247
-13
lines changed

13 files changed

+1247
-13
lines changed

app/src/main/java/com/tinyengine/it/TinyEngineApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
@SpringBootApplication
2626
@EnableAspectJAutoProxy
27-
@MapperScan("com.tinyengine.it.mapper")
27+
@MapperScan({"com.tinyengine.it.mapper","com.tinyengine.it.dynamic.dao"})
2828
public class TinyEngineApplication {
2929
/**
3030
* The entry point of application.
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package com.tinyengine.it.dynamic.controller;
2+
3+
import com.tinyengine.it.common.base.Result;
4+
import com.tinyengine.it.common.log.SystemControllerLog;
5+
import com.tinyengine.it.dynamic.dto.DynamicDelete;
6+
import com.tinyengine.it.dynamic.dto.DynamicInsert;
7+
import com.tinyengine.it.dynamic.dto.DynamicQuery;
8+
import com.tinyengine.it.dynamic.dto.DynamicUpdate;
9+
import com.tinyengine.it.dynamic.service.DynamicService;
10+
import io.swagger.v3.oas.annotations.Operation;
11+
import io.swagger.v3.oas.annotations.media.Content;
12+
import io.swagger.v3.oas.annotations.media.Schema;
13+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
14+
import io.swagger.v3.oas.annotations.tags.Tag;
15+
import jakarta.validation.Valid;
16+
import lombok.extern.slf4j.Slf4j;
17+
import org.springframework.beans.factory.annotation.Autowired;
18+
import org.springframework.validation.annotation.Validated;
19+
import org.springframework.web.bind.annotation.*;
20+
21+
import java.util.Map;
22+
23+
@Validated
24+
@Slf4j
25+
@RestController
26+
@RequestMapping("/platform-center/api")
27+
@Tag(name = "模型数据")
28+
public class ModelDataController {
29+
@Autowired
30+
private DynamicService dynamicService;
31+
32+
/**
33+
* 模型数据查询
34+
*
35+
* @return 返回值 all
36+
*/
37+
@Operation(summary = "模型数据查询", description = "模型数据查询", responses = {
38+
@ApiResponse(responseCode = "200", description = "返回信息",
39+
content = @Content(mediaType = "application/json",schema = @Schema(implementation = Map.class))),
40+
@ApiResponse(responseCode = "400", description = "请求失败")
41+
})
42+
@SystemControllerLog(description = "模型数据查询")
43+
@PostMapping("/model-data/queryApi")
44+
public Result<Map<String, Object>> query(@RequestBody @Valid DynamicQuery dto) {
45+
try {
46+
return Result.success(dynamicService.queryWithPage(dto));
47+
} catch (Exception e) {
48+
log.error("Query failed for table: {}", dto.getNameEn(), e);
49+
return Result.failed("Query operation failed");
50+
}
51+
52+
}
53+
54+
/**
55+
* 新增模型数据
56+
*
57+
* @return 返回值 map
58+
*/
59+
@Operation(summary = "新增模型数据", description = "新增模型数据", responses = {
60+
@ApiResponse(responseCode = "200", description = "返回信息",
61+
content = @Content(mediaType = "application/json",schema = @Schema(implementation = Map.class))),
62+
@ApiResponse(responseCode = "400", description = "请求失败")
63+
})
64+
@SystemControllerLog(description = "新增模型数据")
65+
@PostMapping("/model-data/insertApi")
66+
public Result<Map<String, Object> > insert(@RequestBody @Valid DynamicInsert dto) {
67+
try {
68+
return Result.success(dynamicService.insert(dto));
69+
} catch (Exception e) {
70+
log.error("insert failed for table: {}", dto.getNameEn(), e);
71+
return Result.failed("insert operation failed");
72+
}
73+
74+
}
75+
76+
/**
77+
* 更新模型数据
78+
*
79+
* @return 返回值 map
80+
*/
81+
@Operation(summary = "更新模型数据", description = "更新模型数据", responses = {
82+
@ApiResponse(responseCode = "200", description = "返回信息",
83+
content = @Content(mediaType = "application/json",schema = @Schema(implementation = Map.class))),
84+
@ApiResponse(responseCode = "400", description = "请求失败")
85+
})
86+
@SystemControllerLog(description = "更新模型数据")
87+
@PostMapping("/model-data/updateApi")
88+
public Result<Map<String, Object> > update(@RequestBody @Valid DynamicUpdate dto) {
89+
try {
90+
return Result.success(dynamicService.update(dto));
91+
} catch (Exception e) {
92+
log.error("updateApi failed for table: {}", dto.getNameEn(), e);
93+
return Result.failed("update operation failed");
94+
}
95+
96+
}
97+
/**
98+
* 刪除模型数据
99+
*
100+
* @return 返回值 map
101+
*/
102+
@Operation(summary = "刪除模型数据", description = "刪除模型数据", responses = {
103+
@ApiResponse(responseCode = "200", description = "返回信息",
104+
content = @Content(mediaType = "application/json",schema = @Schema(implementation = Map.class))),
105+
@ApiResponse(responseCode = "400", description = "请求失败")
106+
})
107+
@SystemControllerLog(description = "刪除模型数据")
108+
@PostMapping("/model-data/deleteApi")
109+
public Result<Map<String, Object> > delete(@RequestBody @Valid DynamicDelete dto) {
110+
try {
111+
return Result.success(dynamicService.delete(dto));
112+
} catch (Exception e) {
113+
log.error("deleteApi failed for table: {}", dto.getNameEn(), e);
114+
return Result.failed("delete operation failed");
115+
}
116+
}
117+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.tinyengine.it.dynamic.dao;
2+
3+
import org.apache.ibatis.jdbc.SQL;
4+
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
public class DynamicSqlProvider {
9+
10+
public String select(Map<String, Object> params) {
11+
String tableName = (String) params.get("tableName");
12+
List<String> fields = (List<String>) params.get("fields");
13+
Map<String, Object> conditions = (Map<String, Object>) params.get("conditions");
14+
Integer pageNum = (Integer) params.get("pageNum");
15+
Integer pageSize = (Integer) params.get("pageSize");
16+
String orderBy = (String) params.get("orderBy");
17+
String orderType = (String) params.get("orderType");
18+
19+
SQL sql = new SQL();
20+
21+
// 选择字段
22+
if (fields != null && !fields.isEmpty()) {
23+
for (String field : fields) {
24+
sql.SELECT(field);
25+
}
26+
} else {
27+
sql.SELECT("*");
28+
}
29+
30+
sql.FROM(tableName);
31+
32+
// 条件
33+
if (conditions != null && !conditions.isEmpty()) {
34+
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
35+
if (entry.getValue() != null) {
36+
sql.WHERE(entry.getKey() + " = #{conditions." + entry.getKey() + "}");
37+
}
38+
}
39+
}
40+
// 排序
41+
if (orderBy != null && !orderBy.isEmpty()) {
42+
sql.ORDER_BY(orderBy + " " + orderType);
43+
}
44+
45+
// 分页
46+
if (pageNum != null && pageSize != null) {
47+
return sql.toString() + " LIMIT " + (pageNum - 1) * pageSize + ", " + pageSize;
48+
}
49+
50+
return sql.toString();
51+
}
52+
53+
public String insert(Map<String, Object> params) {
54+
String tableName = (String) params.get("tableName");
55+
Map<String, Object> data = (Map<String, Object>) params.get("data");
56+
57+
SQL sql = new SQL();
58+
sql.INSERT_INTO(tableName);
59+
60+
if (data != null && !data.isEmpty()) {
61+
for (Map.Entry<String, Object> entry : data.entrySet()) {
62+
sql.VALUES(entry.getKey(), "#{data." + entry.getKey() + "}");
63+
}
64+
}
65+
66+
return sql.toString();
67+
}
68+
69+
public String update(Map<String, Object> params) {
70+
String tableName = (String) params.get("tableName");
71+
Map<String, Object> data = (Map<String, Object>) params.get("data");
72+
Map<String, Object> conditions = (Map<String, Object>) params.get("conditions");
73+
74+
SQL sql = new SQL();
75+
sql.UPDATE(tableName);
76+
77+
if (data != null && !data.isEmpty()) {
78+
for (Map.Entry<String, Object> entry : data.entrySet()) {
79+
sql.SET(entry.getKey() + " = #{data." + entry.getKey() + "}");
80+
}
81+
}
82+
83+
if (conditions != null && !conditions.isEmpty()) {
84+
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
85+
sql.WHERE(entry.getKey() + " = #{conditions." + entry.getKey() + "}");
86+
}
87+
}
88+
89+
return sql.toString();
90+
}
91+
92+
public String delete(Map<String, Object> params) {
93+
String tableName = (String) params.get("tableName");
94+
Map<String, Object> conditions = (Map<String, Object>) params.get("conditions");
95+
96+
SQL sql = new SQL();
97+
sql.DELETE_FROM(tableName);
98+
99+
if (conditions != null && !conditions.isEmpty()) {
100+
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
101+
sql.WHERE(entry.getKey() + " = #{conditions." + entry.getKey() + "}");
102+
}
103+
}
104+
105+
return sql.toString();
106+
}
107+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.tinyengine.it.dynamic.dao;
2+
3+
import com.alibaba.fastjson.JSONObject;
4+
import org.apache.ibatis.annotations.*;
5+
import org.springframework.stereotype.Repository;
6+
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
@Repository
11+
@Mapper
12+
public interface ModelDataDao {
13+
14+
@SelectProvider(type = DynamicSqlProvider.class, method = "select")
15+
List<JSONObject> select(Map<String, Object> params);
16+
17+
@InsertProvider(type = DynamicSqlProvider.class, method = "insert")
18+
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
19+
Long insert(Map<String, Object> params);
20+
21+
@UpdateProvider(type = DynamicSqlProvider.class, method = "update")
22+
Integer update(Map<String, Object> params);
23+
24+
@DeleteProvider(type = DynamicSqlProvider.class, method = "delete")
25+
Integer delete(Map<String, Object> params);
26+
27+
@Select("SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT " +
28+
"FROM INFORMATION_SCHEMA.COLUMNS " +
29+
"WHERE TABLE_NAME = #{tableName} AND TABLE_SCHEMA = DATABASE()")
30+
List<Map<String, Object>> getTableStructure(String tableName);
31+
}
32+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.tinyengine.it.dynamic.dto;
2+
3+
import lombok.Data;
4+
5+
import java.util.Map;
6+
7+
@Data
8+
public class DynamicDelete {
9+
private String nameEn;
10+
private Integer id;
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.tinyengine.it.dynamic.dto;
2+
3+
import lombok.Data;
4+
5+
import java.util.Map;
6+
@Data
7+
public class DynamicInsert {
8+
private String nameEn;
9+
private Map<String, Object> params; // 插入/更新数据
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.tinyengine.it.dynamic.dto;
2+
3+
import lombok.Data;
4+
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
@Data
9+
public class DynamicQuery {
10+
11+
private String nameEn; // 表名
12+
private String nameCh; // 表中文名
13+
private List<String> fields; // 查询字段
14+
private Map<String, Object> params; // 查询条件
15+
private Integer currentPage = 1; // 页码
16+
private Integer pageSize = 10; // 每页大小
17+
private String orderBy; // 排序字段
18+
private String orderType = "ASC"; // 排序方式
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.tinyengine.it.dynamic.dto;
2+
3+
import lombok.Data;
4+
5+
import java.util.Map;
6+
@Data
7+
public class DynamicUpdate {
8+
private String nameEn;
9+
private Map<String, Object> data;
10+
private Map<String, Object> params;// 查询条件
11+
}

0 commit comments

Comments
 (0)