前言
车队管理类似的SaaS平台,从0到1,继续..
上一篇咱撸到代码生成的模板,模板或者说代码生成更加友好、更可配的方式,有一些方案各有优劣吧,那本篇继续模板后的实现逻辑。
(我是后半夜Java,在掘金这分享下经验,那些靠copy的搬运作者,未经允许,不要copy文章了)
思路
通过表名,获取表相关信息,调用模板去生成对应代码
实现
control就不写了,就个表名List 就可以,我们先看Service逻辑。这个是参考人人开源的,目前开源的项目还是蛮多的。 返回byte字节是方便给前端导出下载,,让人你要直接生成放到本地路径也可以
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;
/**
* 代码生成器
*/
@Service
public class SysGeneratorService {
@Autowired
private GeneratorDao generatorDao;
/**
* 通过表名称去生成代码,支持多表一起
* @param tableNames 表明集合
* @return
*/
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);
}
IOUtils.closeQuietly(zip);
return outputStream.toByteArray();
}
/**
* 根据表名查询表相关信息
* @param tableName
* @return
*/
public Map<String, String> queryTable(String tableName) {
return generatorDao.queryTable(tableName);
}
/**
* 通过表名获取表的字段信息
* @param tableName
* @return
*/
public List<Map<String, String>> queryColumns(String tableName) {
return generatorDao.queryColumns(tableName);
}
}
代码生成
private static final String COLUMN_NAME = "columnName";
private static final String TABLE_NAME = "tableName";
private static final String TABLE_COMMENT = "tableComment";
private static final String TABLE_PREFIX = "tablePrefix";
private static final String DATA_TYPE = "dataType";
private static final String COLUMN_COMMENT = "columnComment";
private static final String EXTRA = "extra";
private static final String UNKNOW_TYPE = "unknowType";
private static final String BIGDECIMAL = "BigDecimal";
private static final String COLUMN_KEY = "columnKey";
private static final String PRI = "PRI";
/**
* 生成代码
*/
public static void generatorCode(Map<String, String> table,
List<Map<String, String>> columns, ZipOutputStream zip){
//配置信息
Configuration config = getConfig();
boolean hasBigDecimal = false;
//表信息
TableEntity tableEntity = new TableEntity();
tableEntity.setTableName(table.get(TABLE_NAME));
tableEntity.setComments(table.get(TABLE_COMMENT));
//表名转换成Java类名
String className = tableToJava(tableEntity.getTableName(), config.getString(TABLE_PREFIX));
tableEntity.setClassName(className);
tableEntity.setClassname(StringUtils.uncapitalize(className));
//列信息
List<ColumnEntity> columsList = new ArrayList<>();
for(Map<String, String> column : columns){
ColumnEntity entity = new ColumnEntity();
entity.setColumnName(column.get(COLUMN_NAME));
entity.setDataType(column.get(DATA_TYPE));
entity.setComments(column.get(COLUMN_COMMENT));
entity.setExtra(column.get(EXTRA));
String attrName = columnToJava(entity.getColumnName());
entity.setAttrName(attrName);
entity.setAttrname(StringUtils.uncapitalize(attrName));
String attrType = config.getString(entity.getDataType(), UNKNOW_TYPE);
entity.setAttrType(attrType);
if (!hasBigDecimal && attrType.equals(BIGDECIMAL)) {
hasBigDecimal = true;
}
//是否主键
if(PRI.equalsIgnoreCase(column.get(COLUMN_KEY)) && tableEntity.getPk() == null){
tableEntity.setPk(entity);
}
columsList.add(entity);
}
tableEntity.setColumns(columsList);
//没主键,则第一个字段为主键
if(tableEntity.getPk() == null){
tableEntity.setPk(tableEntity.getColumns().get(0));
}
总结
代码生成,有很多案例,没有哪个最好,先这样吧,感觉这个大家手头估计都有几个。
SaaS系统从0到1搭建,未完待续....