1.velocity简介 velocity是⼀个基于Java的模板引擎,可以通过特定的语法获取在Java对象的数据,填充到模板中,从⽽实现界⾯和Java代码的分离。这意味着可以使⽤velocity替代jsp的开发模式了,这使得前端开发⼈员可以和 Java 程序开发⼈员同步开发⼀个遵循 MVC 架构的 web 站点,在实际应⽤中,velocity还可以应⽤于很多其他的场景。
2.应⽤场景web应⽤程序:作为应⽤程序的视图,展⽰数据。源代码⽣成:velocity可⽤于基于模板⽣成Java源代码。⾃动电⼦邮件:⽹站注册,认证等的电⼦邮件模板。⽹页静态化:基于velocity模板,⽣成静态⽹页。
3.velocity组成结构velocity主要分为app、context、runtime和⼀些辅助util⼏个部分
app模块:主要封装了⼀些接⼝,暴露给使⽤者使⽤,主要有两个类,分别是Velocity(单例)和VelocityEnginecontext模块:主要封装了模板渲染需要的变量
runtime模块:整个velocity的核⼼模块,runtime模块会将加载的模块解析成语法树,velocity调⽤mergeTemplate⽅法时会渲染整棵树,并输出最终的渲染结果
runtimeInstance类为整个velocity渲染提供了⼀个单例模式,拿到了这个实例就可以完成渲染过程了
4.快速⼊门4.1 需求分析使⽤velocity定义HTML模板,将动态数据填充到模板中,形成⼀个完整的HTML页⾯
4.2 步骤分析(1)创建项⽬(2)引⼊依赖(3)定义模板(4)输出html
4.3 velocity⼊门程序创建maven项⽬,然后引⼊如下依赖
在templates⽬录下新建⼀个模板⽂件 demo1.vm,内容如下:
hello,${name}!
编写测试类,使⽤velocity⽣成html⽂件
@Test
public void test1() throws IOException { // 1.设置velocity的资源加载器
Properties properties=new Properties();
properties.put(\"file.resource.loader.class\ // 2.初始化velocity引擎 Velocity.init(properties); // 3.创建velocity容器
VelocityContext context=new VelocityContext(); context.put(\"name\张三\"); // 4.加载模板⽂件
Template template = Velocity.getTemplate(\"templates\\\\demo1.vm\ // 5.合并数据到模板
FileWriter fw=new FileWriter(\"D:\\\\idea_code\\\\cat-movie-main\\\\cat-movie-main\\\\movie-server\\\\src\\\\main\\\\resources\\\\static\\\\demo1.html\"); template.merge(context,fw); // 6.释放资源 fw.close(); }
执⾏单元测试,就可以看到static⽬录下⽣成了demo1.html,并且数据显⽰
5.基础语法5.1 VTL介绍Velocity Template Language(VTL),是velocity中提供的⼀种模板语⾔,旨在提供最简单和最⼲净的⽅法来将动态内容合并到⽹页中,简单来说VTL可以将程序的动态数展⽰到⽹页中。VTL语法分为四⼤类:注释、⾮解析内容、引⽤和指令
5.2 注释注释的内容不会被输出1.单⾏注释
## ⾏注释内容
2.多⾏注释
#*
*多⾏注释1*多⾏注释2*#
3.⽂档注释
#**
*⽂档注释**#
5.3 ⾮解析内容⾮解析内容会原样输出
#[[
⾮解析内容${name}]]#
5.4 引⽤5.4.1 变量引⼊引⽤语法就是对引擎上下⽂对象中的属性进⾏操作,语法⽅⾯分为常规语法($属性)和正规语法(${属性})$变量名,若上下⽂中没有对应的变量,则输出字符串$变量名${变量名},若上下⽂中没有对应的变量,则输出字符串${变量名}$!变量名,若上下⽂中没有对应的变量,则输出空字符串\"\"$!{变量名},若上下⽂中没有对应的变量,则输出空字符串\"\"
5.4.2 属性引⽤$变量名.属性,若上下⽂中没有对应的变量,则输出字符串$变量名.属性${变量名.属性},若上下⽂中没有对应的变量,则输出字符串${变量名.属性}$!变量名.属性,若上下⽂中没有对应的变量,则输出空字符串\"\"$!{变量名.属性},若上下⽂中没有对应的变量,则输出空字符串\"\"
5.4.3 ⽅法引⽤$变量名.⽅法([⼊参1[,⼊参2]*]?),常规写法${变量名.⽅法([⼊参1[,⼊参2]*]?)},正规写法$!变量名.⽅法([⼊参1[,⼊参2]*]?),常规写法$!{变量名.⽅法([⼊参1[,⼊参2]*]?)},正规写法
5.5 指令#set
作⽤:在页⾯中声明变量语法:#set($变量=值)
#set($number=10)
#set($str=\"hello world $number\")${str}
#if/#elseif/#else作⽤:进⾏逻辑判断语法:
#if(判断条件)……
#elseif(判断条件)……#else……#end
具体实例
#set($language=\"java\")
#if($language.equals(\"java\"))java开发⼯程师
#elseif($language.equals(\"php\"))php开发⼯程师#else
开发⼯程师#end
#foreach($item in items)作⽤:遍历循环数组或者集合
#foreach($item in $items) …… [break]#end
$items:需要遍历的对象或者集合,如果items的类型为map集合,那么遍历的是map的value$item:变量名称,代表遍历的每⼀项#break:退出循环
内置属性:$foreach.index:获取遍历的索引,从0开始,$foreach.count:获取遍历的次数,从1开始
#foreach($item in $hobbies) $item #break#end
#evaluate
作⽤:动态计算,动态计算可以让我们在字符串中使⽤变量语法:#evaluate(\"计算语句\")可以将服务端的代码直接解析#include
作⽤:引⼊外部资源,引⼊的资源不会被引擎解析语法:#include(resources)
resources可以为单引号或者双引号的字符串,也可以为$变量,内容为外部资源路径注意:路径如果为相对路径,则以引擎配置的⽂件加载器加载路径作为参考#parse
作⽤:引⼊外部资源,引⼊的资源将会被引擎解析语法:#parse(resources)
注意:路径如果为相对路径,则以引擎配置的⽂件加载器加载路径作为参考#define
作⽤:定义重⽤模块语法:
#define($模块名称) 模块内容#end
使⽤的时候直接 $模块名称宏指令
作⽤:定义重⽤模块(可带参数)语法:定义语法:
#macro(宏名 [$arg]?) ……#end
调⽤语法:
#宏名([$arg]?)
实例:
#macro(table $hobbies)
#foreach($item in $hobbies) $item #end#end
#table($hobbies)
6.⽣成代码6.1 定义模板创建controller模板 Controller.java.vm
package ${package}.controller;
import ${package}.entity.${className};import ${package}.entity.ResultData;
import ${package}.service.${className}Service;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;import java.util.List;
@RestController
@RequestMapping(\"/${classname}\")public class ${className}Controller {
@Resource
private ${className}Service ${classname}Service;
/**
* 查询列表 *
* @param name * @param addr * @return */
@GetMapping(\"/list\")
public ResultData getList(String name, String addr, Integer page, Integer limit, HttpServletRequest r ) { return ${classname}Service.getList(name, addr, page, limit); }
/**
* 根据电影名称查询影院信息 *
* @param name * @return */
@GetMapping(\"/index\")
public ResultData getIndexList(String name) {
List<${className}> list = ${classname}Service.getIndexList(name); return new ResultData(true, \"查询成功\ }
/**
* 修改信息 *
* @param ${classname} * @return */
@PostMapping(\"/edit\")
public ResultData updateInfo(@RequestBody ${className} ${classname}) { int count = ${classname}Service.updateInfo(${classname}); if (count == 0) {
return new ResultData(false, \"操作失败\"); } else {
return new ResultData(true, \"操作成功\"); } }
/**
* 添加信息 *
* @param pojo * @return */
@PostMapping(\"/add\")
public ResultData addInfo(@RequestBody ${className} ${classname}) { int count = ${classname}Service.addInfo(${classname}); if (count == 0) {
return new ResultData(false, \"操作失败\"); } else {
return new ResultData(true, \"操作成功\"); } }
/**
* 根据id删除信息 *
* @param ids * @return */
@PostMapping(\"/del\")
public ResultData deleteById(@RequestParam(\"ids\") List View Code 创建service模板 Service.java.vm package ${package}.service; import ${package}.entity.${className};import ${package}.entity.ResultData;import java.util.List; public interface ${className}Service { ResultData getList(String name, String addr, Integer page, Integer limit); int updateInfo(${className} ${classname}); int addInfo(${className} ${classname}); void deleteById(List List<${className}> getIndexList(String name);} View Code 创建serviceImpl模板 ServiceImpl.java.vm package ${package}.service.impl; import cn.hutool.core.util.StrUtil; import com.github.pagehelper.PageHelper;import com.github.pagehelper.PageInfo;import ${package}.dao.${className}Dao;import ${package}.entity.${className};import ${package}.entity.ResultData; import ${package}.service.${className}Service;import org.springframework.stereotype.Service;import tk.mybatis.mapper.entity.Example;import javax.annotation.Resource;import java.util.List; @Service public class ${className}ServiceImpl implements ${className}Service { @Resource private ${className}Dao ${classname}Dao; @Override public ResultData getList(String name, String addr, Integer page, Integer limit) { if (page != null && limit != null) { PageHelper.startPage(page, limit); } Example example = new Example(${className}.class); Example.Criteria criteria = example.createCriteria(); if (StrUtil.isNotBlank(name)) { criteria.andLike(\"name\ } if (StrUtil.isNotBlank(addr)) { criteria.andLike(\"addr\ } List<${className}> list = ${classname}Dao.selectByExample(example); // 是否分页查询 if (page != null && limit != null) { PageInfo<${className}> pageInfo = new PageInfo(list); return new ResultData(true, \"查询成功\ } else { return new ResultData(true, \"查询成功\ } } @Override public int updateInfo(${className} ${classname}) { return ${classname}Dao.updateByPrimaryKeySelective(${classname}); } @Override public int addInfo(${className} ${classname}) { return ${classname}Dao.insertSelective(${classname}); } @Override public void deleteById(List ids.stream().forEach(item -> ${classname}Dao.deleteByPrimaryKey(item)); } } @Override public List<${className}> getIndexList(String name) { return ${classname}Dao.getIndexList(name); }} View Code 创建dao模板 Dao.java.vm package ${package}.dao; import ${package}.entity.${className};import tk.mybatis.mapper.common.Mapper;import java.util.List; public interface ${className}Dao extends Mapper<${className}> { List<${className}> getIndexList(String name);} View Code 6.2 编写⼯具类编写⽣成Java⽂件⼯具类 package com.zxh.movieserver.util; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils;import org.apache.velocity.Template; import org.apache.velocity.VelocityContext;import org.apache.velocity.app.Velocity;import java.io.File; import java.io.FileWriter;import java.io.IOException;import java.io.StringWriter;import java.util.List;import java.util.Map; import java.util.Properties;import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * @Author Eric * @Date 5/26/2021 5:12 PM */ public class GenUtils { /** * ⽣成Java代码 * @param data ⽣成到模板中的数据 * @param templates 模板名称 * @param */ public static void generatorCode(Map Properties properties=new Properties(); properties.put(\"file.resource.loader.class\ // 2.初始化velocity引擎 Velocity.init(properties); // 3.创建velocity容器 VelocityContext context=new VelocityContext(data); // 4.加载模板⽂件 //遍历模板列表,获取每⼀个模板 for (String template : templates) { Template tpl = Velocity.getTemplate(template, \"utf-8\");// StringWriter sw=new StringWriter();// // 5.合并数据到模板// tpl.merge(context,sw); String fileName = genFileName(template, data.get(\"className\").toString(), data.get(\"package\").toString()); try { FileWriter fileWriter=new FileWriter(file+File.separator+fileName); tpl.merge(context,fileWriter); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } // try { // zip.putNextEntry(new ZipEntry(fileName));// IOUtils.write(sw.toString(),zip,\"UTF-8\");// IOUtils.closeQuietly(sw);// zip.flush(); // zip.closeEntry(); // } catch (IOException e) {// e.printStackTrace();// } } } /** * 根据模板名称,类名称,包名称拼接⼀个完整的⽂件路径和名称 * @param template 模板名称 * @param className 类名称 * @param packageName 包名称 * @return */ public static String genFileName(String template,String className,String packageName){ String packagePath=\"main\"+ File.separator+\"java\"+File.separator; if(StringUtils.isNotEmpty(packageName)){ packagePath+=packageName.replace(\".\ } if(template.contains(\"Controller.java.vm\")){ return packagePath+\"controller\"+File.separator+className+\"Controller.java\"; } if(template.contains(\"Service.java.vm\")){ return packagePath+\"service\"+File.separator+className+\"Service.java\"; } if(template.contains(\"ServiceImpl.java.vm\")){ return packagePath+\"service\"+File.separator+\"impl\"+File.separator+className+\"ServiceImpl.java\"; } if(template.contains(\"Dao.java.vm\")){ return packagePath+\"dao\"+File.separator+className+\"Dao.java\"; } return null; }} View Code 6.3 单元测试运⾏测试类就可以⽣成相关代码 package com.zxh.movieserver; import com.zxh.movieserver.util.GenUtils;import org.junit.jupiter.api.Test;import java.awt.*;import java.io.File; import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; import java.util.zip.ZipOutputStream;/** * @Author Eric * @Date 5/26/2021 5:52 PM */ public class Test4 { @Test public void test1() throws FileNotFoundException { Map List File file=new File(\"D:\\\\idea_code\\\\cat-movie-main\\\\cat-movie-main\\\\movie-server\\\\src\\\\\");// FileOutputStream fileOutputStream=new FileOutputStream(file); // ZipOutputStream zipOutputStream=new ZipOutputStream(fileOutputStream); GenUtils.generatorCode(map,list,file); }} View Code 因篇幅问题不能全部显示,请点此查看更多更全内容