起因

项目中需要根据数据库表写很多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步。

逻辑步骤

解析命令行

解析配置文件

获取数据表信息

生成配置信息

生成文件

代码设计

命令解析类 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 typeMap)和StringUtils中的驼峰命名转换(getCamelCaseString)将SQL信息转换成Java信息。

文件生成类 FileGenerator

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

主逻辑如下:

/**

* @param configuration 封装的配置信息

* @param columns 封装的数据表列信息

* @throws IOException

* @throws TemplateException

*/

public static void writeFile(Configuration configuration, List 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

实例演示

源代码

java 模板实现原理,Java Web 模板代码生成器的设计与实现详解相关推荐

  1. java sse spring_【SpringBoot WEB 系列】SSE 服务器发送事件详解

    SSE 全称Server Sent Event,直译一下就是服务器发送事件,一般的项目开发中,用到的机会不多,可能很多小伙伴不太清楚这个东西,到底是干啥的,有啥用 本文主要知识点如下: SSE 扫盲, ...

  2. java调用webservice_笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解...

    原标题:笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解 Java开发网站架构演变过程,到目前为止,大致分为5个阶段,分别为单体架构.集群架构.分布式架构.SOA架构和微服务架构.下 ...

  3. Java中常见RuntimeException与其他异常表及Exception逻辑关系详解

    Java中常见RuntimeException与其他异常表及Exception逻辑关系详解 前言 常见`RuntimeException` 其他错误类型 `Error`类 `Exception`类 E ...

  4. java中北大学ppt总结+课后习题第四章(小宇特详解)

    java中北大学ppt总结+课后习题第四章(小宇特详解) 继承 子类与父类 继承是根据现有类创建新的类的机制,由继承而得到的新类称为子类(subclass)或派生类(derived class),被继 ...

  5. Java调用SMSLib用单口短信猫发送短信详解

    技术园地 当前位置:短信猫网站主页 > 技术园地 > [转载]Java调用SMSLib用单口短信猫发送短信详解 发布时间:2017/02/09 点击量:620 SMSLib是Apache的 ...

  6. [转帖]ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解

    ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解 https://www.cnblogs.com/vipyoumay/p/7525478.html ASP.NET C ...

  7. 《Web前端开发精品课——HTML5 Canvas开发详解》——第一部分第二章节

    本节书摘来自异步社区<Web前端开发精品课--HTML5 Canvas开发详解>一书中的第1部分,第2章,作者:莫振杰 著,更多章节内容可以访问云栖社区"异步社区"公众 ...

  8. java lock的原理,Java中Lock原理探究

    在对于lock锁的使用上,很多人只是掌握了最基础的方法,但是对实现的过程不是很清楚.这里我们对lock锁功能的实现进行分析,以ReentrantLock为例,分析它的锁类型,并对相关的调用方法进行展示 ...

  9. java fragment_Java Web Fragment在项目中使用方法详解

    Web Fragment 是什么 - 它是在 servlet 3.0开始支持的,可以把一个dy web项目拆分为多个项目,解耦合,使其在项目中开发效率提高,下面我演示简单的项目创建过程 用eclips ...

最新文章

  1. 坚果 android 系统升级,坚果手机的系统是什么?坚果手机能升级安卓5.0吗?
  2. matlab 并联机械臂_MATLAB robot toolbox 机械臂轨迹规划
  3. 多线程中局部静态变量初始化的陷阱
  4. 华为S5700S-52P-LI-AC千兆网管交换机web登录界面配置
  5. java jquery用的多吗_[Java教程]如果不用jQuery,Ajax你还能写出多少?
  6. HBuilderX的各版本软件自取
  7. 记事本代码在命令行运行时出现的中文乱码问题
  8. SQL Server上月同期 日期的计算
  9. 4g内存 mysql_mysql 4G内存配置表
  10. Matlab之format 设置命令行窗口输出显示格式
  11. 用Xposed框架拦截微信、人人、QQ等LBS应用的当前位置
  12. 企鹅F4手机外观设计有突破 配MTK6592八核处理器
  13. 结束 oracle 锁 ps -ef|grepp.spid,oracle 解锁表剔除去session 和kill
  14. Unity任意方向拉伸物体
  15. 论文浅尝 | 探索用于归纳型知识图谱补全的关系语义
  16. 计算机毕设(附源码)JAVA-SSM快递代收系统
  17. 交换机二三层转发原理简单总结
  18. Navicat连接Linux-MySQL
  19. js函数内返回一个内部函数详解
  20. 学习笔记(01):C++入门课程-06.浮点数

热门文章

  1. (转)RTMP协议从入门到放弃
  2. 第二百三十一天 how can I 坚持
  3. SRM 591 div1 275
  4. SQL Server2012登录记录怎么删除?
  5. windows渗透大全
  6. iOS之深入解析预乘透明度Premultiplied Alpha
  7. HarmonyOS之剪贴板的功能和使用
  8. LeetCode 多线程 1114. 按序打印
  9. 华为有造车实力,却坚决不造整车,这背后有着怎样的无奈与思考?
  10. 编写你的第一个 Django 应用,第 6 部分