目录
什么是velocity
也就是前端程序员写velocity模板,后端程序员写数据模型,最后整合就是展示给用户的东西
应用场景
组成结构
快速入门
以上就是创建了一个maven项目
我们要在项目中使用velocity,所以要导入对应的依赖
<dependencies>
<!-- velocity 的核心包-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<!-- 进行单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
以上是导入依赖。
现在开始创建模板,这个模块在什么地方都可以,最后只要路径对了就可以,我们习惯放到resources文件夹下
以上先创建一个HTML模板,之后修改这个文件的后缀,变为vm
以上是最简单的语法。
之后我们要写测试类,里面调用这个vm文件,将数据写到这个vm里面
public class quickstart {
@Test
public void test1() throws IOException {
// 1 设置velocity 的资源加载器
Properties properties = new Properties();
// 固定的写法
properties.put("file.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 2 初始化velocity引擎
Velocity.init(properties);
// 3 创建velocity的容器
VelocityContext velocityContext = new VelocityContext();
// 这个容器里面要放一些数据
velocityContext.put("name","jing");
// 4 加载velocity的模板文件
Template template = Velocity.getTemplate("vms/01-quickstart.vm", "utf-8");
// 5 合并数据到模板
FileWriter fileWriter = new FileWriter("D:\\javacode\\velocity_01\\src\\main\\resources\\html\\01quick.html");
template.merge(velocityContext,fileWriter);
// 6 释放资源
fileWriter.close();
}
}
执行完以上的语句,那么在新的文件夹下,就会生成一个HTML文件
总结
就是前端写velocity模板,后端写代码,将数据填充到模板里面,生成HTML文件
以后就是 填充的内容需要是动态的,使用的模板是动态的,输出的HTML的路径是动态的,其他的都是固定的。
基本语法
也就是根据这些语法,我们可以将在context里面的内容填充到模板中
注释
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
## 这个是单行注释
#*
* 这个是多行注释
*
* *#
#**
* 这个是文档注释
* *#
你好,${name},我是好人
</body>
</html>
在vm文件里面,写的注释,最后生成HTML文件,是不会出现在HTML里面的,但是会用空区域代替
有注释的地方,在HTML里面会有很多的空区域
非解析内容
也就是在模板里面写的什么,最后在HTML里面就会展示什么
引用
变量引用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>引用变量</h1>
常规语法:$name11
正规语法:${name11}
常规语法: $!name11
正规语法 : $!{name11}
</body>
</html>
属性引用
也就是变量是一个对象,我们想要对象里面的属性,所以这个就是属性引用
方法引用
指令
流程控制指令
#set 指令
模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
$user.username --- $user.password
$str.split(" ")
$now.getTime()
## 定义变量
#set($str = "hello")
#set($int = 10)
#set($arr = ["10","12"])
#set($boolean = true)
#set($map = {"key1":"values"})
#set($name = "jing")
#set($strt = "你好 $name")
## 获取变量
$str
$int
$arr
$boolean
$map.key1
$name
$strt
</body>
</html>
生成的HTML
#if/#elseif/#else
模板
#set($language = "java")
#if($language.equals("java"))
java
#elseif($language.equals("python"))
python
#end
生成的HTML
#foreach
在velocity里面存放list数据
ArrayList<String> strings = new ArrayList<>();
strings.add("152");
strings.add("452");
strings.add("8566");
String[] hobbi = new String[]{"ddd","888","8888"};
velocityContext.put("strings",strings);
velocityContext.put("hobbi",hobbi);
在模板里面进行遍历
#foreach($item in $hobbi)
$item
#end
#foreach($item in $strings)
$item
#end
引入资源指令
include
#include("/vms/01-quickstart.vm")
都没有被解析,直接将引入的模板的里面的东西给复制过来了
parse
#parse("/vms/01-quickstart.vm")
define
这个就是 定义在这个里面的语法,其他的地方就可以使用
evaluate
#evaluate("#if($user.username == 'liujing' ) liuj #else jjj
#end")
宏指令
和 define指令比较,这个是动态的,意思是里面可以拿出变量里面的值
综合案例
需求分析
步骤分析
代码实现
创建一个ssm项目 或者springboot项目,可以实现对数据库的增删改查的项目就可以了,把velocity的依赖也导入
因为我们要生成以上的几层的数据,所以每一层我们都要写一个模板
controller模板
因为是模板,所以controller的前面的东西我们不写,现在我们建立了这个文件,里面开始写controller层的模板
package ${
package}.controller;
import ${
package}.pojo.${
className};
import ${
package}.service.${
className}Service;
## 每个里面都要有
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
/** * @author jing * @date 2020/11/23--12:00 * 一审信息 */
@Controller
@RequestMapping(value = "/${classname}",method = RequestMethod.POST)
public class ${
className}Controller {
@Autowired
private ${
className}Service ${
classname}Service;
/** * 查询列表 * @param * @return */
@RequestMapping("/${classname}list")
@ResponseBody
public List<${
className}> ${
classname}list(){
List<${
className}> ${
classname}s = null;
try {
${
classname}s = ${
classname}Service.list();
return ${
classname}s;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/** * @author * @date * 保存 */
@RequestMapping("/add${classname}")
@ResponseBody
public String add${
classname}(${
className} ${
classname}){
try {
${
classname}Service.save(${
classname});
return "1";
} catch (Exception e) {
e.printStackTrace();
return "0";
}
}
/** * 修改 * @param * @return */
@RequestMapping("/update${className}")
@ResponseBody
public String update${
className}( ${
className} ${
classname}){
try {
${
className}Service.update(${
classname});
return "1";
} catch (Exception e) {
e.printStackTrace();
return "0";
}
}
}
service 模板
package ${
package}.service;
import ${
package}.pojo.${
className};
import java.util.List;
public interface ${
className}Service {
//查询所有的用户信息
List<${
className}> list();
## 保存数据
void save(${
className} ${
classname});
## 更新数据
void update(${
className} ${
classname});
}
serviceimpl 模板
package ${
package}.service.impl;
import ${
package}.mapper.${
className}Mapper;
import ${
package}.pojo.${
className};
import ${
package}.service.${
className}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/** * @Transactional: * 此注解的作用是开启事务管理,相当于我们以前在applicationcontext.xml * 文件中配置的事务管理。 */
@Transactional
@Service
public class ${
className}ServiceImpl implements ${
className}Service {
//声明mapper层属性
@Autowired
private ${
className}Mapper ${
classname}Mapper;
## 查询list
@Override
public List<${
className}> list() {
return ${
classname}Mapper.list();
}
## 保存
@Override
public void save(${
className} ${
classname}) {
return ${
classname}Mapper.save(${
classname});
}
## 更新
@Override
public void update(${
className} ${
classname}) {
return ${
classname}Mapper.update(${
classname});
}
}
mapper 模板
package ${
package}.mapper;
import ${
package}.pojo.${
className};
import java.util.List;
public interface ${
className}Mapper {
//查询所有的用户信息
List<${
className}> list();
## 保存数据
void save(${
className} ${
classname});
## 更新数据
void update(${
className} ${
classname});
}
公共方法
我们已经写完了模板,现在开始写一个公共方法,就是我们代码生成的路径,也就是用这些模板,生成的java文件,我们要放到哪里
public class GenUtils {
/** * @param date 填充到模板中的数据 * @param templates 模板的名称 * @param zip 输出流 * @date 2021/8/25--22:01 */
public static void generatorCode(Map<String,Object> date, List<String> templates, ZipOutputStream zip){
// 1 设置velocity 的资源加载器
Properties properties = new Properties();
// 固定的写法
properties.put("file.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 2 初始化velocity引擎
Velocity.init(properties);
// 3 创建velocity的容器 这个容器里面要放一些数据
VelocityContext velocityContext = new VelocityContext(date);
// 4 加载velocity的模板文件(因为有多个,所以要遍历)
for(String tem:templates){
Template template = Velocity.getTemplate(tem, "utf-8");
// 5 合并数据到模板
// 创建一个输出流
StringWriter stringWriter = new StringWriter();
// 将数据放到输出流里面
template.merge(velocityContext,stringWriter);
// 把代码数据输出到zip文件里面
String fileName = getFileName(tem, date.get("className").toString(), date.get("package").toString());
try {
zip.putNextEntry(new ZipEntry(fileName));
IOUtils.write(stringWriter.toString(),zip,"UTF-8");
IOUtils.closeQuietly(stringWriter);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** * @param template 模板名称,也就是我们要使用哪个模板生成java文件 * @param className 实体类名称 User * @param packageName 包名称 在哪个包下生成 * @date 2021/8/25--22:01 * @return main/java/com/controller/UserController.java * main/java/com/service/UserService.java * main/java/com/service/impl/UserServiceimpl.java * main/java/com/mapper/UserMapper.java */
public static String getFileName(String template,String className,String packageName){
String packagePath = "main"+ File.separator +"java"+ File.separator;
// 如果包名不为空,我们在基础路径上,拼接这个包名
if(StringUtils.isNullOrEmpty(packageName)){
packagePath+= packageName.replace(".",File.separator)+File.separator;
}
// 看传进来的是什么模板,根据不同模板,拼接不同的路径
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("Mapper.java.vm")){
return packagePath+"mapper"+File.separator+className+"Mapper.java";
}
return null;
}
public static void main(String[] args) {
String fileName = getFileName("Controller.java.vm","User","com");
System.out.println(fileName);
}
}
测试类
package com;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.utils.GenUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipOutputStream;
/** * @author * @date 2021/8/25--22:38 */
public class testy {
public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("package","com");
map.put("className","Student");
map.put("classname","student");
ArrayList<String> strings = new ArrayList<>();
strings.add("vm/Controller.java.vm");
strings.add("vm/Mapper.java.vm");
strings.add("vm/Service.java.vm");
strings.add("vm/ServiceImpl.java.vm");
File file = new File("D:\\data\\code.zip");
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
GenUtils.generatorCode(map,strings,zipOutputStream);
try {
zipOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}