Skip to content

Commit 893aa23

Browse files
authored
Merge pull request #172 from moshowgame/feature_template_update
Feature template update
2 parents 75d880e + 685b952 commit 893aa23

File tree

11 files changed

+273
-105
lines changed

11 files changed

+273
-105
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ ResultVo.error(message);
244244
# Update Logs
245245
| 更新日期 | 更新内容 |
246246
|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
247+
| 2025.12.09 | 优化Mybatis和Mybatis-Plus模板 |
247248
| 2025.12.08 | 引入单元测试和JaCoCo测试覆盖率,优化代码覆盖率 [UNIT_TEST_DOCUMENT.md](UNIT_TEST_DOCUMENT.md) |
248249
| 2025.12.07 | 后端重构优化![REFACTORING_DOCUMENT.md](REFACTORING_DOCUMENT.md) ;目录结构调整! |
249250
| 2025.09.14 | 优化JSqlParser Engine(DDL Create SQL和Select SQL),适配更高级复杂的SQL |

src/main/java/com/softdev/system/generator/service/impl/parser/SqlParserServiceImpl.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,11 @@ public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception
233233
String classComment = null;
234234
//mysql是comment=,pgsql/oracle是comment on table,
235235
//2020-05-25 优化表备注的获取逻辑
236-
if (tableSql.contains("comment=") || tableSql.contains("comment on table")) {
237-
int ix = tableSql.lastIndexOf("comment=");
236+
if (tableSql.toLowerCase().contains("comment=") || tableSql.toLowerCase().contains("comment on table")) {
237+
int ix = tableSql.toLowerCase().lastIndexOf("comment=");
238238
String classCommentTmp = (ix > -1) ?
239239
tableSql.substring(ix + 8).trim() :
240-
tableSql.substring(tableSql.lastIndexOf("comment on table") + 17).trim();
240+
tableSql.substring(tableSql.toLowerCase().lastIndexOf("comment on table") + 17).trim();
241241
if (classCommentTmp.contains("`")) {
242242
classCommentTmp = classCommentTmp.substring(classCommentTmp.indexOf("`") + 1);
243243
classCommentTmp = classCommentTmp.substring(0, classCommentTmp.indexOf("`"));
@@ -256,11 +256,11 @@ public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception
256256
List<FieldInfo> fieldList = new ArrayList<FieldInfo>();
257257

258258
// 正常( ) 内的一定是字段相关的定义。
259-
String fieldListTmp = tableSql.substring(tableSql.indexOf("(") + 1, tableSql.lastIndexOf(")"));
259+
String fieldListTmp = tableSql.substring(tableSql.indexOf("(") + 1, tableSql.lastIndexOf(")")).trim();
260260

261261
// 匹配 comment,替换备注里的小逗号, 防止不小心被当成切割符号切割
262262
String commentPattenStr1 = "comment `(.*?)\\`";
263-
Matcher matcher1 = Pattern.compile(commentPattenStr1).matcher(fieldListTmp);
263+
Matcher matcher1 = Pattern.compile(commentPattenStr1).matcher(fieldListTmp.toLowerCase());
264264
while (matcher1.find()) {
265265

266266
String commentTmp = matcher1.group();
@@ -305,18 +305,20 @@ public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception
305305
// 2019-2-22 zhengkai 要在条件中使用复杂的表达式
306306
// 2019-4-29 zhengkai 优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 )
307307
// 2020-10-20 zhengkai 优化对fulltext/index关键字的处理(感谢@WEGFan的反馈)
308+
// 2025-12-07 zhengkai 修复对primary key的处理
308309
boolean notSpecialFlag = (
309310
!columnLine.contains("key ")
310-
&& !columnLine.contains("constraint")
311-
&& !columnLine.contains(" using ")
312-
&& !columnLine.contains("unique ")
313-
&& !columnLine.contains("fulltext ")
314-
&& !columnLine.contains("index ")
315-
&& !columnLine.contains("pctincrease")
316-
&& !columnLine.contains("buffer_pool")
317-
&& !columnLine.contains("tablespace")
318-
&& !(columnLine.contains("primary ") && columnLine.indexOf("storage") + 3 > columnLine.indexOf("("))
319-
&& !(columnLine.contains("primary ") && i > 3)
311+
&& !columnLine.toLowerCase().contains("constraint")
312+
&& !columnLine.toLowerCase().contains(" using ")
313+
&& !columnLine.toLowerCase().contains("unique ")
314+
&& !columnLine.toLowerCase().contains("fulltext ")
315+
&& !columnLine.toLowerCase().contains("index ")
316+
&& !columnLine.toLowerCase().contains("pctincrease")
317+
&& !columnLine.toLowerCase().contains("buffer_pool")
318+
&& !columnLine.toLowerCase().contains("tablespace")
319+
&& !(columnLine.toLowerCase().contains("primary ") && columnLine.indexOf("storage") + 3 > columnLine.indexOf("("))
320+
&& !(columnLine.toLowerCase().contains("primary ") && i > 3)
321+
&& !columnLine.toLowerCase().contains("primary key")
320322
);
321323

322324
if (notSpecialFlag) {
@@ -349,7 +351,10 @@ public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception
349351
} else {
350352
fieldName = columnName;
351353
}
352-
columnLine = columnLine.substring(columnLine.indexOf("`") + 1).trim();
354+
// 修复Oracle字段名不带引号的情况
355+
if (columnLine.contains("`")) {
356+
columnLine = columnLine.substring(columnLine.indexOf("`") + 1).trim();
357+
}
353358
//2025-03-16 修复由于类型大写导致无法转换的问题
354359
String mysqlType = columnLine.split("\\s+")[1].toLowerCase();
355360
if(mysqlType.contains("(")){
@@ -372,23 +377,23 @@ public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception
372377
}
373378
// field comment,MySQL的一般位于field行,而pgsql和oralce多位于后面。
374379
String fieldComment = null;
375-
if (tableSql.contains("comment on column") && (tableSql.contains("." + columnName + " is ") || tableSql.contains(".`" + columnName + "` is"))) {
380+
if (tableSql.toLowerCase().contains("comment on column") && (tableSql.toLowerCase().contains("." + columnName + " is ") || tableSql.toLowerCase().contains(".`" + columnName + "` is"))) {
376381
//新增对pgsql/oracle的字段备注支持
377382
//COMMENT ON COLUMN public.check_info.check_name IS '检查者名称';
378383
//2018-11-22 lshz0088 正则表达式的点号前面应该加上两个反斜杠,否则会认为是任意字符
379384
//2019-4-29 zhengkai 优化对oracle注释comment on column的支持(@liukex)
380-
tableSql = tableSql.replaceAll(".`" + columnName + "` is", "." + columnName + " is");
381-
Matcher columnCommentMatcher = Pattern.compile("\\." + columnName + " is `").matcher(tableSql);
385+
tableSql = tableSql.toLowerCase().replaceAll(".`" + columnName + "` is", "." + columnName + " is");
386+
Matcher columnCommentMatcher = Pattern.compile("\\." + columnName + " is `").matcher(tableSql.toLowerCase());
382387
fieldComment = columnName;
383388
while (columnCommentMatcher.find()) {
384389
String columnCommentTmp = columnCommentMatcher.group();
385390
//System.out.println(columnCommentTmp);
386391
fieldComment = tableSql.substring(tableSql.indexOf(columnCommentTmp) + columnCommentTmp.length()).trim();
387392
fieldComment = fieldComment.substring(0, fieldComment.indexOf("`")).trim();
388393
}
389-
} else if (columnLine.contains(" comment")) {
394+
} else if (columnLine.toLowerCase().contains(" comment")) {
390395
//20200518 zhengkai 修复包含comment关键字的问题
391-
String commentTmp = columnLine.substring(columnLine.lastIndexOf("comment") + 7).trim();
396+
String commentTmp = columnLine.toLowerCase().substring(columnLine.toLowerCase().lastIndexOf("comment") + 7).trim();
392397
// '用户ID',
393398
if (commentTmp.contains("`") || commentTmp.indexOf("`") != commentTmp.lastIndexOf("`")) {
394399
commentTmp = commentTmp.substring(commentTmp.indexOf("`") + 1, commentTmp.lastIndexOf("`"));
@@ -398,6 +403,9 @@ public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception
398403
commentTmp = commentTmp.substring(0, commentTmp.lastIndexOf(")") + 1);
399404
}
400405
fieldComment = commentTmp;
406+
} else if (columnLine.contains("--")) {
407+
// 支持Oracle风格的注释(--)
408+
fieldComment = columnLine.substring(columnLine.indexOf("--") + 2).trim();
401409
} else {
402410
//修复comment不存在导致报错的问题
403411
fieldComment = columnName;
@@ -416,10 +424,10 @@ public ClassInfo processTableIntoClassInfo(ParamInfo paramInfo) throws Exception
416424
}
417425
}
418426

419-
if (fieldList.size() < 1) {
427+
if (fieldList.isEmpty()) {
420428
throw new Exception("表结构分析失败,请检查语句或者提交issue给我");
421429
}
422-
430+
//build Class Info
423431
ClassInfo codeJavaInfo = new ClassInfo();
424432
codeJavaInfo.setTableName(tableName);
425433
codeJavaInfo.setClassName(className);

src/main/java/com/softdev/system/generator/util/mysqlJavaTypeUtil.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public final class mysqlJavaTypeUtil {
2727
//字符串
2828
mysqlJavaTypeMap.put("char","String");
2929
mysqlJavaTypeMap.put("varchar","String");
30+
mysqlJavaTypeMap.put("varchar2","String"); // Oracle类型
3031
mysqlJavaTypeMap.put("tinytext","String");
3132
mysqlJavaTypeMap.put("text","String");
3233
mysqlJavaTypeMap.put("mediumtext","String");
@@ -35,6 +36,8 @@ public final class mysqlJavaTypeUtil {
3536
mysqlJavaTypeMap.put("date","Date");
3637
mysqlJavaTypeMap.put("datetime","Date");
3738
mysqlJavaTypeMap.put("timestamp","Date");
39+
// 数字类型 - Oracle增强
40+
mysqlJavaTypeMap.put("number","BigDecimal"); // Oracle的NUMBER类型默认映射为BigDecimal,支持精度
3841

3942

4043
mysqlSwaggerTypeMap.put("bigint","integer");
@@ -46,7 +49,10 @@ public final class mysqlJavaTypeUtil {
4649
mysqlSwaggerTypeMap.put("boolean","boolean");
4750
mysqlSwaggerTypeMap.put("float","number");
4851
mysqlSwaggerTypeMap.put("double","number");
49-
mysqlSwaggerTypeMap.put("decimal","Double");
52+
mysqlSwaggerTypeMap.put("decimal","number");
53+
// Oracle类型
54+
mysqlSwaggerTypeMap.put("varchar2","string");
55+
mysqlSwaggerTypeMap.put("number","number");
5056
}
5157

5258
public static HashMap<String, String> getMysqlJavaTypeMap() {

src/main/resources/templates/code-generator/mybatis-plus/pluscontroller.ftl

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ public class ${classInfo.className}Controller {
4343
if(old${classInfo.className}!=null){
4444
${classInfo.className?uncap_first}Mapper.updateById(${classInfo.className?uncap_first});
4545
}else{
46-
if(${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_name",${classInfo.className?uncap_first}.get${classInfo.className}Name()))!=null){
47-
return ${returnUtilFailure}("保存失败,名字重复");
48-
}
49-
${classInfo.className?uncap_first}.setCreateTime(new Date());
50-
${classInfo.className?uncap_first}Mapper.insert(${classInfo.className?uncap_first});
46+
if(${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_name",${classInfo.className?uncap_first}.get${classInfo.className}Name()))!=null){
47+
return ${returnUtilFailure}("保存失败,名字重复");
48+
}
49+
${classInfo.className?uncap_first}.setCreateTime(new Date());
50+
${classInfo.className?uncap_first}Mapper.insert(${classInfo.className?uncap_first});
5151
}
5252
return ${returnUtilSuccess}("保存成功");
5353
}
@@ -83,43 +83,51 @@ public class ${classInfo.className}Controller {
8383
* 自动分页查询
8484
*/
8585
@PostMapping("/list")
86-
public Object list(String searchParams,
87-
@RequestParam(required = false, defaultValue = "0") int page,
88-
@RequestParam(required = false, defaultValue = "10") int limit) {
86+
public Object list(@RequestBody ${classInfo.className} ${classInfo.className?uncap_first},@RequestParam(required = false, defaultValue = "0") int page,@RequestParam(required = false, defaultValue = "10") int limit) {
8987
log.info("page:"+page+"-limit:"+limit+"-json:"+ JSON.toJSONString(searchParams));
9088
//分页构造器
9189
Page<${classInfo.className}> buildPage = new Page<${classInfo.className}>(page,limit);
9290
//条件构造器
9391
QueryWrapper<${classInfo.className}> queryWrapper = new QueryWrapper<${classInfo.className}>();
94-
if(StringUtils.isNotEmpty(searchParams)&&JSON.isValid(searchParams)) {
95-
${classInfo.className} ${classInfo.className?uncap_first} = JSON.parseObject(searchParams, ${classInfo.className}.class);
96-
queryWrapper.eq(StringUtils.isNoneEmpty(${classInfo.className?uncap_first}.get${classInfo.className}Name()), "${classInfo.className?uncap_first}_name", ${classInfo.className?uncap_first}.get${classInfo.className}Name());
92+
if(JSON.stringify(${classInfo.className?uncap_first}).length()>2) {
93+
//自行删除不需要动态查询字段
94+
queryWrapper.
95+
<#list classInfo.fieldList as fieldItem>
96+
eq(StringUtils.isNoneEmpty(${classInfo.className?uncap_first}.get${fieldItem.fieldName}()), "${fieldItem.fieldName}", ${classInfo.className?uncap_first}.get${fieldItem.fieldName}())
97+
</#list>
98+
;
9799
}
98100
//执行分页
99101
IPage<${classInfo.className}> pageList = ${classInfo.className?uncap_first}Mapper.selectPage(buildPage, queryWrapper);
100102
//返回结果
101103
return ${returnUtil}.PAGE(pageList.getRecords(),pageList.getTotal());
102104
}
105+
103106
/**
104-
* 手工分页查询(按需使用)
107+
* 动态条件手工分页查询
108+
* 根据对象属性自动构建条件,如果字段有值则进行分页+指定条件查询,否则仅进行分页查询
105109
*/
106-
/*@PostMapping("/list2")
107-
public Object list2(String searchParams,
108-
@RequestParam(required = false, defaultValue = "0") int page,
109-
@RequestParam(required = false, defaultValue = "10") int limit) {
110-
log.info("searchParams:"+ JSON.toJSONString(searchParams));
111-
//通用模式
112-
${classInfo.className} queryParamDTO = JSON.parseObject(searchParams, ${classInfo.className}.class);
113-
//专用DTO模式
114-
//QueryParamDTO queryParamDTO = JSON.parseObject(searchParams, QueryParamDTO.class);
115-
//queryParamDTO.setPage((page - 1)* limit);
116-
//queryParamDTO.setLimit(limit);
117-
//(page - 1) * limit, limit
118-
List<${classInfo.className}> itemList = ${classInfo.className?uncap_first}Mapper.pageAll(queryParamDTO,(page - 1)* limit,limit);
119-
Integer itemCount = ${classInfo.className?uncap_first}Mapper.countAll(queryParamDTO);
110+
@PostMapping("/list")
111+
public Object list(String searchParams, @RequestParam(required = false, defaultValue = "1") int page, @RequestParam(required = false, defaultValue = "10") int limit) {
112+
log.info("page:"+page+"-limit:"+limit+"-json:"+ JSON.toJSONString(searchParams));
113+
114+
// 分页参数处理
115+
int offset = (page - 1) * limit;
116+
117+
// 查询参数处理
118+
${classInfo.className} queryParamDTO = new ${classInfo.className}();
119+
if(StringUtils.isNotEmpty(searchParams) && JSON.isValid(searchParams)) {
120+
queryParamDTO = JSON.parseObject(searchParams, ${classInfo.className}.class);
121+
}
122+
123+
// 使用动态条件查询
124+
List<${classInfo.className}> itemList = ${classInfo.className?uncap_first}Mapper.selectPageByCondition(queryParamDTO, offset, limit);
125+
int itemCount = ${classInfo.className?uncap_first}Mapper.selectPageByConditionCount(queryParamDTO);
126+
120127
//返回结果
121-
return ${returnUtilSuccess}.PAGE(itemList,itemCount);
122-
}*/
128+
return ${returnUtil}.PAGE(itemList, itemCount);
129+
}
130+
123131
@GetMapping("/list")
124132
public ModelAndView listPage(){
125133
return new ModelAndView("${classInfo.className?uncap_first}-list");
@@ -132,16 +140,16 @@ public class ${classInfo.className}Controller {
132140
}
133141

134142
/**
135-
* 发布/暂停(如不需要请屏蔽)
143+
* 激活/停用(如不需要请屏蔽)
136144
*/
137-
@PostMapping("/publish")
138-
public Object publish(int id,Integer status){
145+
@PostMapping("/active")
146+
public Object active(int id,Integer status){
139147
${classInfo.className} ${classInfo.className?uncap_first} = ${classInfo.className?uncap_first}Mapper.selectOne(new QueryWrapper<${classInfo.className}>().eq("${classInfo.className?uncap_first}_id",id));
140148
if(${classInfo.className?uncap_first}!=null){
141149
${classInfo.className?uncap_first}.setUpdateTime(new Date());
142150
${classInfo.className?uncap_first}.setStatus(status);
143151
${classInfo.className?uncap_first}Mapper.updateById(${classInfo.className?uncap_first});
144-
return ${returnUtilSuccess}((status==1)?"已发布":"已暂停");
152+
return ${returnUtilSuccess}((status==1)?"已激活":"已停用");
145153
}else if(status.equals(${classInfo.className?uncap_first}.getStatus())){
146154
return ${returnUtilFailure}("状态不正确");
147155
}else{
@@ -150,13 +158,13 @@ public class ${classInfo.className}Controller {
150158
}
151159

152160
/**
153-
* 执行(如不需要请屏蔽)
161+
* 测试(如不需要请屏蔽)
154162
*/
155-
@PostMapping("/execute")
156-
public Object execute(){
163+
@GetMapping("/test")
164+
public Object test(){
157165
return ${returnUtilSuccess};
158166
}
159-
}
167+
160168
}
161169

162170

src/main/resources/templates/code-generator/mybatis-plus/plusentity.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import io.swagger.v3.oas.annotations.media.Schema;</#if>
1616
* @date ${.now?string('yyyy-MM-dd')}
1717
*/
1818
<#if isLombok?exists && isLombok==true>@Data</#if><#if isSwagger?exists && isSwagger==true>
19-
@Schema"${classInfo.classComment}")</#if>
19+
@Schema(description = "${classInfo.classComment}")</#if>
2020
public class ${classInfo.className} implements Serializable {
2121

2222
private static final long serialVersionUID = 1L;

0 commit comments

Comments
 (0)