需求

  • 我们需要一个可以通用的且只是改变或增加模板就可以实现的文件生成器

实现

  • 文件类

  • 对于文件的操作,我们需要判断文件夹是否存在,如果不存在则创建和取当前项目路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.hantianwei.generator.util;

import java.io.File;

/**
* Created by tianwei on 2017/6/29.
*/
public class FileUtil {

public static void createDirectory(String path) {
File file = new File(path);
if (!file.exists()) {
try {
file.mkdirs();
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static String getCurrentDirParent() {
String path = System.getProperty("user.dir");
File file = new File(path);
return file.getParent();
}
}
  • 文件类有了,我们需要写一个Freemarker类来实现解析模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.hantianwei.generator.util;

import java.io.*;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
* Created by tianwei on 2017/6/29.
*/
public class FreeMakerUtil {
/**
* 获取模板文件
*
* @param name
* @return
*/
public Template getTemplate(String name) {
try {
Configuration cfg = new Configuration();
cfg.setDefaultEncoding("UTF-8");
cfg.setClassForTemplateLoading(this.getClass(), "/ftl");
Template template = cfg.getTemplate(name);
return template;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

/**
* 生成文件
*
* @param templateName:模板名
* @param root:数据原型
* @param outFilePath:输出路径(全路径名)
*/
public void generateFile(String templateName, Map<String, Object> root, String outFilePath) {

Writer out = null;
try {
outFilePath = FileUtil.getCurrentDirParent() + outFilePath;
FileUtil.createDirectory(new File(outFilePath).getParent());
// 通过一个文件输出流,就可以写到相应的文件中,此处用的是绝对路径
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(outFilePath)), "UTF-8"));
Template temp = this.getTemplate(templateName);
temp.process(root, out);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
  • 生成类

    • 到这里我们只剩下Service里面的逻辑实现部分了,我们在 DataService 中增加模板赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.hantianwei.generator.service.impl;

import com.hantianwei.generator.model.Field;
import com.hantianwei.generator.model.Table;
import com.hantianwei.generator.service.IDataService;
import com.hantianwei.generator.util.FreeMakerUtil;
import com.hantianwei.generator.util.StringUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by tianwei on 2017/6/26.
*/
public class DataService implements IDataService {

/**
* 根据表名获取模板要用的Map型数据
* (带有列信息)
*
* @param table
* @return
*/
public Map<String, Object> getDbTemplateData(Table table, List<Field> fieldList) {
Map<String, Object> templateData = new HashMap<String, Object>();
templateData.put("tableName", table.getName());
templateData.put("tableProName", table.getProName());
templateData.put("fieldList", fieldList);
templateData.put("fieldPk", StringUtil.getFieldPk(fieldList));
templateData.put("config", FreeMakerUtil.useStaticPackage("com.hantianwei.generator.model.Config"));
return templateData;
}

}

package com.hantianwei.generator.service;

import com.hantianwei.generator.model.Field;
import com.hantianwei.generator.model.Table;

import java.util.List;
import java.util.Map;

/**
* Created by tianwei on 2017/6/27.
*/
public interface IDataService {
/**
* 根据表名获取Vo模板要用的Map型数据
*
* @param table
* @return
*/
Map<String, Object> getDbTemplateData(Table table, List<Field> fieldList);
}
  • 再增加 CodeGenerator 对查出的所有表进行循环生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.hantianwei.generator.service.impl;

import com.hantianwei.generator.dao.DataDao;
import com.hantianwei.generator.model.Config;
import com.hantianwei.generator.model.Field;
import com.hantianwei.generator.model.Table;
import com.hantianwei.generator.service.ICodeGenerator;
import com.hantianwei.generator.util.FreeMakerUtil;
import com.hantianwei.generator.util.StringUtil;

import java.util.List;
import java.util.Map;

/**
* Created by tianwei on 2017/6/26.
*/
public class CodeGenerator implements ICodeGenerator {

DataDao dataDao = new DataDao();

private static FreeMakerUtil freeMakerUtil = new FreeMakerUtil();
private static DataService dataService = new DataService();


public void generateFile(String templateName, Table table, List<Field> fieldList, String packagePath, String fileName) {
generateFileWithDb(templateName, table, fieldList, packagePath, fileName);
}

public void generateFileWithDb(String templateName, Table table, List<Field> fieldList, String packagePath, String fileName) {
Map<String, Object> templateData = dataService.getDbTemplateData(table, fieldList);
freeMakerUtil.generateFile(templateName, templateData, packagePath + fileName);
}

public void generatorAllTables() {
List<Table> tables = dataDao.getAllTables(Config.DB_NAME);
for (Table table : tables) {
long startTime = System.currentTimeMillis();
List<Field> fieldList = dataDao.getAllColums(Config.DB_NAME, table.getName());
String tableName = StringUtil.toUpperCaseFirstOne(table.getProName());
//这里可改为枚举控制
generateFile("ModelTemplate.ftl", table, fieldList, Config.PACKAGE_MODEL_PATH, String.format("%s.java", tableName));
generateFile("DaoTemplate.ftl", table, fieldList, Config.PACKAGE_DAO_PATH, String.format("%s%s.java", tableName, StringUtil.toUpperCaseFirstOne(Config.PACKAGE_DAO_NAME)));
generateFile("ServiceTemplate.ftl", table, fieldList, Config.PACKAGE_SERVICE_PATH, String.format("%s%s.java", tableName,StringUtil.toUpperCaseFirstOne(Config.PACKAGE_SERVICE_NAME)));
generateFile("IServiceTemplate.ftl", table, fieldList, Config.PACKAGE_ISERVICE_PATH, String.format("I%s%s.java", tableName,StringUtil.toUpperCaseFirstOne(Config.PACKAGE_SERVICE_NAME)));
generateFile("MapperTemplate.ftl", table, fieldList, Config.PACKAGE_MAPPER_PATH, String.format("%sMapper.xml", tableName));
long endTime = System.currentTimeMillis();
System.out.println(String.format("[%s]表生成完毕,用时[%d]ms", tableName, endTime - startTime));
}
}


}

package com.hantianwei.generator.service;

import com.hantianwei.generator.model.Field;
import com.hantianwei.generator.model.Table;

import java.util.List;

/**
* Created by tianwei on 2017/6/29.
*/
public interface ICodeGenerator {

void generateFile(String templateName, Table table, List<Field> fieldList, String packagePath, String fileName);

void generateFileWithDb(String templateName, Table table, List<Field> fieldList, String packagePath, String fileName);

void generatorAllTables();
}
  • 主方法

    • 主要程序都完工了,我们需要在Mian里面进行调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.hantianwei.generator.main;

import com.hantianwei.generator.service.ICodeGenerator;
import com.hantianwei.generator.service.impl.CodeGenerator;
import com.hantianwei.generator.util.PropUtil;

/**
* Created by tianwei on 2017/6/27.
*/
public class RunGenerator {
public static void main(String[] args){
PropUtil.loadConf(args);

ICodeGenerator cg = new CodeGenerator();
cg.generatorAllTables();

System.out.println("****** OK ******");
}
}
  • 到此所有程序都已完工,我们下章开始实现模板