引言
“我不是在教你学坏,而是教你如何提高生产效率。” ----------- 牛顿
人类社会能够一直进步发展出现在的文明世界,最大的一个原因就是这个世界上懒人居多,懒人为了偷懒就需要提高生产效率,效率提高节省下来的时间才能创造出艺术、娱乐以及更高效率的科学技术。程序员们如何提高生产效率?创造一个自己为自己干活!
今天给大家介绍一个代码生成神器Velocity,Velocity作为一款基于Java的强大模板引擎,其拥有简洁的设计和强大的功能,新手也能很快上手。从此以后你就可以摆脱无聊且繁杂的crud代码,给自己留下诗和远方的闲暇时光。
效果展示
话不多说,以下截图是我利用Velocity写的一个代码生成的工具,支持Mysql或Pgsql两种数据库。新项目开发的时候,你只需要设计好你的表结构,在界面上填写包名、地址后缀、模块名等信息即可。剩下的事情交给Velocity,它会帮你完成从controller、service、dao的所有通用接口。
生成代码压缩包里的目录结构,前后端代码都有。
以下是适用于Mybatis框架的Velocity模板生成的代码文件。Velocity的优点之一就是它将生成代码需要的数据模型与模板解耦,所以对模板的修改可以做到非常的丝滑,数据模型做好了基本上不用做大的调整,剩下的就是DIY自己的模板文件。
也许有人会质疑说,idea中不是有很多代码生成插件吗?我认为别人写的总归没有那么灵活,我自己决定使用Velocity也是因为工作中遇到了一个开源项目需要二开,在使用别人的个性化框架期间,一个一个新建Java文件太费鼠标了,所以我才决定自己写一套模板。
Velocity
Velocity的核心理念是遵循Model-View-Controller(MVC)设计模式,它致力于将视图逻辑与业务逻辑彻底分离。它允许前端开发者使用一种专门的语法来引用预定义好的数据模型,而无需直接编写Java代码。这种设计不仅极大地简化了前端开发者的工作量,也使得后端开发者能够专注于后端逻辑的优化与实现,两者并行工作,极大地提升了开发效率。
Maven 依赖如下:
<properties>
<velocity-tools-version>2.0</velocity-tools-version>
</properties>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>${velocity-tools-version}</version>
</dependency>
Velocity原理
Velocity引擎的工作流程大致如下:
-
开发者创建包含占位符和控制结构的模板文件;
-
这些模板通过Velocity引擎解析时,引擎会根据提供的数据模型动态替换模板中的占位符;
-
生成所需的HTML页面、Java文件或任何其他类型的输出文件。
Hello Velocity World!
<html>
<body>
#set( $foo = "Velocity" )
Hello $foo World!
</body>
<html>
输出结果:
Hello Velocity World!
代码实际上很简单,声明了一个 foo 的变量,给它赋值 "Velocity", 在 body 中显示 “Hello $foo World! ”,Velocity 会将 foo 变量的值替换为 "Velocity"。
以上就是一个使用 Velocity 模板语言(VTL) 的简单应用。VTL 主要是采用引用的方式将动态的内容嵌入到输出文件里面。
建议点赞+收藏+关注,方便以后复习查阅。
语法
VTL 语法主要分为四种:
-
引用。通过 ${variableName} 的方式引用一个变量的属性或者方法;
-
控制。提供一些逻辑分支或者遍历的控制命令,如 #if, #else, #elseif, #foreach 等。
-
导入与包含。大型项目中,Velocity允许在模板之间进行内容的复用和模块化设计,如 #parse 和 #include 指令;
-
宏定义。宏可以封装一段逻辑或输出格式,供模板多次调用以减少重复代码。
注释
单行注释:
## 我是IT果果日记。
多行注释:
#*
我是IT果果日记
我来自东土大唐
要去往西天拜佛求经
*#
引用
引用的简单语法可以写作 $+标识符
的格式。标识符必须以字母开头并区分大小写,剩下的标识符由以下几种类型组成:
-
字母 (a .. z, A .. Z)
-
数字 (0 .. 9)
-
下划线 ("_")
-
连字符("-")
引用的变量都会处理成字符串对象,例如一个整形对象,Velocity 会调用其 toString() 方法将其转化为字符串。
Velocity 里的引用分为三种类型:
-
变量。
-
属性。
-
方法。
变量的引用:
$itguoguo
属性的引用:
## 这里的属性Money既可以是属性的引用,也可以是getMoney()方法的引用,由Velocity来决定是哪一个引用。
$itguoguo.Money
方法的引用:
## 方法的引用格式:$+标识符+方法体
$itguoguo.getMoney()
$itguoguo.setMoney( "1,0000,0000¥" )
$itguoguo.setWifies( ["刘亦菲", "董璇", "夏思凝"] )
此外还有两种特殊的引用:形式引用(Formal Reference Notation)和安静引用(Quiet Reference Notation)。
形式引用常用于引用与文本相邻的情况。例如,我要显示"I have one billionRMB",我可以写成"I have one {unit}RMB"。
## 形式引用
${itguoguo.getMoney()}
${itguoguo.setMoney( "1,0000,0000¥" )}
${itguoguo.setWifies( ["刘亦菲", "董璇", "夏思凝"] )}
安静引用常用于引用变量不存在的情况。
## 普通引用,Velocity返回值:$money
<input type="text" name="money" value="$money"/>
## 安静引用,Velocity返回空字符串
<input type="text" name="money" value="$!money"/>
控制
If / ElseIf / Else 代码示例
## foo为空或者false,表达式判定为假,不会输出内容
#if( $foo )
<div>Hello ITGuoGuo!</div>
#end
## If / ElseIf / Else
#if( $foo < 5 )
<div>up</div>
#elseif( $foo == 5 )
<div>down</div>
#elseif( $bar == 6 )
<div>left</div>
#else
<div>right</div>
#end
Velocity 将在第一个为真的表达式停止并输出内容。
&& / || / ! 代码示例
#if( $foo && $bar )
<div>逻辑与</div>
#end
#if( $foo || $bar )
<div>逻辑或</div>
#end
#if( !$foo )
<div>逻辑非</div>
#end
逻辑非与安静引用里的 ! 容易混淆,逻辑非的 ! 用在 之后。
foreach 代码示例
## names 可以是一个列表或数组
<ul>
#foreach( $name in $names )
<li>$name</li>
#end
</ul>
## people 可以是一个键值对
<ul>
#foreach( $key in $people.keySet() )
<li>Key: $key -> Value: $people.get($key)</li>
#end
</ul>
## Velocity 还可以在循环里使用计数缺省变量 $velocityCount,从1开始计数。
<table>
#foreach( $person in $people )
<tr><td>$velocityCount</td>
<td>$person.Name</td></tr>
#end
</table>
Velocity 默认为 foreach 指令提供了计数变量 $velocityCount ,从1开始计数。也可以在 velocity.properties 文件中配置计数起始的位置。例如下面的配置:
## 循环计数变量名默认 velocityCount
directive.foreach.counter.name = velocityCount
## 循环计数默认起始位从0开始
directive.foreach.counter.initial.value = 0
包含/解析
include 代码示例
#include( "ItGuoGuo.txt" )
ItGuoGuo.txt 文件将被插入到 #include 指令被定义的位置;
ItGuoGuo.txt 文件不会被 Velocity 解析,如果需要的引入文件被解析可以使用 parse 指令;
include 引入的文件必须是配置参数 TEMPLATE_ROOT 所定义目录下的,默认为当前目录。
## 引入多个文件使用逗号分隔
#include( "ItGuoGuo1.gif","ItGuoGuo2.txt","ItGuoGuo3.htm" )
## 引用文件名最好使用变量,例如 $ItGuoGuoReference
#include( "ItGuoGuo.txt", $ItGuoGuoReference )
parse 代码示例
#parse( "ItGuoGuo.vm" )
ItGuoGuo.vm 将被 Velocity 解析,即 ItGuoGuo.vm 可以是静态文件也可以是动态文件;
parse 指令只有一个参数;
parse 引入的文件必须是配置参数 TEMPLATE_ROOT 所定义目录下的,默认为当前目录。
下面是由两个 vm 文件共同完成的逻辑,首先是主文件 main.vm:
main.vm 倒计时开始
#set( $cnt = 10 )
#parse( "parsed.vm" )
main.vm 倒计时完成!
主文件申明了一个 cnt 变量,将在 parsed.vm 文件中做递减处理:
$cnt
#set( $cnt = $cnt - 1 )
#if( $cnt > 0 )
#parse( "parsed.vm" )
#else
parsed.vm 倒计时完成!
#end
程序首先进入 main.vm 申明一个 cnt 变量,通过引入 parsed.vm 文件递归执行递减操作,当 cnt 变量递减为0时打印 “parsed.vm 倒计时完成!” ,最后回到 main.vm 打印 “main.vm 倒计时完成!”
停止
stop 代码示例
#stop
stop 指令会停止模板引擎的执行,通常用作代码调试。
宏
macro 指令示例
#macro( emptytd )
<tr><td></td></tr>
#end
#emptytd()
定义一个名为 emptytd 的宏,然后执行它,就会显示一行空表格。
#macro( colorrows $color $texts )
#foreach( $text in $texts )
<tr><td bgcolor=$color>$text</td></tr>
#end
#end
定义一个名为 colorrows 的宏,第一个参数表示颜色,第二个参数表示表格里的内容。
#set( $list = ["one","two","three","four","five"] )
#set( $color = "red" )
<table>
#tablerows( $color $list )
</table>
调用 colorrows 这个宏,传递两个参数,注意变量 texts,输出如下:
<table>
<tr><td bgcolor="red">one</td></tr>
<tr><td bgcolor="red">two</td></tr>
<tr><td bgcolor="red">three</td></tr>
<tr><td bgcolor="red">four</td></tr>
<tr><td bgcolor="red">five</td></tr>
</table>
宏一般用来在多个模板中共享,这样可以减少模板内的重复工作量,也减少了出错的机率。
转义
Velocity 的指令使用 $ 和 # 开头,如果在模板里需要使用这两个特殊字符,需要做转义处理。
I have $1000000000!
I have $money!
money 是否需要转义要看你想输出 money 这个变量还是 “money” 这个字符串。
#set( $money = "1,000,000,000" )
I have $money!
I have \$money!
输出结果如下:
I have 1,000,000,000!
I have $money!
还有一种情况是引用变量的值需要转义,可以使用 Velocity 的扩展工具 EscapeTool,Maven 依赖如下:
<dependency>
<groupId>org.apache.velocity.tools</groupId>
<artifactId>velocity-tools-generic</artifactId>
<version>3.1</version>
</dependency>
代码生成
前面提到过 Velocity 生成代码的原理是将数据模型和模板合并,输出指定格式的文件。下面我们就来自己动手利用 Velocity 写一个生成代码的小工具。
数据模型
首先需要定义自己的数据模型,因为我们写的这个工具是用来生成 crud 代码的,所以数据模型里的字段主要就是表的元信息。表的元信息实体类如下:
列的元信息实体类如下:
定义好数据模型之后,我们需要调用数据库查找这些信息。以 Mysql 为例:
模板文件
多个模板文件可以共用一套数据模型,当前我们以生成实体类文件为例,实体模板如下:
合并生成
最后是将数据模型合并到模板文件,生成代码文件:
参考
velocity中文文档 wizardforcel.gitbooks.io/velocity-do…
建议点赞+收藏+关注,方便以后复习查阅。