- 😜作 者:是江迪呀
- ✒️本文关键词:
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 服务实现类
- 三、测试
上回我们说了一些开发规范,其实现在你就可以开始写代码了。但是呢效率会很慢,实体类、mapper
、service
等等这些你都要手动创建,这样效率太低了,遇到一个表中有几十个字段的情况,你可以一上午都在写实体类,而且还不能保证准确性,所以我们需要一个工具替我们生成。
一、使用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() {
}
}
三、测试