引入 Velocity 模板引擎,生成代码~
This commit is contained in:
parent
0be7138eef
commit
1bea2ea7f8
7
pom.xml
7
pom.xml
|
@ -54,6 +54,7 @@
|
|||
<mapstruct.version>1.4.1.Final</mapstruct.version>
|
||||
<hutool.version>5.5.6</hutool.version>
|
||||
<easyexcel.verion>2.2.7</easyexcel.verion>
|
||||
<velocity.version>2.2</velocity.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
|
@ -221,6 +222,12 @@
|
|||
<version>${easyexcel.verion}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>${velocity.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@ import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
|
|||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* 字典类型表
|
||||
|
@ -16,6 +15,10 @@ import lombok.EqualsAndHashCode;
|
|||
@TableName("sys_dict_type")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysDictTypeDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,18 @@ package cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen;
|
|||
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenColumnDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ToolCodegenColumnMapper extends BaseMapperX<ToolCodegenColumnDO> {
|
||||
|
||||
default List<ToolCodegenColumnDO> selectByTableId(Long tableId) {
|
||||
return selectList(new QueryWrapper<ToolCodegenColumnDO>()
|
||||
.eq("table_id", tableId)
|
||||
.orderByAsc("ordinal_position"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -95,16 +95,19 @@ public class ToolCodegenColumnDO extends BaseDO {
|
|||
*/
|
||||
private Boolean updateOperation;
|
||||
/**
|
||||
* 是否为 List 查询操作的返回字段
|
||||
* 是否为 List 查询操作的字段
|
||||
*/
|
||||
private Boolean listOperationResult;
|
||||
private Boolean listOperation;
|
||||
/**
|
||||
* List 查询操作的条件类型
|
||||
* 如果为空,则说明不是查询字段
|
||||
*
|
||||
* 枚举 {@link ToolCodegenColumnListConditionEnum}
|
||||
*/
|
||||
private String listOperationCondition;
|
||||
/**
|
||||
* 是否为 List 查询操作的返回字段
|
||||
*/
|
||||
private Boolean listOperationResult;
|
||||
|
||||
// ========== UI 相关字段 ==========
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
||||
|
||||
import cn.hutool.extra.template.TemplateConfig;
|
||||
import cn.hutool.extra.template.TemplateEngine;
|
||||
import cn.hutool.extra.template.TemplateUtil;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenColumnDO;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenTableDO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 代码生成的引擎,用于具体生成代码
|
||||
* 目前基于 {@link org.apache.velocity.app.Velocity} 模板引擎实现
|
||||
*
|
||||
* 考虑到 Java 模板引擎的框架非常多,Freemarker、Velocity、Thymeleaf 等等,所以我们采用 hutool 封装的 {@link cn.hutool.extra.template.Template} 抽象
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
public class ToolCodegenEngine {
|
||||
|
||||
/**
|
||||
* 模板引擎,由 hutool 实现
|
||||
*/
|
||||
private final TemplateEngine templateEngine;
|
||||
|
||||
public ToolCodegenEngine() {
|
||||
TemplateConfig config = new TemplateConfig();
|
||||
config.setResourceMode(TemplateConfig.ResourceMode.CLASSPATH);
|
||||
this.templateEngine = TemplateUtil.createEngine(config);
|
||||
}
|
||||
|
||||
public void execute(ToolCodegenTableDO table, List<ToolCodegenColumnDO> columns) {
|
||||
Map<String, Object> bindingMap = new HashMap<>();
|
||||
bindingMap.put("table", table);
|
||||
bindingMap.put("columns", columns);
|
||||
String result = templateEngine.getTemplate("codegen/dal/do.vm").render(bindingMap);
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
}
|
|
@ -5,16 +5,9 @@ import cn.hutool.core.map.MapUtil;
|
|||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.dashboard.modules.tool.convert.codegen.CodegenConvert;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolCodegenColumnMapper;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolCodegenTableMapper;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolInformationSchemaColumnMapper;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolInformationSchemaTableMapper;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenColumnDO;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenTableDO;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolInformationSchemaColumnDO;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolInformationSchemaTableDO;
|
||||
import cn.iocoder.dashboard.modules.tool.enums.codegen.ToolCodegenColumnHtmlTypeEnum;
|
||||
import cn.iocoder.dashboard.modules.tool.enums.codegen.ToolCodegenColumnListConditionEnum;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.*;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.*;
|
||||
import cn.iocoder.dashboard.modules.tool.enums.codegen.*;
|
||||
import cn.iocoder.dashboard.modules.tool.service.codegen.ToolCodegenService;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -60,8 +53,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
|||
/**
|
||||
* 新增操作,不需要传递的字段
|
||||
*/
|
||||
private static final Set<String> CREATE_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet(
|
||||
"id");
|
||||
private static final Set<String> CREATE_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet("id");
|
||||
/**
|
||||
* 修改操作,不需要传递的字段
|
||||
*/
|
||||
|
@ -69,11 +61,11 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
|||
/**
|
||||
* 列表操作的条件,不需要传递的字段
|
||||
*/
|
||||
private static final Set<String> LIST_OPERATION_CONDITION_COLUMN = Sets.newHashSet();
|
||||
private static final Set<String> LIST_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet("id");
|
||||
/**
|
||||
* 列表操作的结果,不需要返回的字段
|
||||
*/
|
||||
private static final Set<String> LIST_OPERATION_RESULT_COLUMN = Sets.newHashSet();
|
||||
private static final Set<String> LIST_OPERATION_RESULT_EXCLUDE_COLUMN = Sets.newHashSet();
|
||||
|
||||
/**
|
||||
* Java 类型与 MySQL 类型的映射关系
|
||||
|
@ -90,13 +82,15 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
|||
.build();
|
||||
|
||||
static {
|
||||
// 处理 OPERATION 相关的字段
|
||||
Arrays.stream(BaseDO.class.getDeclaredFields()).forEach(field -> {
|
||||
CREATE_OPERATION_EXCLUDE_COLUMN.add(field.getName());
|
||||
UPDATE_OPERATION_EXCLUDE_COLUMN.add(field.getName());
|
||||
LIST_OPERATION_CONDITION_COLUMN.add(field.getName());
|
||||
LIST_OPERATION_RESULT_COLUMN.add(field.getName());
|
||||
LIST_OPERATION_EXCLUDE_COLUMN.add(field.getName());
|
||||
LIST_OPERATION_RESULT_EXCLUDE_COLUMN.add(field.getName());
|
||||
});
|
||||
LIST_OPERATION_RESULT_COLUMN.remove("create_time"); // 创建时间,还是需要返回的
|
||||
LIST_OPERATION_EXCLUDE_COLUMN.remove("create_time"); // 创建时间,还是可能需要传递的
|
||||
LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("create_time"); // 创建时间,还是需要返回的
|
||||
}
|
||||
|
||||
@Resource
|
||||
|
@ -134,7 +128,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
|||
columns.forEach(column -> {
|
||||
initColumnDefault(column);
|
||||
column.setTableId(table.getId());
|
||||
codegenColumnMapper.insert(column);
|
||||
codegenColumnMapper.insert(column); // TODO 批量插入
|
||||
});
|
||||
return table.getId();
|
||||
}
|
||||
|
@ -150,10 +144,11 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
|||
table.setBusinessName(StrUtil.subAfter(table.getTableName(),
|
||||
'_', false)); // 第一个 _ 前缀的后面,作为 module 名字
|
||||
table.setBusinessName(StrUtil.toCamelCase(table.getBusinessName())); // 可能存在多个 _ 的情况,转换成驼峰
|
||||
table.setClassName(StrUtil.toCamelCase(table.getClassName())); // 驼峰
|
||||
table.setClassComment(StrUtil.subBefore(table.getClassComment(), // 去除结尾的表,作为类描述
|
||||
table.setClassName(StrUtil.upperFirst(StrUtil.toCamelCase(table.getTableName()))); // 驼峰 + 首字母大写
|
||||
table.setClassComment(StrUtil.subBefore(table.getTableComment(), // 去除结尾的表,作为类描述
|
||||
'表', true));
|
||||
table.setAuthor("芋艿"); // TODO 稍后改成创建人
|
||||
table.setTemplateType(ToolCodegenTemplateTypeEnum.CRUD.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +170,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
|||
column.setJavaField(StrUtil.toCamelCase(column.getColumnName()));
|
||||
// 处理 dictType 字段,暂无
|
||||
// 处理 javaType 字段
|
||||
String dbType = StrUtil.subBefore(column.getColumnName(), ')', false);
|
||||
String dbType = StrUtil.subBefore(column.getColumnType(), '(', false);
|
||||
javaTypeMappings.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().contains(dbType))
|
||||
.findFirst().ifPresent(entry -> column.setJavaType(entry.getKey()));
|
||||
|
@ -187,26 +182,29 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
|||
|
||||
private void processColumnOperation(ToolCodegenColumnDO column) {
|
||||
// 处理 createOperation 字段
|
||||
column.setCreateOperation(!CREATE_OPERATION_EXCLUDE_COLUMN.contains(column.getColumnName())
|
||||
&& !column.getPrimaryKey()); // 非主键
|
||||
column.setCreateOperation(!CREATE_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())
|
||||
&& !column.getPrimaryKey()); // 对于主键,创建时无需传递
|
||||
// 处理 updateOperation 字段
|
||||
column.setUpdateOperation(!UPDATE_OPERATION_EXCLUDE_COLUMN.contains(column.getColumnName()));
|
||||
// 处理 listOperationResult 字段
|
||||
column.setListOperationResult(!LIST_OPERATION_RESULT_COLUMN.contains(column.getColumnName()));
|
||||
// 处理 listOperationCondition 字段。默认设置为需要过滤的条件,手动进行取消
|
||||
if (!LIST_OPERATION_CONDITION_COLUMN.contains(column.getColumnName())
|
||||
&& !column.getPrimaryKey()) { // 非主键
|
||||
column.setUpdateOperation(!UPDATE_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())
|
||||
|| column.getPrimaryKey()); // 对于主键,更新时需要传递
|
||||
// 处理 listOperation 字段
|
||||
column.setListOperation(!LIST_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField())
|
||||
&& !column.getPrimaryKey()); // 对于主键,列表过滤不需要传递
|
||||
// 处理 listOperationCondition 字段
|
||||
columnListOperationConditionMappings.entrySet().stream()
|
||||
.filter(entry -> StrUtil.endWithIgnoreCase(column.getJavaField(), entry.getKey()))
|
||||
.findFirst().ifPresent(entry -> column.setListOperationCondition(entry.getValue().getCondition()));
|
||||
if (column.getListOperationCondition() == null) {
|
||||
column.setListOperationCondition(ToolCodegenColumnListConditionEnum.EQ.getCondition());
|
||||
}
|
||||
columnListOperationConditionMappings.entrySet().stream()
|
||||
.filter(entry -> StrUtil.endWithIgnoreCase(column.getColumnName(), entry.getKey()))
|
||||
.findFirst().ifPresent(entry -> column.setListOperationCondition(entry.getValue().getCondition()));
|
||||
// 处理 listOperationResult 字段
|
||||
column.setListOperationResult(!LIST_OPERATION_RESULT_EXCLUDE_COLUMN.contains(column.getJavaField()));
|
||||
}
|
||||
|
||||
private void processColumnUI(ToolCodegenColumnDO column) {
|
||||
// 基于后缀进行匹配
|
||||
columnHtmlTypeMappings.entrySet().stream()
|
||||
.filter(entry -> StrUtil.endWithIgnoreCase(column.getColumnName(), entry.getKey()))
|
||||
.filter(entry -> StrUtil.endWithIgnoreCase(column.getJavaField(), entry.getKey()))
|
||||
.findFirst().ifPresent(entry -> column.setHtmlType(entry.getValue().getType()));
|
||||
// 如果是 Boolean 类型时,设置为 radio 类型.
|
||||
// 其它类型,因为字段名可以相对保障,所以不进行处理。例如说 date 对应 datetime 类型.
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* ${table.description}
|
||||
*/
|
||||
@TableName("${table.tableName}")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ${table.tableName}DO extends BaseDO {
|
||||
|
||||
#foreach ($column in $columns)
|
||||
/**
|
||||
* ${column.columnComment}
|
||||
*/
|
||||
#if(${column.primaryKey} && ${column.javaType} != 'String')
|
||||
@TableId
|
||||
#end
|
||||
#if(${column.primaryKey} && ${column.javaType} == 'String')
|
||||
@TableId(type = IdType.INPUT)
|
||||
#end
|
||||
private ${column.javaType} ${column.javaField};
|
||||
#end
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
||||
|
||||
import cn.iocoder.dashboard.TestApplication;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolCodegenColumnMapper;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolCodegenTableMapper;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenColumnDO;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenTableDO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ToolCodegenEngineTest {
|
||||
|
||||
@Resource
|
||||
private ToolCodegenTableMapper codegenTableMapper;
|
||||
@Resource
|
||||
private ToolCodegenColumnMapper codegenColumnMapper;
|
||||
|
||||
@Resource
|
||||
private ToolCodegenEngine codegenEngine;
|
||||
|
||||
@Test
|
||||
public void testExecute() {
|
||||
ToolCodegenTableDO table = codegenTableMapper.selectById(8);
|
||||
List<ToolCodegenColumnDO> columns = codegenColumnMapper.selectByTableId(table.getId());
|
||||
codegenEngine.execute(table, columns);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
||||
|
||||
import cn.iocoder.dashboard.TestApplication;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
class ToolCodegenServiceImplTest {
|
||||
|
||||
@Resource
|
||||
private ToolCodegenServiceImpl toolCodegenService;
|
||||
|
||||
@Test
|
||||
public void tetCreateCodegenTable() {
|
||||
toolCodegenService.createCodegenTable("sys_dict_type");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue