新建一个空白的springboot项目,然后将以下代码复制到一个类里,按指示运行main方法,即可生成一个简单的项目
点击查看代码
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Stream;
/**
* mybatis-plus 逆向工程示例代码
* 1. 新建一个maven工程
* 2. 导入依赖包 (见底部依赖包注释)
* 3. 修改下面的数据库配置
* 4. 运行下面的main方法,(如遇报错,请再次执行,首次执行要执行二次)
* 5. 以上即创建项目完成
*/
public class GenerateCode {
private String driverName = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/mytest?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF8";
private String username = "root";
private String password = "root";
private String[] tableNames = {"student", "parent","sql_datasource"}; // 需要生成代码的表名
private String parentPackage = "com.demo"; //父类包名(必须有)
private String author = "author"; // 每个类加上作者
private String outputDir = ""; // 请默认空当前项目(否则请以/src/main/java结尾)
private DbType datebaseType = DbType.MYSQL; //数据库类型
private String javaPath = new File("").getCanonicalPath() + "\\src\\main\\java\\";
private String resourcePath = new File("").getCanonicalPath() + "\\src\\main\\resources\\";; // 资源路径
private String javaPathAndPackage = javaPath + parentPackage.replace(".", "\\") + "\\";
public GenerateCode() throws IOException {
}
public static void main(String[] args) throws Exception {
GenerateCode generateCode = new GenerateCode();
// 生成controller 模板文件
generateCode.createControllerTemplate();
// 生成controller/service/entity/mapper等
generateCode.generator();
// 删除多余的mapper.xml文件
generateCode.deleteXML();
// 生成main方法
generateCode.generatorMain();
// 生成配置文件
generateCode.generatorYML();
// 生成swagger 配置类
generateCode.generatorSwagger();
// 生成mybatis-plus 分页配置类
generateCode.generatorMybatisPlusPage();
// 生成 ResultVO
generateCode.generatorResultVO();
}
private void deleteXML() {
String filePath = javaPathAndPackage + "mapper\\xml";
File file = new File(filePath);
Stream.of(Objects.requireNonNull(file.listFiles())).forEach(File::delete);
file.delete();
}
// 生成controller service serviceImpl entity mapper mapper.xml
public void generator() throws Exception {
if (outputDir == null || "".equals(outputDir)) {
outputDir = new File("").getCanonicalPath() + "\\src\\main\\java";
}
// 1、全局配置
GlobalConfig config = new GlobalConfig();
config.setActiveRecord(false) // 开启AR模式
.setAuthor(author) // 设置作者
// 生成路径(一般都是生成在此项目的src/main/java下面)
.setOutputDir(outputDir)
.setSwagger2(false) // 开启swagger 注解
.setFileOverride(false) // 第二次生成会把第一次生成的覆盖掉
.setIdType(IdType.AUTO) // 主键策略
.setServiceName("%sService") // 生成的service接口名字首字母是否为I,这样设置就没有I
.setBaseResultMap(true) // 生成resultMap
.setBaseColumnList(false); // 在xml中生成基础列
// 2、数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(datebaseType) // 数据库类型
.setDriverName(driverName)
.setUrl(url)
.setUsername(username)
.setPassword(password);
// 3、策略配置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setCapitalMode(true) // 开启全局大写命名
// .setDbColumnUnderline(true) // 表名字段名使用下划线
.setNaming(NamingStrategy.underline_to_camel) // 下划线到驼峰的命名方式
.setRestControllerStyle(true) // rest风格,即controller加 @RestController
.setTablePrefix("tb_") // 表名前缀
.setEntityLombokModel(false) // 使用lombok
.setInclude(tableNames); // 逆向工程使用的表
// 4、包名策略配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent(parentPackage) // 设置包名的parent
.setMapper("mapper")
.setService("service")
.setController("controller")
.setEntity("entity")
.setXml("mapper.xml"); // 设置xml文件的目录,如果为null,则不生成xml文件
// 5、自定义配置,调整 xml 生成目录到resource/mapper下面
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
Map<String, Object> map = new HashMap<>();
map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
this.setMap(map);
}
};
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return outputDir + "\\..\\resources\\mapper\\" + tableInfo.getEntityName() + "Mapper.xml";
}
});
cfg.setFileOutConfigList(focList);
// 6、模板配置(自定义controller层模板)
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setController("/controller.java.vm"); // controller模板采用自定义模板
// 7、整合配置
AutoGenerator autoGenerator = new AutoGenerator();
autoGenerator.setGlobalConfig(config)
.setDataSource(dataSourceConfig)
.setStrategy(strategyConfig)
.setPackageInfo(packageConfig)
.setTemplate(templateConfig)
.setCfg(cfg);
// 6、执行
autoGenerator.execute();
}
private void generatorResultVO() throws IOException {
File dir = new File(javaPathAndPackage, "common");
dir.mkdirs();
String resultVo = String.format(CodeString.resultVO,parentPackage);
creatFile(resultVo, new File(dir,"ResultVO.java"));
}
// 创建Controller的自定义模板
private void createControllerTemplate() throws IOException {
String resourcePath = new GenerateCode().resourcePath;
File resourceFile = new File(resourcePath, "controller.java.vm");
String controllerTemlate = CodeString.controllerTemlate;
controllerTemlate = String.format(controllerTemlate, parentPackage);
creatFile(controllerTemlate,resourceFile);
}
// 生成MybatisPlus 分页配置
private void generatorMybatisPlusPage() throws IOException {
String mybatisPlusPage =CodeString.mybatisPlusPage;
mybatisPlusPage = String.format(mybatisPlusPage, parentPackage);
File dir = new File(javaPathAndPackage + "config");
dir.mkdirs();
File mainFile = new File(dir, "MybatisPlusConfig.java");
creatFile(mybatisPlusPage, mainFile);
}
// 生成swagger-ui的配置文件
private void generatorSwagger() throws IOException {
String swaggerConfig = CodeString.swaggerConfig;
swaggerConfig = String.format(swaggerConfig, parentPackage, parentPackage);
File dir = new File(javaPathAndPackage+ "config");
dir.mkdirs();
File mainFile = new File(dir, "Swagger2.java");
creatFile(swaggerConfig,mainFile);
}
// 生成项目启动类
private void generatorMain() throws IOException {
// 取出 applicationName, 并且首字母大写
String applicationName = parentPackage.substring(parentPackage.lastIndexOf('.') + 1);;
applicationName = applicationName.substring(0, 1).toUpperCase() + applicationName.substring(1) + "Application";
// 将main字符串的字符替换
String mainStr = CodeString.mainStr;
mainStr = String.format(mainStr, parentPackage, parentPackage, applicationName, applicationName);
File mainFile = new File(javaPathAndPackage,applicationName+".java");
creatFile(mainStr,mainFile);
}
// 生成配置文件application.yml(如果存在,则不生成)
private void generatorYML() throws IOException {
String applicationYML = CodeString.applicationYML;
applicationYML = String.format(applicationYML, driverName, url, username, password, parentPackage, parentPackage);
File resourceFile = new File(resourcePath, "application.yml");
creatFile(applicationYML, resourceFile);
}
private void creatFile(String contentStr, File createFile) throws IOException {
if (!createFile.exists()) {
FileWriter fileWriter = new FileWriter(createFile);
fileWriter.write(contentStr);
fileWriter.flush();
fileWriter.close();
System.out.println(String.format("====================生成文件%s成功!!!====================",createFile.getName()));
} else {
System.out.println(String.format("-------------生成文件%s失败,配置文件已存在!!!-------------",createFile.getName()));
}
}
}
class CodeString{
// application.yml 模板
final static String applicationYML = "# 配置端口号\n" +
"server:\n" +
" port: 8888\n" +
"\n" +
"spring:\n" +
" datasource:\n" +
" driver-class-name: %s\n" +
" url: %s\n" +
" password: %s\n" +
" username: %s\n" +
"\n" +
"mybatis:\n" +
" # 指定bean所在包,在mapper.xml中可以使用别名而不使用类的全路径名\n" +
" type-aliases-package: %s.entity\n" +
" configuration:\n" +
" # 驼峰转换\n" +
" map-underscore-to-camel-case: true\n" +
" # 当mybatis的xml文件和mapper接口不在相同包下时,用mapperLocations属性指定xml文件的路径。\n" +
" mapper-locations: mapper/*.xml\n" +
"mapper:\n" +
" wrap-keyword: \"`{0}`\" # 自动配置关键字,配置后不需要使用 @Column 指定别名\n\n" +
"logging:\n" +
" level:\n" +
" %s: debug\n" +
"swagger:\n" +
" enable: true";
// 启动类模板
final static String mainStr = "package %s;\n" +
"import org.mybatis.spring.annotation.MapperScan;\n" +
"import org.springframework.boot.SpringApplication;\n" +
"import org.springframework.boot.autoconfigure.SpringBootApplication;\n\n" +
"@SpringBootApplication\n" +
"@MapperScan(\"%s.mapper\")\n" +
"public class %s{\n" +
" public static void main(String[] args) {\n" +
" SpringApplication.run(%s.class, args);\n" +
" }\n}";
// swagger-ui配置模板
final static String swaggerConfig = "package %s.config;\n" +
"\n" +
"import org.springframework.beans.factory.annotation.Value;\n" +
"import org.springframework.context.annotation.Bean;\n" +
"import org.springframework.context.annotation.Configuration;\n" +
"import springfox.documentation.builders.ApiInfoBuilder;\n" +
"import springfox.documentation.builders.PathSelectors;\n" +
"import springfox.documentation.builders.RequestHandlerSelectors;\n" +
"import springfox.documentation.service.ApiInfo;\n" +
"import springfox.documentation.service.Contact;\n" +
"import springfox.documentation.spi.DocumentationType;\n" +
"import springfox.documentation.spring.web.plugins.Docket;\n" +
"import springfox.documentation.swagger2.annotations.EnableSwagger2;\n" +
"import java.io.IOException;\n" +
"\n" +
"@Configuration\n" +
"@EnableSwagger2\n" +
"public class Swagger2 {\n" +
"\n" +
" // swagger开关\n" +
" @Value(\"${swagger.enable}\")\n" +
" private boolean swaggerEnable;\n" +
" @Value(\"${server.port}\")\n" +
" private Integer port;\n" +
"\n" +
" @Bean\n" +
" public Docket createRestApi() {\n" +
" if (swaggerEnable) {\n" +
" System.out.println(\"\\n 访问地址:\\n http://127.0.0.1:\"+port+\"/swagger-ui.html\\n\");\n" +
" try {\n" +
" Runtime.getRuntime().exec(\"rundll32 url.dll,FileProtocolHandler \" + \"http://127.0.0.1:\"+port+\"/swagger-ui.html\");\n" +
" } catch (IOException e) {\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
" return new Docket(DocumentationType.SWAGGER_2)\n" +
" .enable(swaggerEnable)\n" +
" .apiInfo(apiInfo())\n" +
" .select()\n" +
" .apis(RequestHandlerSelectors.basePackage(\"%s\")) //swagger扫描指定包下面的接口\n" +
" .paths(PathSelectors.any())\n" +
" .build();\n" +
" }\n" +
"\n" +
" private ApiInfo apiInfo() {\n" +
" Contact contact = new Contact(\"author\",\"http://127.0.0.1:xxxx(随便或者网站地址)\",\"xxxxxxx@qq.com\");\n" +
" return new ApiInfoBuilder()\n" +
" .title(\"这个是swagger的标题\")\n" +
" .description(\"这个是副标题\")\n" +
" .contact(contact)\n" +
" .version(\"1.0\")\n" +
" .build();\n" +
" }\n" +
"\n" +
" /**\n" +
" * 分多个组\n" +
" * 将上面两个方法复制并改名\n" +
" * 分组必须加组名,且不能重复\n" +
" */ \n" +
"}";
// mybatis-plus 分页插件
final static String mybatisPlusPage = "package %s.config;\n" +
"\n" +
"import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;\n" +
"import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;\n" +
"import org.springframework.context.annotation.Bean;\n" +
"import org.springframework.context.annotation.Configuration;\n" +
"\n" +
"@Configuration\n" +
"@ConditionalOnClass(value = {PaginationInterceptor.class})\n" +
"public class MybatisPlusConfig {\n" +
" @Bean\n" +
" public PaginationInterceptor paginationInterceptor() {\n" +
" PaginationInterceptor paginationInterceptor = new PaginationInterceptor();\n" +
" return paginationInterceptor;\n" +
" }\n" +
"}\n";
// controller模板
final static String controllerTemlate = "package ${package.Controller};\n" +
"\n" +
"import ${package.Entity}.${table.entityName};\n" +
"import ${package.Service}.${table.serviceName};\n" +
"import com.demo.common.ResultVO;import com.baomidou.mybatisplus.core.metadata.IPage;\n" +
"import io.swagger.annotations.Api;" +
"import org.slf4j.Logger;\n" +
"import org.slf4j.LoggerFactory;\n" +
"import io.swagger.annotations.ApiOperation;\n" +
"import com.baomidou.mybatisplus.extension.plugins.pagination.Page;\n" +
"import org.springframework.beans.factory.annotation.Autowired;\n" +
"import org.springframework.transaction.annotation.Transactional;\n" +
"import org.springframework.web.bind.annotation.*;\n" +
"import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;\n" +
"import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;\n" +
"\n" +
"#if(${restControllerStyle})\n" +
"#else\n" +
"import org.springframework.stereotype.Controller;\n" +
"#end\n" +
"#if(${superControllerClassPackage})\n" +
"import ${superControllerClassPackage};\n" +
"#end\n" +
"\n" +
"/**\n" +
" * <p>\n" +
" * $!{table.comment} 前端控制器\n" +
" * </p>\n" +
" *\n" +
" * @author ${author}\n" +
" * @since ${date}\n" +
" */\n" +
"@Api(tags=\"\")\n" +
"#if(${restControllerStyle})\n" +
"@RestController\n" +
"#else\n" +
"@Controller\n" +
"#end\n" +
"@RequestMapping(\"#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end\")\n" +
"#if(${kotlin})\n" +
"class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end\n" +
"\n" +
"#else\n" +
"#if(${superControllerClass})\n" +
"public class ${table.controllerName} extends ${superControllerClass} {\n" +
"#else\n" +
"public class ${table.controllerName} {\n" +
"#end\n" +
"\n" +
" @Autowired\n" +
" private ${table.serviceName} ${table.entityPath}Service;\n" +
"\n" +
" private final Logger log = LoggerFactory.getLogger(this.getClass());\n\n" +
" @PostMapping(\"selectAll\")\n" +
" @ApiOperation(value=\"查找所有\",notes=\"\")\n" +
" public ResultVO selectAll() {\n" +
" return ResultVO.success(\"查找成功\",${table.entityPath}Service.lambdaQuery().getBaseMapper().selectList(null));\n" +
" }\n" +
"\n" +
" @PostMapping(\"selectById\")\n" +
" @ApiOperation(value=\"根据id查找\",notes=\"\")\n" +
" public ResultVO selectById(@RequestParam(\"id\") Integer id) {\n" +
" return ResultVO.success(\"查找成功\",${table.entityPath}Service.getById(id));\n" +
" }\n" +
"\n" +
" @PostMapping(\"selectForPage\")\n" +
" @ApiOperation(value=\"根据条件分页查找\",notes=\"\")\n" +
" public ResultVO selectForPage(@RequestParam(\"pageNum\") Integer pageNum,\n" +
" @RequestParam(\"pageSize\") Integer pageSize,\n" +
" @RequestParam(value = \"condition\",required = false) String condition) {\n" +
" IPage<${table.entityName}> page = new Page<>(pageNum,pageSize);\n" +
" QueryWrapper<${table.entityName}> queryWrapper = new QueryWrapper<>();\n" +
"// queryWrapper.lambda()\n" +
"// .ge(Parent::getId, condition);\n" +
" return ResultVO.success(\"查找成功\",${table.entityPath}Service.getBaseMapper().selectPage(page, queryWrapper));\n" +
" }\n" +
"\n" +
" @PostMapping(\"deleteById\")\n" +
" @ApiOperation(value=\"根据id删除\",notes=\"\")\n" +
" @Transactional(rollbackFor = {Exception.class})\n" +
" public ResultVO deleteById(@RequestParam(\"id\") Integer id) {\n" +
" int i = ${table.entityPath}Service.getBaseMapper().deleteById(id);\n" +
" if (i == 1) {\n" +
" return ResultVO.success(\"删除成功\");\n" +
" } else {\n" +
" return ResultVO.error(\"删除失败\");\n" +
" }\n" +
" }\n" +
"\n" +
" @PostMapping(\"add\")\n" +
" @ApiOperation(value=\"添加\",notes=\"\")\n" +
" @Transactional(rollbackFor = {Exception.class})\n" +
" public ResultVO add(@RequestBody ${table.entityName} ${table.entityPath}) {\n" +
" int i = ${table.entityPath}Service.getBaseMapper().insert(${table.entityPath});\n" +
" if (i == 1) {\n" +
" return ResultVO.success(\"添加成功\");\n" +
" } else {\n" +
" return ResultVO.error(\"添加失败\");\n" +
" } \n" +
" }\n" +
"\n" +
" @PostMapping(\"updateById\")\n" +
" @ApiOperation(value=\"根据id更新非null字段\",notes=\"\")\n" +
" @Transactional(rollbackFor = {Exception.class})\n" +
" public ResultVO updateById(@RequestBody ${table.entityName} ${table.entityPath}) {\n" +
" UpdateWrapper<${table.entityName}> updateWrapper = new UpdateWrapper<>();\n" +
" updateWrapper.eq(\"id\", ${table.entityPath}.getId());\n" +
" int i = ${table.entityPath}Service.lambdaQuery().getBaseMapper().update(${table.entityPath}, updateWrapper);\n" +
" if (i == 1) {\n" +
" return ResultVO.success(\"更新成功\");\n" +
" } else {\n" +
" return ResultVO.error(\"更新失败\");\n" +
" }\n" +
" }\n" +
"\n" +
"}\n" +
"\n" +
"#end";
// ResultVO 返回结果集
final static String resultVO = "package %s.common;\n" +
"\n" +
"public class ResultVO {\n" +
" private String code;\n" +
" private String message;\n" +
" private Object data;\n" +
"\n" +
" // 静态成功方法\n" +
" public static ResultVO success(String message, Object obj) {\n" +
" ResultVO responseResult = new ResultVO();\n" +
" responseResult.setCode(\"success\");\n" +
" responseResult.setMessage(message);\n" +
" responseResult.setData(obj);\n" +
" return responseResult;\n" +
" }\n" +
"\n" +
" // 静态成功方法\n" +
" public static ResultVO success(String message) {\n" +
" ResultVO responseResult = new ResultVO();\n" +
" responseResult.setCode(\"success\");\n" +
" responseResult.setMessage(message);\n" +
" return responseResult;\n" +
" }\n" +
"\n" +
" // 静态失败方法\n" +
" public static ResultVO error(String message) {\n" +
" ResultVO responseResult = new ResultVO();\n" +
" responseResult.setCode(\"error\");\n" +
" responseResult.setMessage(message);\n" +
" return responseResult;\n" +
" }\n" +
"\n" +
"\n" +
"\n" +
" private ResultVO() {\n" +
" }\n" +
"\n" +
" public String getCode() {\n" +
" return code;\n" +
" }\n" +
"\n" +
" public void setCode(String code) {\n" +
" this.code = code;\n" +
" }\n" +
"\n" +
" public String getMessage() {\n" +
" return message;\n" +
" }\n" +
"\n" +
" public void setMessage(String message) {\n" +
" this.message = message;\n" +
" }\n" +
"\n" +
" public Object getData() {\n" +
" return data;\n" +
" }\n" +
"\n" +
" public void setData(Object data) {\n" +
" this.data = data;\n" +
" }\n" +
"}\n";
}
/* maven 依赖包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--配置mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--mybatisplus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
*/