【企业级SpringBoot单体项目模板 】——Mybatis-plus自动代码生成

news2024/11/19 1:43:43
  • 😜           :是江迪呀
  • ✒️本文关键词SpringBoot项目模版企业级模版
  • ☀️每日   一言我们之所以这样认为,是因为他们这样说。他们之所以那样说,是因为他们想让我们那样认为。所以实践才是检验真理的唯一准则。

文章目录

  • 一、使用Velocity模版自动生成代码
  • 二、自定义vm模版
    • 2.1 MyController.java.vm
    • 2.2 MyEntity.java.vm 实体类
    • 2.3 MyMapper.java.vm mapper接口
    • 2.4 MyMapper.xml.vm mapper.xml
    • 2.5 MyService.java.vm 服务层
    • 2.6 MyServiceImpl.java.vm 服务实现类
  • 三、测试

上回我们说了一些开发规范,其实现在你就可以开始写代码了。但是呢效率会很慢,实体类、mapperservice等等这些你都要手动创建,这样效率太低了,遇到一个表中有几十个字段的情况,你可以一上午都在写实体类,而且还不能保证准确性,所以我们需要一个工具替我们生成。

一、使用Velocity模版自动生成代码

我们以生成t_user表为例,表结构如下:

在这里插入图片描述

Generator代码:

package com.shijiangdiya.common;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;

import java.util.*;

public class Generator {
    /**
     * 生成的代码的顶层包名
     */
    private static final String SERVICE_NAME = "code";
    /**
     * 最终包路径
     */
    private static final StringBuilder FINAL_PATH = new StringBuilder();

    /**
     * 表名前缀
     */
    private static String tablePrefix = "t_";


    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help);
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    /**
     * 代码生成器
     */
    public static void main(String[] args) {
        // 目标数据表名
        String[] tableName = scanner("表名,多个英文逗号分割").split(",");
        generateByTables(tableName);
    }

    private static void generateByTables(String... tableNames) {
        AutoGenerator mpg = new AutoGenerator();
        mpg.setTemplateEngine(new VelocityTemplateEngine());
        // 全局配置
        GlobalConfig gc = globalGenerate();
        // 包配置
        PackageConfig pc = packageGenerate();
        // 数据库配置
        DataSourceConfig dsc = dataSourceGenerate();
        // 自定义模板
        TemplateConfig tc = templateGenerate();
        // 策略配置
        StrategyConfig strategy = strategyGenerate(tableNames);
        mpg.setGlobalConfig(gc);
        mpg.setDataSource(dsc);
        mpg.setPackageInfo(pc);
        mpg.setTemplate(tc);
        mpg.setStrategy(strategy);
        mpg.execute();
    }

    /**
     * 数据库配置
     *
     * @return 数据源
     */
    private static DataSourceConfig dataSourceGenerate() {
        YamlPropertiesFactoryBean yamlMapFactoryBean = new YamlPropertiesFactoryBean();
        yamlMapFactoryBean.setResources(new ClassPathResource("application.yml"));
        //获取yml里的参数
        Properties properties = yamlMapFactoryBean.getObject();
        String url = properties.getProperty("spring.datasource.url");
        String driver = properties.getProperty("spring.datasource.driver-class-name");
        String username = properties.getProperty("spring.datasource.username");
        String password = properties.getProperty("spring.datasource.password");
        // 数据库配置
        DataSourceConfig dsc = new DataSourceConfig();
        //数据类型
        dsc.setDbType(DbType.MYSQL);
        dsc.setUrl(url);
        dsc.setDriverName(driver);
        dsc.setUsername(username);
        dsc.setPassword(password);
        return dsc;
    }

    /**
     * 全局配置
     *
     * @return 全局配置
     */
    private static GlobalConfig globalGenerate() {
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        //是否覆盖文件
        gc.setFileOverride(true);
        // 获取顶层目录
        String projectPath = System.getProperty("user.dir");
        // 获取子项目目录
        String path = Generator.class.getClassLoader().getResource("").getPath();
        String levelPath = path.substring(0, path.indexOf("target") - 1);
        if (!projectPath.equals(levelPath)) {
            FINAL_PATH.append(levelPath);
        } else {
            FINAL_PATH.append(projectPath);
        }
        //输出路径
        gc.setOutputDir(FINAL_PATH + "/src/main/java");
        //作者名称
        gc.setAuthor("shijiangdiya");
        //生成后是否自动打开文件
        gc.setOpen(true);
        // XML 二级缓存
        gc.setEnableCache(false);
        //是否使用swagger2
        gc.setSwagger2(true);
        // 自定义文件命名,注意 %s 会自动填充表实体属性!
        gc.setControllerName("%sController");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        //mapper.xml中生成基础resultMap
        gc.setBaseResultMap(true);
        //mapper.xml中生成基础columnList
        gc.setBaseColumnList(true);
        // 主键类型
        gc.setIdType(IdType.ID_WORKER);
        return gc;
    }

    /**
     * 策略配置
     * 主要的表字段映射
     *
     * @param tableName 表名
     * @return 策略配置
     */
    private static StrategyConfig strategyGenerate(String[] tableName) {
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //表名映射到实体策略,带下划线的转成 驼峰
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //列名映射到类型属性策略,带下划线的转成驼峰
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 表名和字段名是否大小写
        strategy.setCapitalMode(false);
        //实体类使用lombok
        strategy.setEntityLombokModel(true);
        //controller使用rest接口模式
        strategy.setRestControllerStyle(true);
        // 继承顶层controller 这里是
        strategy.setSuperControllerClass("com.shijiangdiya.config.AbstractController");
        //设置表名
        strategy.setInclude(tableName);
        //去掉前缀
        strategy.setTablePrefix(tablePrefix);
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);
        // 驼峰转连字符
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setEntityBuilderModel(true);
        return strategy;
    }

    /**
     * 自定义模板
     *
     * @return 模板
     */
    private static TemplateConfig templateGenerate() {
        // 设置自定义的模板
        TemplateConfig tc = new TemplateConfig();
        tc.setController("templates/MyController.java.vm")
                .setEntity("templates/MyEntity.java.vm")
                .setService("templates/MyService.java.vm")
                .setServiceImpl("templates/MyServiceImpl.java.vm")
                .setMapper("templates/MyMapper.java.vm")
                .setXml("/templates/MyMapper.xml.vm");
                // 不要源码包内的mapper
        return tc;
    }

    /**
     * 包配置
     *
     * @return 包配置
     */
    private static PackageConfig packageGenerate() {
        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(SERVICE_NAME);
        pc.setParent("com.shijiangdiya");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        pc.setMapper("mapper");
        pc.setXml("mapper.xml");
        return pc;
    }
}

