项目中对于基础的crud代码实现和实体类等通用文件的构建,我们除了可以使用mabtis逆向工程,也可以使用模板引擎去完成。
-
根据实体类中的属性我们可以个性化配置自己的代码生成文件格式
-
在postman中(后续会追加网页端代码生成)根据自己的需求填写配置信息,一般必填的如下,分别有dsName:数据库名称,tableName:表名称,moduleName:模块名称,以及projectPath:代码生成的路径。可以根据需求追加实体类中的属性作为请求参数
-
当提示代码生成结束后则可以找到对应路径下,可以发现有生成的压缩包,同时也包含了被解压后生成的文件,所有不需要自己再次手动解压。
自动生成后的文件可在版本控制中查看。
以下来介绍如何简单搭建一个代码生成服务。
首先在pom文件导入依赖
<dependency>
<artifactId>velocity</artifactId>
<groupId>org.apache.velocity</groupId>
<version>1.7</version>
</dependency>
按照如下项目结构进行文件的编写
层级结构:
controller层:主要存放代码生成相关功能的对外访问路径
/**
* 代码生成器,代码生成模块
*/
@Component
@RestController
@RequiredArgsConstructor
@RequestMapping("/generator")
public class GeneratorController {
private final GeneratorService generatorService;
/**
* 列表
* @param tableName 参数集
* @param dsName 数据源编号
* @return 数据库表
*/
@GetMapping("/page")
public Result getPage(Page page, String tableName, String dsName) {
return Result.success(generatorService.getPage(page, tableName, dsName));
}
/**
* 预览代码
* @param genConfig 数据表配置
* @return
*/
@GetMapping("/preview")
public Result previewCode(@RequestBody GenConfig genConfig) {
return Result.success(generatorService.previewCode(genConfig));
}
/**
* 生成代码
*/
@SneakyThrows
@PostMapping("/code")
public String generatorCode(@RequestBody GenConfig genConfig, HttpServletResponse response) {
byte[] data = generatorService.generatorCode(genConfig);
FileOutputStream fileOutputStream = null;
String path="G:\\Download\\changrong-cloud.zip";
if (null!=genConfig&&null!=genConfig.getProjectPath()&&(!"".equals(genConfig.getProjectPath()))){
path=genConfig.getProjectPath()+"\\changrong-cloud.zip";
}
//输出到指定文件路径并生成对应压缩包
fileOutputStream = new FileOutputStream(new File(path));
fileOutputStream.write(data);
fileOutputStream.flush();
fileOutputStream.close();
// response.reset();
// response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
// String.format("attachment; filename=%s.zip", genConfig.getTableName()));
// response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(data.length));
// response.setContentType("application/octet-stream; charset=UTF-8");
//
// IoUtil.write(response.getOutputStream(), Boolean.TRUE, data);
//自动解压缩包
if (null!=genConfig&&null!=genConfig.getProjectPath()&&(!"".equals(genConfig.getProjectPath()))){
zipUncompress.zipUncompress(path,genConfig.getProjectPath());
}
return "代码生成结束";
}
/**
* 将字符串写入到文件
* <p><b>如果文件未创建,则自动创建</b>
* @param file 要写入的文件
* @param content 字符串
* @param fileEncoding 文件编码
*/
public static void writeFile(File file, String content, String fileEncoding){
FileOutputStream fos;
try {
fos = new FileOutputStream(file, false);
OutputStreamWriter osw;
if (fileEncoding == null) {
osw = new OutputStreamWriter(fos);
} else {
osw = new OutputStreamWriter(fos, fileEncoding);
}
BufferedWriter bw = new BufferedWriter(osw);
bw.write(content);
bw.close();
osw.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("写入文件失败!!");
}
}
}
entity层:存放代码生成的实体类文件,主要包含请求配置实体类,数据库读取,表读取实体类等。
@Data
public class ColumnEntity {
/**
* 列表
*/
private String columnName;
/**
* 数据类型
*/
private String dataType;
/**
* 备注
*/
private String comments;
/**
* 驼峰属性
*/
private String caseAttrName;
/**
* 普通属性
*/
private String lowerAttrName;
/**
* 属性类型
*/
private String attrType;
/**
* 其他信息
*/
private String extra;
/**
* 字段类型
*/
private String columnType;
/**
* 是否可以为空
*/
private Boolean nullable;
/**
* 是否隐藏
*/
private Boolean hidden;
}
/**
* 生成配置
*/
@Data
public class GenConfig {
/**
* 数据源name
*/
private String dsName;
/**
* 包名
*/
private String packageName;
/**
* 作者
*/
private String author;
/**
* 模块名称
*/
private String moduleName;
/**
* 表前缀
*/
private String tablePrefix;
/**
* 表名称
*/
private String tableName;
/**
* 表备注
*/
private String comments;
/**
* 代码风格 0 - avue 1 - element
*/
private String style;
/**
* 项目路径
*/
private String projectPath;
}
/**
* 数据源表
*/
@Data
@TableName("gen_datasource_conf")
@EqualsAndHashCode(callSuper = true)
public class GenDatasourceConf extends Model<GenDatasourceConf> {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId
private Integer id;
/**
* 名称
*/
private String name;
/**
* jdbcurl
*/
private String url;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 创建时间
*/
private LocalDateTime createDate;
/**
* 更新
*/
private LocalDateTime updateDate;
/**
* 删除标记
*/
@TableLogic
private String delFlag;
}
/**
* 生成记录
*/
@Data
@TableName("gen_form_conf")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "生成记录")
public class GenFormConf extends Model<GenFormConf> {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId
@ApiModelProperty(value = "ID")
private Integer id;
/**
* 表名称
*/
@ApiModelProperty(value = "表名称")
private String tableName;
/**
* 表单信息
*/
@ApiModelProperty(value = "表单信息")
private String formInfo;
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
/**
* 修改时间
*/
@ApiModelProperty(value = "修改时间")
private LocalDateTime updateTime;
/**
* 删除标记
*/
@ApiModelProperty(value = "删除标记")
private String delFlag;
}
/**
* 表属性
*/
@Data
public class TableEntity {
/**
* 名称
*/
private String tableName;
/**
* 备注
*/
private String comments;
/**
* 主键
*/
private ColumnEntity pk;
/**
* 列名
*/
private List<ColumnEntity> columns;
/**
* 驼峰类型
*/
private String caseClassName;
/**
* 普通类型
*/
private String lowerClassName;
}
mapper层:代码生成用来读取请求信息中数据库相关具体属性。
/**
* 代码生成器
*/
@Mapper
public interface GeneratorMapper {
/**
* 分页查询表格
* @param page
* @param tableName
* @return
*/
IPage<List<Map<String, Object>>> queryList(Page page, @Param("tableName") String tableName);
/**
* 查询表信息
* @param tableName 表名称
* @param dsName 数据源名称
* @return
*/
Map<String, String> queryTable(@Param("tableName") String tableName, String dsName);
/**
* 查询表列信息
* @param tableName 表名称
* @param dsName 数据源名称
* @return
*/
List<Map<String, String>> queryColumns(@Param("tableName") String tableName, String dsName);
}
service层:代码生成逻辑,包括根据模板引擎转化成对应文件,获取表单信息输出文件压缩流等。
public interface GeneratorService {
/**
* 生成代码
* @param tableNames 表名称
* @return
*/
byte[] generatorCode(GenConfig tableNames) throws IOException;
/**
* 分页查询表
* @param page 分页信息
* @param tableName 表名
* @param name 数据源ID
* @return
*/
IPage<List<Map<String, Object>>> getPage(Page page, String tableName, String name);
/**
* 预览代码
* @param genConfig 查询条件
* @return
*/
Map<String, String> previewCode(GenConfig genConfig);
}
/**
* 代码生成器
*/
@Service
@RequiredArgsConstructor
public class GeneratorServiceImpl implements GeneratorService {
private final GeneratorMapper generatorMapper;
private final GenFormConfMapper genFormConfMapper;
/**
* 分页查询表
*
* @param tableName 查询条件
* @param dsName
* @return
*/
@Override
public IPage<List<Map<String, Object>>> getPage(Page page, String tableName, String dsName) {
return generatorMapper.queryList(page, tableName);
}
/**
* 预览代码
*
* @param genConfig 查询条件
* @return
*/
@Override
public Map<String, String> previewCode(GenConfig genConfig) {
// 根据tableName 查询最新的表单配置
List<GenFormConf> formConfList = genFormConfMapper.selectList(Wrappers.<GenFormConf>lambdaQuery()
.eq(GenFormConf::getTableName, genConfig.getTableName()).orderByDesc(GenFormConf::getCreateTime));
String tableNames = genConfig.getTableName();
for (String tableName