题外话:最近搭建ssm框架写项目,重复功能太多,数据库表也很多,于是依靠了代码生成器去提高开发效果,下面是本人正在使用的一个代码生成器,亲测可用,按着步骤来会实现的,相信你一定会受益匪浅!


前言:

我们在写代码的时候,应该已经发现了,如果你还要做另外一个模块,那么它们的基础代码都差不多,虽然我们直接拷备过来修改使用也是可以的。但还是会觉得有点浪费时间,所以我们可以做一个自己生成基础代码的功能,然后我们直接生成,再添加其它的功能即可!没有代码生成器的时候,如果添加用户模型domain,复制IUserService,修改类名,ctrl+f,进行人工替换

而使用了代码生成器就是先定义好模板,然后使用代码自动修改类名,有代码参照模板进行指定内容自动替换

注:写代码生成器前,先把项目进行备份,以免写出问题无法挽回!

 

使用技术:velocity  官网地址 --> http://velocity.apache/

velocity:简单来说就是可以通过我们自定义配置的模板去生成我们想要的东西


可以先用一个临时模型User,进行测试

所需依赖包  (注意:我这里是maven项目的pom文件导入jar包方式)

<dependency>
     <groupId>org.apache.velocity</groupId>
     <artifactId>velocity</artifactId>
     <version>1.7</version>
</dependency>
<dependency>
     <groupId>org.apache.velocity</groupId>
     <artifactId>velocity-tools</artifactId>
     <version>2.0</version>
</dependency>

开发步骤

  1. 准备模板(把每个模块需要改的地方确定好)
  2. 确定所有模板的生成顺序
  3. 确定所有模板的生成位置
  4. 确定要生成的基本功能的domain(User)
  5. 根据Domain名称与模板结合,在相应位置生成文件
  6. 解决如果父文件夹不存在的问题
  7. 解决如果文件已经存在的问题
  8. 排错(有错先改模板)

准备模板

我需要生成多少个文件,我就得准备多少个模板

把所有User对应的文件都拷备一份到相应的位置(并改名为Domain):

(注意:大写与小写的替换)

把模板中的文件进行修改

提示(大家要操作的时候小心小心再小心)

所有的(大写)User换成${Domain}

所有的(小写)user换成${domain}

只留下一个最基础的name字段,其它的多余功能全部去掉

注意(User中关于部门的操作都需要去掉)

替换的位置$不要值不要出现前后空格

这里我就随便放一个模板样例,根据自己项目所需修改自己想要的模板即可 

温馨小提示:这里我没有配置domain类,因为最近我写的项目是MyBatis的ssm框架,所以可以使用MyBatis-Generator代码生成器根据数据库的表生成 --> domain--> mapper接口 --> mapper映射,这里也给个MyBatis-Generator代码生成器的链接:https://blog.csdn/qq_38225558/article/details/85016484

package com.zhengqing.hello.service;

import com.zhengqing.hello.service.IBaseService;
import com.zhengqing.hello.domain.${Domain};

public interface I${Domain}Service extends IBaseService<${Domain}> {

}

像这种情况不管,它只是一个模板而已

确定顺序

确定修改的顺序(这个顺序你根据自己的习惯决定即可)
src/main/java/com/zhengqing/hello/query/DomainQuery.java
src/main/java/com/zhengqing/hello/repository/DomainRepository.java
src/main/java/com/zhengqing/hello/service/IDomainService.java
src/main/java/com/zhengqing/hello/service/impl/DomainServiceImpl.java
src/main/java/com/zhengqing/hello/web/controller/DomainController.java
src/main/test/com/zhengqing/hello/service/DomainServiceTest.java
src/main/webapp/js/model/domain.js
src/main/webapp/WEB-INF/views/domain/domain.jsp

准备路径,完成创建代码  【直接将代码拷贝到自己的项目中修改成自己的路径使用即可!!】

完整代码如下 (已解决了如果文件存在 我们就直接覆盖的问题)

package test;