二、自定义vm模版

使用自定义模板你可以生成更加符合你业务场景的代码。

2.1 MyController.java.vm

在控制层中,提供了CRUD的方法,你可以自定义一些通用的东西,比如传入查询的QO、返回的DTO等。

package ${package.Controller};

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import com.shijiangdiya.config.Response;


#if(${superControllerClassPackage})
import $!{superControllerClassPackage};
#end


/**
 * <p>
 * $!{table.comment} 前端控制器
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
#set($entityName = ${entity.substring(0,1).toLowerCase()}+${entity.substring(1)})
@RestController
@RequestMapping(value = {"#if(${controllerMappingHyphenStyle})/api/${controllerMappingHyphen}#else /api/${table.entityPath}#end"},
		produces = MediaType.APPLICATION_JSON_VALUE)
@Api(value = "${table.controllerName}", description = "$!{table.comment}", produces = MediaType.APPLICATION_JSON_VALUE)
public class ${table.controllerName} extends ${superControllerClass} {
    @Autowired
    private ${table.serviceName} ${entityName}Service;

    @ResponseBody
    @ApiOperation(value = "", notes = "")
    @GetMapping(value = "/")
    public Response select(){
        ${entityName}Service.select();
        return returnSuccess();
    }

    @ResponseBody
    @ApiOperation(value = "", notes = "")
    @PostMapping(value = "")
    public Response add(){
        ${entityName}Service.add();
        return returnSuccess();
    }

    @ResponseBody
    @ApiOperation(value = "", notes = "")
    @PutMapping(value = "/{id}")
    public Response update(@PathVariable Long id){
        ${entityName}Service.modifyById();
        return returnSuccess();
    }

    @ApiOperation(value = "$!{table.comment}-删除", notes = "$!{table.comment}-删除")
    @DeleteMapping(value = "/{id}")
    public Response delete(@PathVariable Long id){
        ${entityName}Service.deleteById(id);
        return returnSuccess();
    }

}

2.2 MyEntity.java.vm 实体类

package ${package.Controller};

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import com.shijiangdiya.config.Response;


#if(${superControllerClassPackage})
import $!{superControllerClassPackage};
#end


/**
 * <p>
 * $!{table.comment} 前端控制器
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
#set($entityName = ${entity.substring(0,1).toLowerCase()}+${entity.substring(1)})
@RestController
@RequestMapping(value = {"#if(${controllerMappingHyphenStyle})/api/${controllerMappingHyphen}#else /api/${table.entityPath}#end"},
		produces = MediaType.APPLICATION_JSON_VALUE)
@Api(value = "${table.controllerName}", description = "$!{table.comment}", produces = MediaType.APPLICATION_JSON_VALUE)
public class ${table.controllerName} extends ${superControllerClass} {
    @Autowired
    private ${table.serviceName} ${entityName}Service;

    @ResponseBody
    @ApiOperation(value = "", notes = "")
    @GetMapping(value = "/")
    public Response select(){
        ${entityName}Service.select();
        return returnSuccess();
    }

    @ResponseBody
    @ApiOperation(value = "", notes = "")
    @PostMapping(value = "")
    public Response add(){
        ${entityName}Service.add();
        return returnSuccess();
    }

    @ResponseBody
    @ApiOperation(value = "", notes = "")
    @PutMapping(value = "/{id}")
    public Response update(@PathVariable Long id){
        ${entityName}Service.modifyById();
        return returnSuccess();
    }

    @ApiOperation(value = "$!{table.comment}-删除", notes = "$!{table.comment}-删除")
    @DeleteMapping(value = "/{id}")
    public Response delete(@PathVariable Long id){
        ${entityName}Service.deleteById(id);
        return returnSuccess();
    }

}

2.3 MyMapper.java.vm mapper接口

package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.apache.ibatis.annotations.Mapper;

/**
 * <p>
 * $!{table.comment} Mapper 接口
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Mapper
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

}

2.4 MyMapper.xml.vm mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
</mapper>

2.5 MyService.java.vm 服务层

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.List;
/**
 * <p>
 * $!{table.comment} 服务类
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
#set($entityName = ${entity.substring(0,1).toLowerCase()}+${entity.substring(1)})
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

    /**
        * 查询
        */
       List select();

       /**
        * 修改
        */
       void add();

       /**
        * 删除
        * @param id
        */
       void deleteById(Long id);

       /**
        * 修改
        */
       void modifyById();
}

