这样一个任务,数据库里有好多张表,数据已经初始化好了。一天时间写个微服务,再用20多个rest接口把数据暴露给前端用。在大厂里,一个项目组的好多个螺丝钉就要996了。我这一个人搞,怎么办呢。作为一个程序员当然是要自动化了。因为要反向生成,那就用mybatis-plus呗
Springboot项目就不用说了,自己随便建个
这些依赖都是要用到的基础依赖
compile('com.baomidou:mybatis-plus-boot-starter:3.1.0')
compile('com.baomidou:mybatis-plus-generator:3.1.0')
compile('org.freemarker:freemarker')
compile('mysql:mysql-connector-java')
compile('org.projectlombok:lombok')
compile 'io.springfox:springfox-swagger2:2.9.2'
compile 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'org.springframework.boot:spring-boot-starter-web'
server:
port: 8010
servlet:
context-path: /
spring:
datasource:
url: jdbc:mysql://127.0.0.1:43521/trade_analysis_data?nullNamePatternMatchesAll=true&tinyInt1isBit=false&useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 123123
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5 # 最小空闲连接数量
idle-timeout: 180000 # 空闲连接存活最大时间,默认600000(10分钟)
maximum-pool-size: 10 # 连接池最大连接数,默认是10
auto-commit: true # 此属性控制从池返回的连接的默认自动提交行为,默认值:true
pool-name: authPool # 连接池名
max-lifetime: 1800000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
connection-timeout: 30000 # 数据库连接超时时间,默认30秒,即30000
mybatis-plus:
global-config:
db-config:
id-type: auto
field-strategy: not_empty
table-underline: true
db-type: mysql
logic-delete-value: 1
logic-not-delete-value: 0
mapper-locations: classpth:/mpper/**Mapper.xml
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("cn.togeek.jcz.mapper")
public class MybatisPlusConfig {
/**
* @description: 配置分页插件
* 不配的话分页就不好用了
* @param: []
* @return: com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
有些博客会有配自定义模板的步骤,不要搞了,开源内置的很好,自定义的话就准备加班吧
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
@Component
public class GeneratorCodeHelper {
@Autowired
private Environment env;
/**
* 在控制台读取表名
* @param tableName
* @return
*/
private String scanner(String tableName){
Scanner scanner = new Scanner(System.in);
StringBuffer buffer = new StringBuffer();
buffer.append("请输入").append(tableName).append(": ");
System.out.println(buffer.toString());
if(scanner.hasNext()) {
String table = scanner.next();
if(!StringUtils.isEmpty(table)) {
return table;
}
}
throw new MybatisPlusException("请输入正确的"+tableName);
}
public void generate() {
while(true) {
String tableName = scanner("表名,实体名(以空格分开,实体名不给,则默认为驼峰处理后的表名(去掉t_)),exit退出");
if("exit".equalsIgnoreCase(tableName)) {
return;
}
generate(tableName.trim());
}
}
private void generate(String scanner) {
int blank = scanner.indexOf(" ");
String tableName = null;
String entityName = null;
if(blank > 0) {
tableName = scanner.substring(0, blank).trim();
entityName = scanner.substring(blank).trim();
}
else {
tableName = scanner;
}
if(StringUtils.isEmpty(entityName)) {
entityName = tableName.startsWith("t_") || tableName.startsWith("T_") ? tableName.substring(2) : tableName;
/**将表名转换为驼峰*/
StringBuilder builder = new StringBuilder();
Arrays.asList(entityName.split("_"))
.forEach(temp -> builder.append(StringUtils.capitalize(temp)));
entityName = builder.toString();
}
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java")
.setAuthor("generator")
.setEntityName(entityName)
.setMapperName(entityName + "Mapper")
.setServiceName(entityName + "Service")
.setControllerName(entityName + "Controller")
.setOpen(false)
.setSwagger2(true);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(env.getProperty("spring.datasource.url"));
// dsc.setSchemaName("public");
dsc.setDriverName(env.getProperty("spring.datasource.driver-class-name"));
dsc.setUsername(env.getProperty("spring.datasource.username"));
dsc.setPassword(env.getProperty("spring.datasource.password"));
mpg.setDataSource(dsc);
/**全局配置,配置生成代码的路径和类名定制*/
String newModuleName = "generator";
PackageConfig pc = new PackageConfig();
pc.setParent("cn.test.project")
.setMapper("mapper."+newModuleName)
.setEntity("entity."+newModuleName)
.setService("service."+newModuleName)
.setController("controller."+newModuleName)
.setPathInfo(new HashMap<>());
pc.getPathInfo().put(ConstVal.ENTITY_PATH, gc.getOutputDir() + "/cn/test/project/entity/" + newModuleName);
pc.getPathInfo().put(ConstVal.MAPPER_PATH, gc.getOutputDir() + "/cn/test/project/mapper/" + newModuleName);
pc.getPathInfo().put(ConstVal.SERVICE_PATH, gc.getOutputDir() + "/cn/test/project/service/" + newModuleName);
pc.getPathInfo().put(ConstVal.CONTROLLER_PATH, gc.getOutputDir() + "/cn/test/project/controller/" + newModuleName);
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 自定义输出配置
List focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + newModuleName + "/" + tableInfo.getEntityName() +
"Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setInclude(tableName);
strategy.setControllerMappingHyphenStyle(true);
//strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
直接启动项目,填写对应的表名,就反向生成代码了
import cn.test.project.config.GeneratorCodeHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.PostConstruct;
@SpringBootApplication
public class JczApplication {
@Autowired
private GeneratorCodeHelper codeGenerator;
@PostConstruct
public void generate() {
generateCode();
}
private void generateCode() {
codeGenerator.generate();
System.exit(0);
}
public static void main(String[] args) {
SpringApplication.run(JczApplication.class, args);
}
}
git地址:https://gitee.com/tangjunchao/springboot-mybatis-plus