开发者社区> 行者武松> 正文

Java Web模板代码生成器的设计与实现

简介:
+关注继续查看

起因

项目中需要根据数据库表写很多Meta、Dao、Service代码,其中很多代码都是重复而繁琐的。因此如果有一个模板代码的生成器,就可以一定程度提高开发效率。

目标

可配置生成Java Web项目中Dao、Meta、Service层模板代码的生成器。

代码框架

mvn archetype:generate -DgroupId=com.zju -DartifactId=JavaWebCodeGenerator -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false -DarchetypeCatalog=internal

设计思路

项目参考Mybatis generator生成代码的过程,具体步骤分为以下5步。

逻辑步骤

  1. 解析命令行
  2. 解析配置文件
  3. 获取数据表信息
  4. 生成配置信息
  5. 生成文件

代码设计

命令解析类 ShellRunner

该类负责解析命令行的命令,解析配置文件并封装所需的数据给代码生成类。

可解析命令有-configfile:指定配置文件所在路径和-overwrite:是否重写目标文件。

配置文件的配置项有:

//Java SQL 驱动所在路径(暂未使用)
private static final String CLASS_PATH_ENTRY = "class.path.entry";
//Java 驱动类型(暂未使用)
private static final String DRIVER_CLASS = "driver.class";
//数据库地址
private static final String CONNECTION_URL = "connection.url";
//数据库用户名
private static final String USER_ID = "user.id";
//数据库密码
private static final String USER_PASSWORD = "user.password";
//模型生成地址
private static final String JAVA_MODEL_PACKAGE = "java.model.package";
//SQL生成地址
private static final String SQL_MAPPING_PACKAGE = "sql.mapping.package";
//项目地址
private static final String PROJECT = "project";
//数据表名
private static final String TABLE_NAME = "table.name";
//模型名称
private static final String DOMAIN_OBJECT_NAME = "domain.object.name";

代码生成类 CodeGenerator

该类负责连接数据库,查询数据表的表信息,将SQL类型映射成Java类型并封装所需的数据给文件生成类。

Class.forName(configuration.getDriverClass());
//获取数据库连接
Connection connection = DriverManager.getConnection(configuration.getConnectionURL(), configuration.getUserId(), configuration.getPassword());
DatabaseMetaData databaseMetaData = connection.getMetaData();
//获取表结构信息
ResultSet rs = databaseMetaData.getColumns("", "", configuration.getTableName(), "%");

通过以上几行代码,rs变量中已经获得目标数据表的表信息。

databaseMetaData.getColumns方法的实质是执行了SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME="tableName"语句。

在结果集中,后续处理大致需要以下表信息列。

字段 描述
DATA_TYPE 数据类型
COLUMN_SIZE 数据长度
COLUMN_NANE 列名
NULLABLE 是否允许非空
DECIMAL_DIGITS 小数位数
REMARKS 备注
COLUMN_DEF 默认值

最后通过JavaTypeResolver中的类型映射(Map<Integer, JdbcTypeInformation> typeMap)和StringUtils中的驼峰命名转换(getCamelCaseString)将SQL信息转换成Java信息。

文件生成类 FileGenerator

该类通过FreeMarker模板引擎组合数据成目标代码文件。

主逻辑如下:

/** * @param configuration 封装的配置信息 * @param columns       封装的数据表列信息 * @throws IOException * @throws TemplateException */
public static void writeFile(Configuration configuration, List<TableColumn> columns) throws IOException, TemplateException {
    File r=new File("");
    //测试环境获取项目根目录路径
    //String path=Class.class.getClass().getResource("/").getPath();
    //Jar包获取根目录路径
    String path=r.getAbsolutePath();
    //System.out.println("path:"+path);
    Configuration cfg = new Configuration();
    cfg.setDirectoryForTemplateLoading(new File(path + "/ftl")); //需要文件夹绝对路径
    cfg.setDefaultEncoding("UTF-8");
    cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
    Map root = new HashMap();
    root.put("configuration", configuration);
    root.put("columnList", columns);
    writeSingleFile(cfg, root, "DaoImpl.ftl", configuration.getProjectPath(), configuration.getSqlMappingPackage().replace(".", "/"), configuration.getDomainObjectName(), "DaoImpl.java",configuration.getOverwrite());
    writeSingleFile(cfg, root, "Dao.ftl", configuration.getProjectPath(), configuration.getSqlMappingPackage().replace(".", "/"), configuration.getDomainObjectName(), "Dao.java",configuration.getOverwrite());
    writeSingleFile(cfg, root, "Meta.ftl", configuration.getProjectPath(), configuration.getJavaModelPackage().replace(".", "/"), configuration.getDomainObjectName(), ".java",configuration.getOverwrite());
}

注意

在测试中,Class.class.getClass().getResource("/").getPath();该方法可以获取项目根目录,但是在测试生成的Jar包时,该方法时效。因此在生成Jar包前需要把该行修改成new File("").getAbsolutePath();获取生成路径。

项目结构

项目结构

配置文件范例

generatorConfig.properties

class.path.entry=src/test/resources/mysql-connector-java-5.1.38.jar
driver.class=com.mysql.jdbc.Driver
connection.url=jdbc:mysql://localhost:3307/work
user.id=
user.password=
java.model.package=com.model
sql.mapping.package=com.dao
project=src
table.name=holiday
domain.object.name=Holiday

运行命令范例

java -jar JavaWebCodeGenerator.jar -configfile generatorConfig.properties -overwrite

实例演示

实例演示

源代码

https://github.com/TedHacker/PracticeArea/tree/master/JavaWebCodeGenerator



作者:tedhacker.top

来源:51CTO

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
通过90行代码学会HTML5 WebSQL的4种基本操作
通过90行代码学会HTML5 WebSQL的4种基本操作
22 0
希尔排序(简单易懂,图文并貌,插入排序)java代码实现
希尔排序(简单易懂,图文并貌,插入排序)java代码实现
14 0
快速排序(随机化快速排序 随机主元)java代码(递归实现)分治法(分而治之)
快速排序(随机化快速排序 随机主元)java代码(递归实现)分治法(分而治之)
12 0
归并排序 (分而治之算法) java代码实现(java完整代码)java递归实现(分而治之)MergeSort(分治法)
归并排序 (分而治之算法) java代码实现(java完整代码)java递归实现(分而治之)MergeSort(分治法)
19 0
最大子数组(最大子数组和)分治法 java代码实现(完整版)递归方式实现(分而治之)
最大子数组(最大子数组和)分治法 java代码实现(完整版)递归方式实现(分而治之)
26 0
Web前端,让你代码整洁的原则
写Web页面就像我们建设房子一样,地基牢固,房子才不会倒。同样的,我们制作Web页面也一样,一个良好的HTML结构是制作一个美丽的网站的开始,同样的,良好的CSS只存在同样良好的HTML中,所以一个干净的,语义的HTML的优点很多,那么平时制作中,我们做到了这一点吗?我们一起来看一张图片:   上图展示了两段代码,我想大家都只会喜欢第一种,我们先不说其语义,至少他的结构让我们看上去清爽,而第二种呢?一看就是糟糕的代码的代码,让人讨厌的代码。
966 0
+关注
行者武松
杀人者,打虎武松也。
17142
文章
2569
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载