自动化代码生成器原理&实现
目录
Survive by day and develop by night.
talk is cheap, show me the code,make a better result.
概述
平台代码中项目代码中很多重复的代码,我们可以直接利用,免得以后因为细节问题而出错。
根据实际场景分析:
需求:
1.实现基本的CRUD三层代码的功能
实现思路
1.获得模板:
我们的模板如下获得模板对象:
package ${packageName}.dao;
<#if frameWorkVal=="springBoot">
import org.apache.ibatis.annotations.Mapper;
</#if>
import org.springframework.stereotype.Repository;
<#if entityName??>
import ${packageName}.entity.${entityName};
</#if>
<#if frameWorkVal=="springBoot">
@Mapper
</#if>
@Repository
<#if !entityName??>
public interface ${IDaoName} extends IBaseDao {
}
<#else>
public interface ${IDaoName} extends IBaseDao<${entityName}> {
}
</#if>
2.链接数据库获取sql参数
List<String> primaryKeyList = ChildWindowConstant.primaryKeyListMap.get(currentTableName);
String currentTableCnName = ChildWindowConstant.currentTableCnNameMap.get(currentTableName);
// root.put(CodeConstant.primaryKeyList, primaryKeyList);
root.put(CodeConstant.currentTableCnName, currentTableCnName);
// 因为主键必须设置 所以所有的条件不可能为0
List<DatabaseModel> allColumnList = ChildWindowConstant.allColumnMsgMap.get(currentTableName);
3.检查和创建目录
此时比较简单,
public static String checkAndMakeDir(String mkdir) {
File path = new File(mkdir);
if (!path.exists()) {
path.mkdirs();
}
return mkdir;
}
4.framemark 处理
daoTemplate.process(root, daoOut);
5.关闭流处理
daoOut.flush();
拓展实现一个基本的POJO的代码编辑器
按照以上的流程:我们先抽象一个方法:基本的Field对象:
package demo.POJO;
public class Filed {
private String fieldType;
private String fieldName;
public String getFieldType() {
return fieldType;
}
public void setFieldType(String fieldType) {
this.fieldType = fieldType;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
}
2,抽象出一个基本的包名并且把这个设置进去:
package demo.POJO;
import java.util.LinkedHashSet;
import java.util.Set;
public class JavaPropertiesuser {
// private final String pkg;
private final String pkg;
private final String entityName;
private final Set<Filed> fileds=new LinkedHashSet<Filed>();
private final Set<String> imports=new LinkedHashSet<String>();
public JavaPropertiesuser(String pkg, String entityName) {
super();
this.pkg = pkg;
this.entityName = entityName;
}
void addFiled(Class<?> type,String filedName) {
final String pattern="java.lang";
String fieldType=type.getName();
if(!fieldType.startsWith(pattern)) {
this.imports.add(fieldType);
}
int i=fieldType.lastIndexOf(".");
Filed field=new Filed();
field.setFieldType(fieldType.substring(i+1));
field.setFieldName(filedName);
fileds.add(field);
}
public String getPkg() {
return pkg;
}
public String getEntityName() {
return entityName;
}
public Set<Filed> getFileds() {
return fileds;
}
public Set<String> getImports() {
return imports;
}
}
3.主程序测试:
模板文件如下:
package ${pkg};
<#list imports as impt>
import ${impt};
</#list>
public class ${entityName} {
<#list fileds as field>
private ${field.fieldType} ${field.fieldName};
</#list>
根据模板引擎处理ftl文件:
package demo.POJO;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import freemarker.core.Configurable;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* Hello world!
*
*/
public class App
{
public App() {
super();
// TODO Auto-generated constructor stub
}
static String rootpath = "d:";
static String packageName = "cn.felord.code";
static String templatePath = "D:\\02.code\\POJO\\src\\main\\java";
static String templateName = "entity.ftl";
public static void main(String[] args) throws IOException, TemplateException {
JavaPropertiesuser userEntity = new JavaPropertiesuser("UserEntity", packageName);
userEntity.addFiled(String.class, "username");
userEntity.addFiled(LocalDate.class, "birthday");
userEntity.addFiled(LocalDateTime.class, "addTime");
userEntity.addFiled(Integer.class, "gender");
userEntity.addFiled(Integer.class, "age");
autoCodingJavaEtity(rootpath, templatePath, templateName, userEntity);
}
private static void autoCodingJavaEtity(String rootPath, String templatPath, String templateName,
JavaPropertiesuser javaPropertiesuser) throws IOException, TemplateException {
Configuration conf = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
conf.setDefaultEncoding("utf-8");
conf.setDirectoryForTemplateLoading(new File(templatPath));
Template template = conf.getTemplate(templateName);
// 定义一个输出流来导出代码文件
String ext = ".java";
String javaName = javaPropertiesuser.getEntityName().concat(ext);
String packageName = javaPropertiesuser.getPkg();
// String out=rootPath.concat(packageName)
String out = rootPath
.concat(Stream.of(packageName.split("\\.")).collect(Collectors.joining("/", "/", "/" + javaName)));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(out));
template.process(javaPropertiesuser, outputStreamWriter);
}
}
4.效果:
参考资料和推荐阅读
欢迎阅读,各位老铁,如果对你有帮助,点个赞加个关注呗!~