renren-generator的代码生成流程详解
文章详细解析了renren-generator项目的代码生成流程,包括核心控制器SysGeneratorController的功能与实现、服务层SysGeneratorService的逻辑处理、代码生成工具类GenUtils的具体实现,以及代码压缩与下载的完整流程。
代码生成的入口与控制器(SysGeneratorController)
在renren-generator项目中,SysGeneratorController是代码生成流程的核心入口和控制器。它负责接收前端请求,调用服务层生成代码,并将生成的代码文件以压缩包形式返回给用户。以下是对SysGeneratorController的详细解析。
控制器功能概述
SysGeneratorController提供了两个主要功能:
- 列表查询:获取数据库中可生成代码的表信息。
- 代码生成:根据用户选择的表生成对应的代码文件。
核心方法解析
1. 列表查询方法
@ResponseBody
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params) {
PageUtils pageUtil = sysGeneratorService.queryList(new Query(params));
return R.ok().put("page", pageUtil);
}
- 功能:查询数据库中可生成代码的表信息,支持分页和条件查询。
- 参数:
params:前端传递的查询参数,如分页信息、表名等。
- 返回值:
- 返回一个
R对象,包含分页数据。
- 返回一个
2. 代码生成方法
@RequestMapping("/code")
public void code(String tables, HttpServletResponse response) throws IOException {
byte[] data = sysGeneratorService.generatorCode(tables.split(","));
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"renren.zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(data, response.getOutputStream());
}
- 功能:根据用户选择的表生成代码文件,并以压缩包形式返回。
- 参数:
tables:用户选择的表名,多个表名以逗号分隔。response:HTTP响应对象,用于返回生成的代码文件。
- 流程:
- 调用
sysGeneratorService.generatorCode生成代码。 - 设置响应头,指定文件名和内容类型。
- 将生成的代码文件写入响应流。
- 调用
类图
以下是SysGeneratorController的类图,展示了其与SysGeneratorService的依赖关系:
代码生成流程
以下是代码生成的时序图,展示了从请求到生成代码的完整流程:
总结
SysGeneratorController作为代码生成的入口,通过简洁的接口设计实现了高效的代码生成功能。其核心方法list和code分别负责查询表信息和生成代码文件,与SysGeneratorService紧密配合,为用户提供了便捷的代码生成体验。
服务层逻辑(SysGeneratorService)
在renren-generator项目中,SysGeneratorService是代码生成流程中的核心服务层,负责处理与数据库表相关的查询操作以及代码生成逻辑。以下将详细介绍其实现细节和功能模块。
1. 查询数据库表列表
SysGeneratorService通过queryList方法实现对数据库表的列表查询功能。该方法支持分页查询,并适配了多种数据库类型(如MySQL、MongoDB等)。
public PageUtils queryList(Query query) {
Page<?> page = PageHelper.startPage(query.getPage(), query.getLimit());
List<Map<String, Object>> list = generatorDao.queryList(query);
int total = (int) page.getTotal();
if (generatorDao instanceof MongoDBGeneratorDao) {
total = MongoDBCollectionFactory.getCollectionTotal(query);
}
return new PageUtils(list, total, query.getLimit(), query.getPage());
}
功能说明:
- 分页查询:使用
PageHelper实现分页逻辑,返回分页结果。 - 多数据库适配:通过
generatorDao接口动态适配不同数据库的查询逻辑,如MongoDB的特殊处理。
2. 查询表结构与列信息
SysGeneratorService提供了两个方法用于获取表结构和列信息:
queryTable:查询指定表的元数据信息。queryColumns:查询指定表的所有列信息。
public Map<String, String> queryTable(String tableName) {
return generatorDao.queryTable(tableName);
}
public List<Map<String, String>> queryColumns(String tableName) {
return generatorDao.queryColumns(tableName);
}
功能说明:
- 这两个方法为代码生成提供了基础数据支持,确保生成的代码与数据库结构完全匹配。
3. 代码生成逻辑
generatorCode方法是SysGeneratorService的核心功能,负责将数据库表结构转换为代码文件,并打包为ZIP格式返回。
public byte[] generatorCode(String[] tableNames) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
for (String tableName : tableNames) {
// 查询表信息
Map<String, String> table = queryTable(tableName);
// 查询列信息
List<Map<String, String>> columns = queryColumns(tableName);
// 生成代码
GenUtils.generatorCode(table, columns, zip);
}
if (MongoManager.isMongo()) {
GenUtils.generatorMongoCode(tableNames, zip);
}
IOUtils.closeQuietly(zip);
return outputStream.toByteArray();
}
功能说明:
- 多表支持:支持同时生成多个表的代码。
- MongoDB适配:通过
MongoManager判断是否为MongoDB数据库,并调用generatorMongoCode生成MongoDB相关代码。 - ZIP打包:生成的代码文件通过
ZipOutputStream打包,便于用户下载。
4. 类图展示
以下为SysGeneratorService的类图,展示了其核心方法和依赖关系:
5. 总结
SysGeneratorService通过灵活的查询和代码生成逻辑,为renren-generator提供了强大的后端支持。其设计充分考虑了多数据库适配和代码生成的效率问题,是项目中的关键组件之一。
代码生成工具类(GenUtils)详解
GenUtils 是 renren-generator 项目中的核心工具类,负责代码生成的具体逻辑实现。它通过解析数据库表结构,结合 Velocity 模板引擎,动态生成 Java 实体类、DAO、Service、Controller 等代码文件。以下是对 GenUtils 的详细解析。
功能概述
GenUtils 的主要功能包括:
- 模板管理:定义代码生成的模板路径。
- 代码生成:根据表结构和配置生成代码文件。
- MongoDB 支持:针对 MongoDB 的特殊处理逻辑。
- 工具方法:提供表名转类名、列名转属性名等辅助方法。
核心方法解析
1. getTemplates()
定义代码生成所需的模板文件路径。支持 MySQL 和 MongoDB 两种数据库类型。
public static List<String> getTemplates() {
List<String> templates = new ArrayList<String>();
templates.add("template/Entity.java.vm");
templates.add("template/Dao.xml.vm");
templates.add("template/menu.sql.vm");
templates.add("template/Service.java.vm");
templates.add("template/ServiceImpl.java.vm");
templates.add("template/Controller.java.vm");
templates.add("template/Dao.java.vm");
templates.add("template/index.vue.vm");
templates.add("template/add-or-update.vue.vm");
if (MongoManager.isMongo()) {
templates.remove(0);
templates.remove(1);
templates.remove(2);
templates.add("template/MongoEntity.java.vm");
}
return templates;
}
2. generatorCode()
生成代码的核心方法,接收表信息和列信息,通过 Velocity 模板引擎渲染代码文件。
public static void generatorCode(Map<String, String> table,
List<Map<String, String>> columns, ZipOutputStream zip) {
// 配置信息
Configuration config = getConfig();
// 表信息处理
TableEntity tableEntity = new TableEntity();
tableEntity.setTableName(table.get("tableName"));
tableEntity.setComments(table.get("tableComment"));
// 列信息处理
List<ColumnEntity> columsList = new ArrayList<>();
for (Map<String, String> column : columns) {
ColumnEntity columnEntity = new ColumnEntity();
columnEntity.setColumnName(column.get("columnName"));
columnEntity.setDataType(column.get("dataType"));
columnEntity.setComments(column.get("columnComment"));
// 转换列名为 Java 属性名
columnEntity.setAttrName(columnToJava(columnEntity.getColumnName()));
columsList.add(columnEntity);
}
tableEntity.setColumns(columsList);
// 渲染模板
VelocityContext context = new VelocityContext(map);
for (String template : templates) {
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, "UTF-8");
tpl.merge(context, sw);
// 写入 Zip 文件
zip.putNextEntry(new ZipEntry(getFileName(template, tableEntity.getClassName(), config.getString("package"), config.getString("moduleName")));
IOUtils.write(sw.toString(), zip, "UTF-8");
}
}
3. columnToJava() 和 tableToJava()
工具方法,用于将数据库列名和表名转换为 Java 属性名和类名。
public static String columnToJava(String columnName) {
return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
}
public static String tableToJava(String tableName, String[] tablePrefixArray) {
if (null != tablePrefixArray && tablePrefixArray.length > 0) {
for (String tablePrefix : tablePrefixArray) {
if (tableName.startsWith(tablePrefix)) {
tableName = tableName.replaceFirst(tablePrefix, "");
}
}
}
return columnToJava(tableName);
}
流程图
以下为 GenUtils 的代码生成流程:
表格:模板文件与生成代码对应关系
| 模板文件 | 生成的代码文件 |
|---|---|
template/Entity.java.vm | 实体类(如 UserEntity.java) |
template/Dao.java.vm | DAO 接口(如 UserDao.java) |
template/Service.java.vm | Service 接口(如 UserService.java) |
template/Controller.java.vm | Controller 类(如 UserController.java) |
注意事项
- 配置文件:
GenUtils依赖generator.properties文件,需确保其路径正确。 - 模板路径:模板文件需放在
resources/template目录下。 - MongoDB 支持:若使用 MongoDB,需通过
MongoManager.isMongo()判断并调整模板列表。
生成代码的压缩与下载流程
在renren-generator中,代码生成后的压缩与下载流程是用户获取生成代码的关键步骤。本节将详细介绍这一流程的实现细节,包括代码压缩的逻辑、下载响应的设置以及相关工具类的使用。
1. 代码压缩的实现
代码生成后,系统会将生成的代码文件压缩为ZIP格式,便于用户下载。这一功能主要通过ZipOutputStream实现,以下是核心代码片段:
try (ZipOutputStream zip = new ZipOutputStream(outputStream)) {
// 生成代码并写入ZIP流
GenUtils.generatorCode(table, columns, zip);
GenUtils.generatorMongoCode(tableNames, zip);
} finally {
IOUtils.closeQuietly(zip);
}
关键点说明:
ZipOutputStream:用于将生成的代码文件压缩为ZIP格式。GenUtils.generatorCode:生成标准数据库表的代码文件。GenUtils.generatorMongoCode:生成MongoDB相关的代码文件。IOUtils.closeQuietly:确保资源被正确关闭,避免内存泄漏。
2. 下载响应的设置
在控制器层,系统通过设置HTTP响应头,将生成的ZIP文件提供给用户下载。以下是相关代码:
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"renren.zip\"");
关键点说明:
Content-Type:设置为application/octet-stream,表示二进制流文件。Content-Disposition:设置为attachment,并指定文件名renren.zip,强制浏览器下载文件。
3. 流程图示
以下是通过mermaid流程图展示的代码压缩与下载流程:
4. 相关工具类
| 工具类/方法 | 功能描述 |
|---|---|
ZipOutputStream | 提供ZIP格式的压缩功能,将多个文件打包为一个ZIP文件。 |
GenUtils | 包含生成代码的核心逻辑,支持多种数据库和MongoDB的代码生成。 |
IOUtils.closeQuietly | 确保资源被安全关闭,避免因异常导致的资源泄漏。 |
5. 代码示例
以下是一个完整的代码生成与下载的示例:
@RestController
@RequestMapping("/sys/generator")
public class SysGeneratorController {
@Autowired
private SysGeneratorService sysGeneratorService;
@RequestMapping("/code")
public void code(String tables, HttpServletResponse response) throws IOException {
// 设置响应头
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"renren.zip\"");
// 生成代码并压缩
try (OutputStream outputStream = response.getOutputStream()) {
sysGeneratorService.generateCode(tables, outputStream);
}
}
}
说明:
- 用户通过访问
/sys/generator/code接口,传入表名参数tables,即可触发代码生成与下载流程。 - 生成的ZIP文件将自动下载到用户本地,文件名为
renren.zip。
总结
renren-generator通过SysGeneratorController、SysGeneratorService和GenUtils的协同工作,实现了高效的代码生成功能。其设计充分考虑了多数据库适配和代码生成效率,为用户提供了便捷的代码生成体验。从查询表信息到生成代码文件,再到压缩下载,整个流程清晰且高效。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



