什么是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();
        }


    }
}