栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot代码生成器,从此不用手撸代码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot代码生成器,从此不用手撸代码

前言

通常在开始开发项目的时候,首先会建立好数据库相关表,然后根据表结构生成 Controller、Service、DAO、Model以及一些前端页面。

如果开发前没有强制的约束,而每个程序员都有自己的编码习惯,最终会导致一个项目呈现出多种编码风格。再有就是一些CRUD的列表功能,基本是没啥挑战性的,纯粹苦力活,浪费时间。

所以,根据公司现有框架,开发一款统一风格的代码生成器还是很有必要的。

技术选型

开发框架:SpringBoot+JPA,考虑到会生成各种前后端代码文件,这里我们选用freemarker模板引擎来制作相应的模板。

实现思路 获取表结构信息

首先我们定义一个实体类,为了使用方便,把表和字段信息放到了一个类中:

@Data
public class AppGen extends PageBean implements Serializable {

    
    private String tableName;
    
    private String entityName;
    
    private String lowerEntityName;
    
    private String tableComment;
    
    private String prefix;
    
    private String function;

    
    private String columnName;
    
    private String entityColumnName;
    
    private String columnComment;

    
    private String dataType;

    
    private Object columnExtra;
    
    private Object columnLength;

    private List list;

}

获取表列表:

@Override
@Transactional(readonly = true)
public Result list(AppGen gen){
    String countSql = "SELECt COUNT(*) FROM information_schema.tables ";
    countSql +="WHERe table_schema='tools'";
    Long totalCount = dynamicQuery.nativeQueryCount(countSql);
    PageBean data = new PageBean<>();
    if(totalCount>0){
 String nativeSql = "SELECt table_name as tableName,table_comment as tableComment ";
 nativeSql+="FROM information_schema.tables WHERe table_schema='tools'";
 Pageable pageable = PageRequest.of(gen.getPageNo(),gen.getPageSize());
 List list = dynamicQuery.nativeQueryPagingListModel(AppGen.class,pageable, nativeSql);
 data = new PageBean<>(list, totalCount);
    }
    return Result.ok(data);
}

制作模板

模板太多了,这里只以Controller模板为例,贴一下实现代码,更多模板见源码:

package com.tools.module.${prefix}.web;

import com.tools.common.config.AbstractController;
import com.tools.common.model.Result;
import com.tools.module.${prefix}.entity.${entityName};
import com.tools.module.${prefix}.service.${entityName}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/${prefix}/${function}")
public class ${entityName}Controller extends AbstractController {

    @Autowired
    private ${entityName}Service ${function}Service;

    
    @PostMapping("/list")
    public Result list(${entityName} ${function}){
 return ${function}Service.list(${function});
    }
    
    @PostMapping("/get")
    public Result get(Long id){
 return ${function}Service.get(id);
    }
    
    @PostMapping("/save")
    public Result save(@RequestBody ${entityName} ${function}){
 return ${function}Service.save(${function});
    }

    
    @PostMapping("/delete")
    public Result delete(Long id){
 return ${function}Service.delete(id);
    }
}

说白了其实就是传递参数,把一些可变的代码片段使用${name}形式编写。

代码生成

有点长,慢慢看,其实就是渲染各种前后端模板:

@PostMapping("/create")
public Result create(@RequestBody AppGen gen) throws IOException, TemplateException {
    
    List list = genService.getByTable(gen);
    String name = gen.getTableName();
    String[] table =  StringUtils.split(name,"_");
    gen.setPrefix(table[0]);
    gen.setFunction(table[1]);
    gen.setEntityName(GenUtils.allInitialCapital(gen.getTableName()));
    list.stream().forEach(column-> {
column.setEntityColumnName(GenUtils.secInitialCapital(column.getColumnName()));
    });
    gen.setList(list);
    String baseFile = filePath+ SystemConstant.SF_FILE_SEPARATOR+"com"+
     SystemConstant.SF_FILE_SEPARATOR+ "tools"+
     SystemConstant.SF_FILE_SEPARATOR+ "module"+
     SystemConstant.SF_FILE_SEPARATOR+ gen.getPrefix()+SystemConstant.SF_FILE_SEPARATOR;
    
    File entityFile = FileUtil.touch(baseFile+"entity"+
     SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+".java");
    File repositoryFile = FileUtil.touch(baseFile+"repository"+
     SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"Repository.java");
    File serviceFile = FileUtil.touch(baseFile+"service"+
     SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"Service.java");
    File serviceImplFile = FileUtil.touch(baseFile+"service"+
     SystemConstant.SF_FILE_SEPARATOR+"impl"+SystemConstant.SF_FILE_SEPARATOR+
     gen.getEntityName()+"ServiceImpl.java");
    File controllerFile = FileUtil.touch(baseFile+"web"+
     SystemConstant.SF_FILE_SEPARATOR + gen.getEntityName() + "Controller.java");
    
    String htmlPath =  filePath+
     SystemConstant.SF_FILE_SEPARATOR + "templates"+
     SystemConstant.SF_FILE_SEPARATOR + gen.getPrefix()+
     SystemConstant.SF_FILE_SEPARATOR + gen.getFunction()+SystemConstant.SF_FILE_SEPARATOR;
    File listFile = FileUtil.touch(htmlPath + "list.html");
    File formFile = FileUtil.touch(htmlPath + "form.html");
    
    Template template = configuration.getTemplate("html/list.ftl");
    String text = FreeMarkerTemplateUtils.processTemplateIntoString(
     template, gen);
    FileUtil.writeString(text,listFile,"UTF-8");
    template = configuration.getTemplate("html/form.ftl");
    text = FreeMarkerTemplateUtils.processTemplateIntoString(
     template, gen);
    FileUtil.writeString(text,formFile,"UTF-8");
    
    template = configuration.getTemplate("java/repository.ftl");
    text = FreeMarkerTemplateUtils.processTemplateIntoString(
     template, gen);
    FileUtil.writeString(text,repositoryFile,"UTF-8");
    
    template = configuration.getTemplate("java/entity.ftl");
    text = FreeMarkerTemplateUtils.processTemplateIntoString(
     template, gen);
    FileUtil.writeString(text,entityFile,"UTF-8");
    
    template = configuration.getTemplate("java/service.ftl");
    text = FreeMarkerTemplateUtils.processTemplateIntoString(
     template, gen);
    FileUtil.writeString(text,serviceFile,"UTF-8");
    
    template = configuration.getTemplate("java/serviceImpl.ftl");
    text = FreeMarkerTemplateUtils.processTemplateIntoString(
     template, gen);
    FileUtil.writeString(text,serviceImplFile,"UTF-8");
    
    template = configuration.getTemplate("java/controller.ftl");
    text = FreeMarkerTemplateUtils.processTemplateIntoString(
     template, gen);
    FileUtil.writeString(text,controllerFile,"UTF-8");
    return Result.ok();
}

生成逻辑还是很傻瓜的,后期会慢慢优化,比如根据字段类型生成不同的表单形式,可以自定义字段是否显示等的。

小结

总的来说,还是比较容易上手的,相对于一些简单的列表功能分分钟撸出效果,开发一分钟,喝茶一整天。当然对于一些复杂的效果,还是自己一一去实现。

源码

https://gitee.com/52itstyle/SPTools

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/237828.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号