easygen通用代码生成框架[开源]
什么东东
用过mybatis的同学都知道,手工写mapper和xml是一件很痛苦的事儿,幸好官方提供了Mybatis-Generator,但是这家伙生成的东西不开放不方便修改,而且项目中的代码生成需求不只是数据访问层,比如说view、service、controller,这些地方到处充斥着重复代码,有什么好办法了,反正我是见识少,只能自己动手了。
设计思路
简单点,设计的思路简单点,只有简单别人才好上手。
- 1.利用模板引擎加载模型,渲染模板,生成文件。
- 2.模型由模型构建器加载,要内置mysql元数据作为模型,支持自定义其他模型构建器
- 3.模型和模板文件要分离,这样模型可以重用到其他模板
- 4.模型和模板文件是一对多的关系,方面根据一个表生成po、mapper、service
- 5.支持一个模型批量生成,如数据库表这种,不能每个表对应一个模型吧
先不要想那么多,就这些吧
使用方式设计
很多同学一上来就写代码,最后根据功能设计使用方式,我更倾向于先把使用方式设计好,俗话说好的开始是成功的一半。
- 代码生成方式简单点,那就 java -jar xxxx.jar吧,然后在ohmyzsh里配置一下alias就爽了。
- 配置文件用json 简单好维护,文件名和路径默认,支持修改。
- 发布包提供样板,方便学习和使用。
好了,先YY一个配置文件,看看:
{
"modelBuilders": [
{
"name": "mysql", //模型构建器名称要
"type": "db:mysql", //构建器类型
"configPath": "modelBuilders/mysql.json" //数据库配置
}
],
"templates": [
{
"name": "beanClass",
"modelBuilderName": "mysql", //关联的模型构建器name
"templateFilename": "beanClass.ftl",
"outputPath": "output/bean"
}
]
}
恩就这样,是不是有点晕,我解释一下:
- 1.首先我们的框架加载配置文件。
- 2.然后根据配置文件中的modelBuilders加载指定type的模型构建器
- 3.然后将configPath指定的配置文件传给模型构建器,用于构建数据模型
- 4.框架根据配置文件中的templates中的每一个元素的modelBuilderName属性去关联已经构建好的模型构建器。
- 5.然后框架使用模型构建器构建Model,并根据templateFilename指定的模板文件进行渲染(使用freemarker)
- 6.输出文件到outputPath
最终效果
github: https://github.com/BigMaMonkey/easygen
其实框架的代码很简单,重点还是设计好使用方式,简单并可扩展,其实过程中还需要一些其他特性:
- 基于freemarker的模板语法,上手简单
- 内置mysql、json模型构建器,并支持自定义
- 支持生成指定表、去掉表前缀、转换大小写等
- 支持模型与模板的一对多关系(模型与模板的分离)
- 支持List类型的模型,批量生成。
- 支持自定义文件名生成规则
- 支持自定义输出路径
- 支持模板自定义参数
以下示例演示了应用于mybatis的代码生成使用。
1.首先下载easygen发布包 下载
解压后,包含以下几部分:
- easygen-1.0-SNAPSHOT.jar:这是easygen主程序,负责读取配置文件并生成代码
- config.json:这是easy主配置文件
- modelBuildrs:这里存放的是模型构建器的配置文件
- templates:这是里存放的是模板文件
- lib:这里存放的是easygen引用的第三方jar包
2.编写主配置文件
目录下的config.json为主配置文件, 发布包已经给出了一个比较完整的配置,包括型构建器配置和模板配置,包括生成bean、mapperclass、mapperxml、serviceInterface、serviceImpl、view、dbtojson(生成数据库元数据)很简单自己看配置和代码就行了。。。
{
"modelBuilders": [
{
"name": "mysql", //构建器名称要唯一
"type": "db:mysql", //构建器类型目前只支持mysql和json两种
"configPath": "modelBuilders/mysql.json" //数据库配置和生成表指定
},
{
"name": "json",
"type": "json",
"configPath": "modelBuilders/data.json" //与mysql构建器不同的是,这里直接是模型数据。
},
{
"name": "http",
"type": "custom", //自定义的构建器
"configPath": "modelBuilders/xxx.json", //这个json反序列化类型需要在IModelBuilder的泛型参数中指出。
"modelBuilderClassName": "org.BigMaMonkey.XXX.XXX" //自定义的构建器需要实现类,实现IModelBuilder借口
}
],
"templates": [
{
"name": "mapperXml",
"modelBuilderName": "json", //关联的构建器名称,不是类型
"templateFilename": "data.ftl", //ftl模板文件
"outputPath": "output/data", //输出目录,会自动递归创建目录。
"outputFilenameRule": "data_{name}.xml", //输出文件名规则,{}内变量为模型的字段field
"options": {} //自定义模板参数,可以在模板中使用,请自由发挥。
},
{
"name": "mapperXml",
"modelBuilderName": "mysql",
"templateFilename": "mapperXml.ftl",
"outputPath": "output/mapperXml",
"outputFilenameRule": "{upperCaseName}Mapper.xml",
"options": {
"mapperns": "org.bigmonkey.robot.mapper",
"pons": "org.bigmonkey.robot.entity.po"
}
},
{
"name": "beanClass",
"modelBuilderName": "mysql",
"templateFilename": "beanClass.ftl",
"outputPath": "output/bean",
"outputFilenameRule": "{upperCaseName}.java",
"options": {
"pons": "org.bigmonkey.robot.entity.po"
}
},
{
"name": "mapperClass",
"modelBuilderName": "mysql",
"templateFilename": "mapperClass.ftl",
"outputPath": "output/mapper",
"outputFilenameRule": "{upperCaseName}Mapper.java",
"options": {
"pons": "org.bigmonkey.robot.entity.po",
"mpns": "org.bigmonkey.robot.mapper"
}
},
{
"name": "serviceInterface",
"modelBuilderName": "mysql",
"templateFilename": "serviceInterface.ftl",
"outputPath": "output/service",
"outputFilenameRule": "I{simpleName}Service.java",
"options": {
"pons": "org.bigmonkey.robot.entity.po",
"itns": "org.bigmonkey.robot.service"
}
},
{
"name": "serviceImpl",
"modelBuilderName": "mysql",
"templateFilename": "serviceImpl.ftl",
"outputPath": "output/service",
"outputFilenameRule": "{simpleName}ServiceImpl.java",
"options": {
"pons": "org.bigmonkey.robot.entity.po",
"imns": "org.bigmonkey.robot.service.impl"
}
},
{
"name": "view",
"modelBuilderName": "mysql",
"templateFilename": "view.ftl",
"outputPath": "output/view",
"outputFilenameRule": "{name}view.vue",
"options": {}
},
{
"name": "db-to-json",
"modelBuilderName": "mysql",
"templateFilename": "dbtojson.ftl",
"outputPath": "output/json",
"outputFilenameRule": "{name}.json",
"options": {}
}
]
}
3.编写模板
其实模板的编写很简单,你只需要掌握freemarker的ftl语法,以及基本的json知识就可以了。
这里只讲解mybatis内置构建器的使用
3.1.首先是构建器配置
{
"name": "mysql", //构建器名称要唯一
"type": "db:mysql", //构建器类型目前只支持mysql和json两种
"configPath": "modelBuilders/mysql.json" //数据库配置和生成表指定
}
type中db:mysql指定使用内置的mysql构建器,configPath指定构建器的配置文件,配置如下:
{
"dbUrl": "jdbc:mysql://localhost:3306/device_manage",
"driverClassName": "com.mysql.jdbc.Driver",
"username": "root",
"password": "root",
"tables": "sys_user,pub_dict" //用,分割指定生成的表名,也可以留空表示生成所有表
}
3.2.需要给出的是内置mysql构建器的模型结构,你才能在ftl中使用
{
"name": "sys_user", //原始表名
"upperCaseName": "SYS_User", //前缀大写+首字符大写表名,用于创建PO、Mapper等
"simpleName": "User", // 去掉前缀的表名,目前只支持_分割的表名,如sys_user
"pkgs": [
"java.util.Date" // 字段类型对应的Java包,import到java文件
],
"fields": [
{
"name": "name", //原始字段名
"upperCaseName": "Name", //首字母大写字段名
"dataType": "12", // 字段类型值,对应 java.sql.Types中的枚举值
"typeName": "VARCHAR", //字段数据库类型,其他类型参见源码:TableField.java
"columnSize": "32", //字段大小
"columnType": {
"javaType": "String", //对应的java类型
"pkg": null //基础类型为null,不需要import
}
}
],
"primaryKey": {
//同field中的元素属性
}
}
在ftl中模型的跟是model,例如你要在ftl中输出一个表名${model.name}, 又或者是主键的名称${model.primaryKey.name}
如果你在模板配置中设置了自定义模板参数options,请这样使用它${options.xxx}
通过在outputFilenameRule中使用{XXX}可以引用model中根属性,来自定义输出文件名,如{upperCaseName}Mapper.java
4.最后使用方式相当简单:
java -jar easygen-1.0-SNAPSHOT.jar
当然你也可以把代码的执行集成到你自己的项目或工具:
public class App {
public static void main(String[] args) {
GeneratorManager generatorManager = new GeneratorManager();
try {
generatorManager.Start();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
easygen通用代码生成框架[开源]的更多相关文章
- gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架
gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架 gRPC:Google开源的基于HTTP/2和ProtoBuf的通用RPC框架 Google Guava官方教程(中文版 ...
- 开源通用爬虫框架YayCrawler-开篇
各位好!从今天起,我将用几个篇幅的文字向大家介绍一下我的一个开源作品--YayCrawler,其在GitHub上的网址是:https://github.com/liushuishang/YayCraw ...
- fieldmeta 基于springboot的字段元数据管理,通用代码生成,快速开发引擎
fieldmeta: 基于springboot的字段元数据管理 version:Alpha 0.0.1 ,码云地址:https://gitee.com/klguang/fieldmeta 元数据(Me ...
- 各种Android UI开源框架 开源库
各种Android UI开源框架 开源库 转 https://blog.csdn.net/zhangdi_gdk2016/article/details/84643668 自己总结的Android开源 ...
- 60.Android通用流行框架大全
转载:https://segmentfault.com/a/1190000005073746 Android通用流行框架大全 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的 ...
- 看过《大湿教我写.net通用权限框架(1)之菜单导航篇》之后发生的事(续)——主界面
引言 在UML系列学习中的小插曲:看过<大湿教我写.net通用权限框架(1)之菜单导航篇>之后发生的事 在上篇中只拿登录界面练练手,不把主界面抠出来,实在难受,严重的强迫症啊.之前一直在总 ...
- .net通用权限框架B/S(一)
一直做软件实施,用过一些二次开发平台,最近看了一些大神写的框架,于是参考写了一个B/S通用权限框架,项目使用MVC4+EF5+EASYUI(.net framework4),开发环境vs2010+sq ...
- .net通用权限框架C/S概览
通用权限框架cs部分 先概述一下,cs使用vs2010+sql2008 和bs公用同一个数据库 为使界面好看使用了第三方控件 donetbar和devexpress,正版是要收费的,但是你们都明白的可 ...
- .net通用权限框架B/S (五)--WEB(3)组织机构
.net通用权限框架B/S 首先我们看导航菜单中,对组织机构的设置 我们设置了组织机构名称,链接(对应的mvc控制器名/orga),图标是个小钥匙,菜单的操作权限设置的是"添加,编辑,删除& ...
随机推荐
- JS模式--装饰者模式(用AOP动态改变函数的参数)
Function.prototype.before = function (beforefn) { var _self = this; return function () { beforefn.ap ...
- 【转】QQ传输文件原理参考(来自互联网)
QQ的文件发送是怎样的过程呢?通常,发送文件的计算机首先要通过消息服务器将其IP地址发送给接收计算机,当接收计算机同意接收的确认消息反馈到消息服务器后,消息服务器将据此设置好文件传输对话.随即,发送计 ...
- hadoop集群搭建--CentOS部署Hadoop服务
在了解了Hadoop的相关知识后,接下来就是Hadoop环境的搭建,搭建Hadoop环境是正式学习大数据的开始,接下来就开始搭建环境!我们用到环境为:VMware 12+CentOS6.4 hadoo ...
- 【lucene系列学习二】Lucene实现高亮显示关键词
首先,导入下图所示库 然后,import org.apache.lucene.search.highlight.*; 下面,我们新建一个实现高亮显示功能的函数 public static String ...
- 微坑---微信小程序ios上时间字符串转换为时间戳时,在开发工具上和安卓手机上运行成功
给定一个时间字符串 var time="2017-02-27 16:42:53" js有三种转换为时间戳的方法:1.var timestamp = Date.parse(time ...
- 产品经理学Python:参数传递方式
这是关于Python的第5篇文章,主要介绍下参数传递方式和如何设计自己的函数. (一) 本篇主要介绍2种参数传递方式. 位置参数 调用函数时,根据函数定义的参数位置来传递参数. def right_t ...
- Redis 基本安全规范文档
温馨提示:我在一家手游的公司工作,因为经常用到redis,特为此整理文档(借鉴过大神的文章): 一.什么是redis(出自百度百科)? redis是一个key-value存储系统.和Memcached ...
- EmpyoyeeManger_1.0
整体结构 首先创建一个名为employee的数据库 create database employee; 然后在该数据库下建一张表 CREATE TABLE t_emp( id BIGINT PRIMA ...
- 结构体的vector resize()与初始化
序: 我们在使用vector的时候可以自定义里面的数据类型.例如这样: struct Edge{ int from; int to; int weight; }; vector<Edge> ...
- AngularJS的相关应用
一.[AngularJS常用指令] 1.ng-app:声明Angular所管辖的区域.一般写在body或html上,原则上一个页面只有一个: <body ng- ...