import com.zhengqing.util.LayuiColumn;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.junit.Test;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class MyEasyCodeUtil {

    /*
     * 代码的生成顺序:
     * rpms-web/src/main/webapp/static/js/model/domain.js
     * rpms-web/src/main/webapp/WEB-INF/views/domain/index.jsp
     * rpms-web/src/main/java/com/zhengqing/hello/web/controller/DoaminController.java
     * rpms-service/src/main/java/com/zhengqing/hello/service/IDomainService.java
     * rpms-service/src/main/java/com/zhengqing/hello/service/impl/DomainServiceImpl.java
     * */

    private String projectPath = "F:\\IT_zhengqing\\IdeaProjects\\TestProject\\";//这里写自己项目的绝对路径

    //准备路径的拼接
    private String[] paths ={
            "rpms-web/src/main/webapp/static/js/model/",
            "rpms-web/src/main/webapp/WEB-INF/views/domain/",
            "rpms-web/src/main/java/com/zhengqing/hello/web/controller/",
            "rpms-service/src/main/java/com/zhengqing/hello/service/",
            "rpms-service/src/main/java/com/zhengqing/hello/service/impl/",
            "rpms-common/src/main/java/com/zhengqing/hello/query/"
    };

    //准备所有模板名称(和路径顺序一致)
    private String[] tempNames = {
            "domain.js",
            "index.jsp",
            "DomainController.java",
            "IDomainService.java",
            "DomainServiceImpl.java",
            "DomainQuery.java"
    };

    //准备要生成的Domain(有可能同时生成多个)
    private String[] domains = {"User"}; //这里写要生成的domain类名

    //生成相应的文件-->创建代码
    @Test
    public void testCreate() throws Exception{

        //创建模板应用上下文
        VelocityContext context = new VelocityContext();//Domain  domain   vos
        //一.遍历所有的Domain
        for (int i = 0; i < domains.length; i++) {
            //1.1拿到大写的domain
            String domainBig = domains[i];
            //1.2拿到小写的domain
            String domainSmall = domainBig.substring(0,1).toLowerCase() + domainBig.substring(1);
            //1.3设置上下文的替换名称
            context.put("Domain",domainBig);
            context.put("domain",domainSmall);
            //vos  数组或者集合    {title:   filed:}
            List<FieldVo> vos = scanDomain(domainBig);
            context.put("vos", vos);

            //二.遍历所有的路径
            for (int j = 0; j < paths.length; j++) {
                //2.1拿到相应的路径
                String path =paths[j];
                //2.2拿到相应的模板名称
                String tempName = tempNames[j];
                //2.3拼接回我们需要的位置文件
                String realPath = (projectPath+path + tempName).replaceAll("Domain",domainBig).replaceAll("domain",domainSmall);

                //三.准备相应文件与模板进行组合
                //3.1准备相应的文件(要生成的文件)
                File file = new File(realPath);
            /*  // 如果文件存在,我们根据情况看是否需要覆盖
                if (file.exists() && !FLAG){
                    return;
                }*/
                //  如果父文件不存在,我们创建一个
                File parentFile = file.getParentFile();
                if(!parentFile.exists()){
                    parentFile.mkdirs();
                }
                //3.2拿到相应的模板(需要设置好编码)
                Template template = Velocity.getTemplate("template/"+tempName,"UTF-8");
                FileWriter writer = new FileWriter(file);
                template.merge(context, writer);
                writer.close();
            }
        }
    }

    private List<FieldVo> scanDomain(String domainBig) {
        List<FieldVo> list = new ArrayList<>();
        try {
            //Class对象
            String className = "com.zhengqing.hello.domain."+domainBig;
            Class c = Class.forName(className);
            //获取所有的字段
            Field[] fields = c.getDeclaredFields();
            for (Field field : fields) {
                //扫描上面的注解LayuiColumn
                if(field.isAnnotationPresent(LayuiColumn.class)){
                    //有LayuiColumn注解
                    LayuiColumn layuiColumn = field.getAnnotation(LayuiColumn.class);
                    String title = layuiColumn.title();
                    //拿到字段的名称
                    String name = field.getName();
                    FieldVo fv = new FieldVo(title,name);
                    list.add(fv);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return list;
    }

}

下面这段代码做前端页面生成时与domain里面字段对应【直接拷贝到自己项目即可】

public class FieldVo {
    private String title;
    private String filed;
    public FieldVo() { }
    public FieldVo(String title, String filed) {
        this.title = title;
        this.filed = filed;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getFiled() {
        return filed;
    }
    public void setFiled(String filed) {
        this.filed = filed;
    }
}

自定义注解【加在domain类的字段上面可实现,让前端生成遍历字段 为自己想要的中文,而不是domain的字段】

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LayuiColumn {
    public String title();
}

ex:

解决$冲突问题

创建出来后我们运行,会发现domain.js会报错。原因是js中有很多$,而这些$和Velocity中的$形成了冲突,我们可以使用以下这种办法来进行解决:

domain.js修改

顶部加上:#set( $D = '$' ) -> 为$显示设置一个变量

进行替换

$(  ->  ${D}(

$.  ->  ${D}.

其它细节处理

  先运行看效果,如果有问题,请先进行模板文件的修改,再重新生成。直到最后功能可以成功!(记住:有错先改模板)

如果代码生成器生成的文件有问题(错误),找到错误,修改模板,重新生成 -> 一直到生成没有问题为止(慢慢调)

最后配置好之后生成代码,也是非常爽的哦~~~

更多推荐

JavaWeb(19) 代码生成器 (velocity实现前后端自动生成)