2.6 MyServiceImpl.java.vm 服务实现类

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import java.util.List;

/**
 * <p>
 * $!{table.comment} 服务实现类
 * </p>
 *
 * @author ${author}
 * @since ${date}
 * @version ${cfg.version}
 */
#set($entityName = ${entity.substring(0,1).toLowerCase()}+${entity.substring(1)})
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {

     @Override
       public List select() {
           return null;
       }

       @Override
       public void add() {

       }

       @Override
       public void deleteById(Long id) {

       }

       @Override
       public void modifyById() {

       }
}

三、测试

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1035864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

漏刻有时数据可视化Echarts组件开发(30):自定义方向的数据流向动画

let points = [{name: 市城市管理局,desc: {type: 1,},},{name: 科大讯飞,desc: {type: 2,},},{name: 市水利局,desc: {type: 1,},},{name: 市政法委,desc: {type: 1,},},{name: 市自然资源和规划局,desc: {type: 1,},},{name: 市生态环境局,desc: {type: 1,},},{name: 市大数据…

资源分享 | 情绪脑电研究公开数据集

SEED SEED数据集是由上海交大类脑计算与机器智能研究中心(BCMI)开发的。该数据集是基于脑电的情绪分类任务而设计的数据集。该数据集记录了15名被试在观看积极、中性和消极情绪电影片段时的EEG信号&#xff0c;每个视频片段的时间为3-5分钟。每个参与者重复采集三天&#xff0…

BST搜索二叉树

目录 二叉搜索树概念 ​编辑 1 二叉搜索树的构建 2. 二叉搜索树的删除 3二叉搜索树中放入元素 4. 二叉搜索树中元素的删除 5. 二叉搜索树中元素的遍历 6 二叉搜索树中元素的查找 7二叉搜索树的拷贝构造 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一…

【lesson10】fork创建进程的现象解答

文章目录 fork现象fork问题 fork现象 我们先来看一段代码。 大家觉得这段代码的printf会打印几次&#xff1f; 结果&#xff1a; 我们可以清楚的看到&#xff0c;第二个printf打印了2次。 我们再来看一段不可思议的代码&#xff1a; 运行结果&#xff1a; 我们可以看到这r…

编写Dockerfile

Dockerfile 编写Dockerfile 制作 FROM java:7 MAINTAINER bunny <邮箱qq.com> ADD easybbs-web-release-1.0.jar app.jar CMD java -jar app.jar构建 docker build -f ./my_dockerfile -t app:1.0 .启动 docker rm my_app docker ps -a docker run -d -p 9000:7070 …

前端教程-总览

现已经更新完毕图中教程汇总后期收集所有教程资料整理

【考研】2023暨南大学848答案 2020-2023 计算机基础综合 830答案

&#x1f525;&#x1f525; I 仓库 还在更新&#xff0c;敬请期待 &#x1f525;暨南大学计算机848报考信息汇总仓库 仓库内有20年真题答案 https://github.com/zhanjuex/JNU_848 备用仓库 (目录可能用不了 https://xindon.coding.net/public/open/JNU_848/git/files &#x1…

基于springboot+vue的入校申报审批系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

基于Java+SpringBoot+Vue+Uniapp的美容预约平台小程序设计与实现(开题报告+任务书+源码+lw+ppt +部署文档+讲解)

文章目录 前言用户微信小程序端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌…

Spring的后处理器-BeanFactoryPostprocessor

目录 Spring后处理器 Bean工厂后处理器-BeanFactoryPostProcessor 修改beanDefinition对象 添加beanDefiniton对象 方法一 方法二 自定义Component Spring后处理器 Spring后处理器是Spring对外开放的重要拓展点&#xff08;让我们可以用添加自己的逻辑&#xff09;&…

使用 PyTorch 的计算机视觉简介 (4/6)

一、说明 在本单元中&#xff0c;我们将了解卷 积神经网络&#xff08;CNN&#xff09;&#xff0c;它是专门为 计算机视觉设计的。 多层卷积层允许我们从图像中提取某些图像模式&#xff0c;池化层&#xff0c;以及在 CIFAR-10上的表现。 二、多层 CNN 在上一个单元中&#xf…

拦截|篡改|伪造.NET类库中不限于public的类和方法

大家好&#xff0c;我是沙漠尽头的狼。 本文首发于Dotnet9&#xff0c;介绍使用Lib.Harmony库拦截第三方.NET库方法&#xff0c;达到不修改其源码并能实现修改方法逻辑、预期行为的效果&#xff0c;并且不限于只拦截public访问修饰的类及方法&#xff0c;行文目录&#xff1a;…

Mysql004:用户管理

前言&#xff1a;本章节讲解的是mysql中的用户管理&#xff0c;包括&#xff08;管理数据用户&#xff09;、&#xff08;控制数据库的访问权限&#xff09;。 目录 1. 查询用户 2. 创建用户 3. 修改用户密码 4. 删除用户 5. 权限控制 1. 查询用户 在mysql数据库中&#xff0…

P-GaN栅极HEMT开关瞬态分析中的动态栅极电容模型

标题&#xff1a;Dynamic Gate Capacitance Model for Switching Transient Analysis in P-GaN Gate HEMTs 摘要 在这项工作中&#xff0c;提出了一种用于P-GaN栅极HEMT的高效开关瞬态分析模型&#xff0c;该模型考虑了开关瞬态过程中的动态栅极电容CG(VDS, VGS)特性。同时&a…

【STM32教程】第五章 STM32的定时器

案例代码及相关资料下载链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1hsIibEmsB91xFclJd-YTYA?pwdjauj 提取码&#xff1a;jauj 1 定时器综述 1.1 定时器简介 TIM&#xff08;Timer&#xff09;定时器&#xff0c;最基本功能就是定时触发中断&#xff1…

python随手小练3

题目&#xff1a; 写出一个判断闰年的python代码&#xff1a; 闰年的条件&#xff1a; 如果N能够被4整除&#xff0c;并且不能被100整除&#xff0c;则是闰年 或者&#xff1a;N能被400整除&#xff0c;也是闰年 即&#xff1a;4年一润并且百年不润&#xff0c;每400年再润一…

前端第二课,HTML,alt,title,width/heigh,border,<a>超链接,target,tr,td,th

目录 一、title: &#x1f49b; ​二、alt&#x1f499; 三、width/heigh&#x1f49c; 四、border ❤️ 五、超链接&#x1f49a; 六、target &#x1f497; 七、tr&#x1f495; 八、td&#x1f498; 九、th&#x1f49e; 十、rowspan 一、title: &#x1f49b; 快…

漏刻有时数据可视化Echarts组件开发(29):工业图形动画

var nodes = [{nodeName: 新能源,value: [-10, 100],symbolSize: 50,symbol:image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAAB3R…

【操作系统笔记四】高速缓存

CPU 高速缓存 存储器的分层结构&#xff1a; 问题&#xff1a;为什么这种存储器层次结构行之有效呢&#xff1f; 衡量 CPU 性能的两个指标&#xff1a; 响应时间&#xff08;或执行时间&#xff09;&#xff1a;执行一条指令平均时间 吞吐量&#xff0c;就是 1 秒内 CPU 可以…

ideal 同一项目启动多实列

点击service(如果没有:点击菜单栏&#xff1a;Views -> Tool Windows -> Services&#xff1b;中文对应&#xff1a;视图 -> 工具窗口 -> 服务&#xff1b;快捷键是Alt F8&#xff0c;但是本地快捷键可能冲突&#xff0c;并未成功。) 刚创建好的窗口是空白的&…