一、背景介绍
最近恰巧遇到代码生成的相关任务,结合调研结果,现将自己的实验经历做个小结,
本文基于 SpringBoot + Mybatis 架构展开,代码生成以 Mybatis Generator 为核心,
同时,基于 FreeMarker 制作了自定义插件,拓展了 Mybatis Generator 的相关功能,
最终,实现了 DAO + Service + Controller 各层的自动代码生成。
二、 实验步骤
2.1 首先,实现自己的 Mybatis Generator 插件,用于生成 Service 和 Controller,
因为原生 generator 只能生成 DAO
打开 STS, 创建一个 maven 项目,maven-archetype-quickstart 类型即可
删除 src/test ,没啥用
编辑 pom.xml,添加 Mybatis 依赖、FreeMarker 依赖
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.shida</groupId>
<artifactId>mybatis3plugins</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mybatis3plugins</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.6</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
</dependencies>
</project>
修改 App.java 为 ServiceControllerPlugin.java,同时编辑内容为
package org.shida.mybatis3plugins;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
public class ServiceControllerPlugin extends PluginAdapter {
public boolean validate(List<String> warnings) {
return true;
}
@Override
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
String javaRepositoryPackage = this.getContext().getJavaClientGeneratorConfiguration().getTargetPackage();
String javaMapperType = introspectedTable.getMyBatis3JavaMapperType();
String topPackage = javaRepositoryPackage.substring(0, javaRepositoryPackage.lastIndexOf('.'));
String javaClassName = javaMapperType.substring(javaMapperType.lastIndexOf('.') + 1, javaMapperType.length()).replace("Mapper", "");
String targetProject = this.getContext().getJavaClientGeneratorConfiguration().getTargetProject();
Map<String, String> root = new HashMap<String, String>();
root.put("topPackage", topPackage);
root.put("EntityName", javaClassName);
root.put("entityName", new StringBuilder().append(Character.toLowerCase(javaClassName.charAt(0)))
.append(javaClassName.substring(1)).toString());
genService(targetProject, topPackage, javaClassName, root);
genController(targetProject, topPackage, javaClassName, root);
return null;
}
@SuppressWarnings("deprecation")
private void genService(String targetProject, String topPackage, String javaClassName, Map<String, String> root) {
String dirPath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/service";
String filePath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/service/" + javaClassName
+ "Service.java";
File dir = new File(dirPath);
File file = new File(filePath);
if (file.exists()) {
System.err.println(file + " already exists, it was skipped.");
return;
} else {
try {
dir.mkdirs();
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Configuration cfg = new Configuration();
cfg.setClassForTemplateLoading(this.getClass(), "/");
cfg.setObjectWrapper(new DefaultObjectWrapper());
try {
Template temp = cfg.getTemplate("EntityService.ftl");
Writer out = new OutputStreamWriter(new FileOutputStream(file));
temp.process(root, out);
out.flush();
} catch (TemplateNotFoundException e) {
e.printStackTrace();
} catch (MalformedTemplateNameException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
private void genController(String targetProject, String topPackage, String javaClassName,
Map<String, String> root) {
String dirPath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/controller";
String filePath = targetProject + "/" + topPackage.replaceAll("\\.", "/") + "/controller/" + javaClassName
+ "Controller.java";
File dir = new File(dirPath);
File file = new File(filePath);
if (file.exists()) {
System.err.println(file + " already exists, it was skipped.");
return;
} else {
try {
dir.mkdirs();
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Configuration cfg = new Configuration();
cfg.setClassForTemplateLoading(this.getClass(), "/");
cfg.setObjectWrapper(new DefaultObjectWrapper());
try {
Template temp = cfg.getTemplate("EntityController.ftl");
Writer out = new OutputStreamWriter(new FileOutputStream(file));
temp.process(root, out);
out.flush();
} catch (TemplateNotFoundException e) {
e.printStackTrace();
} catch (MalformedTemplateNameException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
}
该 Plugin 继承了 PluginAdapter ,通过重写 contextGenerateAdditionalJavaFiles 方法实现额外文件的生成
代码中,调用了 freemarker 模板,需要把模板放至 src/main/resources 文件夹下
注意,这里为了简单,我只示例了 实例创建方法 create/insert
Service 模板:EntityService.ftl ,
package ${topPackage}.service;
import ${topPackage}.domain.${EntityName};
import ${topPackage}.repository.${EntityName}Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* generated by shida's plugin
*/
@Service
public class ${EntityName}Service {
@Autowired
private ${EntityName}Mapper ${entityName}Mapper;
public int insert(${EntityName} ${entityName}) {
return ${entityName}Mapper.insert(${entityName});
}
}
Controller 模板:EntityController.ftl
package ${topPackage}.controller;
import ${topPackage}.domain.${EntityName};
import ${topPackage}.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;
/**
* generated by shida's plugin
*/
@RestController
@RequestMapping("/api")
public class ${EntityName}Controller {
@Autowired
private ${EntityName}Service ${entityName}Service;
@PostMapping("/${entityName}/create")
public int create(@RequestBody ${EntityName} ${entityName}) {
return ${entityName}Service.insert(${entityName});
}
}
编译插件并安装到本地仓库,mvn install
2.2 然后,我们创建一个 SpringBoot 项目,同时整合 MyBatis 和 Mybatis Generator
打开 STS, 创建一个 maven 项目,maven-archetype-quickstart 类型即可
删除 src/test ,这里没什么用
修改 pom.xml,添加相关依赖和插件,主要是 SpringBoot 和 Mybatis 以及 Archetype 相关的
注意,这里同时引用了 我们在 2.1 步生成的插件 mybatis3plugins
修改后的最后版本为:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.shida</groupId>
<artifactId>gendemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>gendemo</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<verbose>false</verbose>
<overwrite>true</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.shida</groupId>
<artifactId>mybatis3plugins</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
</project>
编写 SpringBoot 启动入口类前,首先修改包名,将 org.shida.gendemo 修改为 org.shida
之所以这么改,是为了防止自动生成代码时产生错误的包问题
然后,修改 App.java 的内容,设置为 SpringBoot 启动类,最终 App.java 的内容为
package org.shida;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
@Configuration
@SpringBootApplication
@MapperScan(basePackages = "org.shida")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
在 src/main 下建立 resources 文件夹,然后在 resources 文件夹下创建 application.yml 文件
该文件是 SpringBoot 的配置文件,最终配置为(数据库信息改成你自己真实使用的)
spring:
jackson:
serialization.indent_output: true
datasource:
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://127.0.0.1:3306/generate?useUnicode=true&characterEncoding=utf8&useSSL=false
username: shida
password: shida
server:
port: 9000
接着,在 resources 文件夹下创建 generatorConfig.xml,设置代码生成的相关信息
注意,这里插件加入了我们自己的插件,org.shida.mybatis3plugins.ServiceControllerPlugin
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="mysql.properties" />
<context id="mysqlTables" targetRuntime="MyBatis3">
<property name="javaFileEncoding" value="UTF-8" />
<property name="javaFormatter"
value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" />
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
<plugin type="org.mybatis.generator.plugins.MapperAnnotationPlugin" />
<plugin type="org.shida.mybatis3plugins.ServiceControllerPlugin" />
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="${jdbc.url}" userId="${jdbc.username}"
password="${jdbc.password}" />
<!--指定生成的类型为java类型,避免数据库中number等类型字段 -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--自动生成的实体的存放包路径 -->
<javaModelGenerator
targetPackage="org.shida.domain" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<sqlMapGenerator targetPackage="org.shida.xml"
targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="ANNOTATEDMAPPER"
targetPackage="org.shida.repository" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="rootInterface" value="" />
</javaClientGenerator>
</context>
</generatorConfiguration>
可以看到 generatorConfig.xml 内引用了 mysql.properties,
因此,我们在 resources 内放置 mysql.properties ,数据库信息写成你的真实信息
jdbc.url=jdbc:mysql://127.0.0.1:3306/generate?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=shida
jdbc.password=shida
至此,SpringBoot 模板工程就已经建好了,我们基于此生成 Archetype
执行,mvn archetype:create-from-project
2.3 编辑模板,设置变量替换项
build 成功后,我们把 target/generated-sources/archetype 拷贝到一个工作目录,
然后我们使用 vscode 打开 archetype 文件夹
删除不必要的文件,下边3个,这是 eclipse 相关的,对于模板项目没用
src\main\resources\archetype-resources\.settings、
src\main\resources\archetype-resources\.classpath、
src\main\resources\archetype-resources\.project
修改 src\main\resources\META-INF\maven\archetype-metadata.xml
这里配置了 archetype 需要传入的参数(主要是db信息),以及打包的文件信息,最后修改内容为
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="gendemo"
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<requiredProperties>
<requiredProperty key="dbHost" >
<defaultValue>127.0.0.1</defaultValue>
</requiredProperty>
<requiredProperty key="dbPort" >
<defaultValue>3306</defaultValue>
</requiredProperty>
<requiredProperty key="dbName" />
<requiredProperty key="dbTables" />
<requiredProperty key="dbUser" />
<requiredProperty key="dbPassword" />
</requiredProperties>
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</fileSet>
</fileSets>
</archetype-descriptor>
需要注意的是,除了在 archetype-metadata.xml 中配置参数外,还需要在
src\test\resources\projects\basic\archetype.properties 中指定,参数名与archetype-metadata是对应的
属性任意写,基于模板创建项目时是要以实际传入为准的
#Sat May 26 14:10:10 CST 2018
package=it.pkg
version=0.1-SNAPSHOT
groupId=archetype.it
artifactId=basic
dbHost=127.0.0.1
dbPort=3306
dbName=database
dbTables=table
dbUser=root
dbPassword=root
然后,我们修改源码文件,将变量用占位符替换
application.xml
spring:
jackson:
serialization.indent_output: true
datasource:
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://${dbHost}:${dbPort}/${dbName}?useUnicode=true&characterEncoding=utf8&useSSL=false
username: ${dbUser}
password: ${dbPassword}
server:
port: 9000
mysql.properties
#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
jdbc.url=jdbc:mysql://${dbHost}:${dbPort}/${dbName}?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=${dbUser}
jdbc.password=${dbPassword}
generatorConfig.xml
#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="mysql.properties" />
<context id="mysqlTables" targetRuntime="MyBatis3">
<property name="javaFileEncoding" value="UTF-8" />
<property name="javaFormatter"
value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" />
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
<plugin type="org.mybatis.generator.plugins.MapperAnnotationPlugin" />
<plugin type="org.shida.mybatis3plugins.ServiceControllerPlugin" />
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="${symbol_dollar}{jdbc.url}" userId="${symbol_dollar}{jdbc.username}"
password="${symbol_dollar}{jdbc.password}" />
<!--指定生成的类型为java类型,避免数据库中number等类型字段 -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--自动生成的实体的存放包路径 -->
<javaModelGenerator
targetPackage="${package}.domain" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<sqlMapGenerator targetPackage="${package}.xml"
targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="ANNOTATEDMAPPER"
targetPackage="${package}.repository" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="rootInterface" value="" />
</javaClientGenerator>
#foreach( $tableName in $dbTables.split(",") )
#set($upperTableName = $tableName.substring(0, 1).toUpperCase() + $tableName.substring(1))
<table schema="${dbName}" tableName="${tableName}" domainObjectName="$upperTableName">
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="mysql" identity="true" />
</table>
#end
</context>
</generatorConfiguration>
修改 pom.xml,删除 maven-archetype-plugin ,已经不需要了,删除
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<version>2.2</version>
</plugin>
然后,我们执行 mvn install 安装该 archetype 到仓库
2.4 验证 archetype
首先设置 sts maven setting.xml 路径为正确路径
新建一个 maven 项目,勾选 Include snapshot archetypes,选择我们自己的 archetype
需要填写 DB 相关参数,填写真实的 db 信息,多个 table 用 逗号 分隔
生成项目结构为:
然后,首先生成代码,执行 mvn mybatis-generator:generate
红框内的代码自动生成了,运行 App.java
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.2.RELEASE)
2018-05-27 14:53:11.757 INFO 5768 --- [ main] org.shida.test.App : Starting App on auto-PC with PID 5768 (C:\Users\auto\Documents\workspace-sts-3.9.4.RELEASE\test\target\classes started by auto in C:\Users\auto\Documents\workspace-sts-3.9.4.RELEASE\test)
2018-05-27 14:53:11.762 INFO 5768 --- [ main] org.shida.test.App : No active profile set, falling back to default profiles: default
2018-05-27 14:53:11.858 INFO 5768 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@19bb07ed: startup date [Sun May 27 14:53:11 CST 2018]; root of context hierarchy
2018-05-27 14:53:12.658 INFO 5768 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Generic; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Generic.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]]
2018-05-27 14:53:13.656 INFO 5768 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9000 (http)
2018-05-27 14:53:13.697 INFO 5768 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-05-27 14:53:13.698 INFO 5768 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.31
2018-05-27 14:53:13.708 INFO 5768 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [D:\java\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;D:/jre/bin/server;D:/jre/bin;D:/jre/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;D:\java\bin;D:\apache-maven-3.5.3\bin;;C:\Program Files (x86)\Microsoft VS Code\bin;D:\spring-tool-suite-3.9.4.RELEASE-e4.7.3a-win32-x86_64\sts-bundle\sts-3.9.4.RELEASE;;.]
2018-05-27 14:53:13.819 INFO 5768 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-05-27 14:53:13.820 INFO 5768 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1965 ms
2018-05-27 14:53:14.008 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-05-27 14:53:14.016 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-05-27 14:53:14.017 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-05-27 14:53:14.017 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-05-27 14:53:14.017 INFO 5768 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-05-27 14:53:14.462 INFO 5768 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-27 14:53:14.825 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@19bb07ed: startup date [Sun May 27 14:53:11 CST 2018]; root of context hierarchy
2018-05-27 14:53:14.917 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/price/create],methods=[POST]}" onto public int org.shida.test.controller.PriceController.create(org.shida.test.domain.Price)
2018-05-27 14:53:14.918 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/user/create],methods=[POST]}" onto public int org.shida.test.controller.UserController.create(org.shida.test.domain.User)
2018-05-27 14:53:14.920 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-05-27 14:53:14.921 INFO 5768 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-05-27 14:53:14.956 INFO 5768 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-27 14:53:14.956 INFO 5768 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-27 14:53:15.267 INFO 5768 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-05-27 14:53:15.268 INFO 5768 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'dataSource' has been autodetected for JMX exposure
2018-05-27 14:53:15.274 INFO 5768 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2018-05-27 14:53:15.321 INFO 5768 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9000 (http) with context path ''
2018-05-27 14:53:15.324 INFO 5768 --- [ main] org.shida.test.App : Started App in 4.029 seconds (JVM running for 4.725)
应用成功启动,然后实验一下,使用 postman,发送一条请求
可以看到,已经成功录入数据
三、 总结
整体功能,本文从流程上已经走通了:
首先编写自定义的generator plugin,实现对 Service 和 Controller 的代码生成,
然后定制一个SpringBoot 模板工程,打包成 archetype
以后直接基于该 archetype 就可以快速创建项目了,项目已经集成好了自动代码生成框架,
可以很方便地生成基础代码,至于 Service 和 Controller 功能代码的完善,就交给阅读本文的您去逐渐完善吧!