使用mybatis-generator-core 逆向生成 mapper.xml,dao,service,serviceImpl,Controller
1.pom文件引入逆向工具类,swagger 描述字段
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
2.项目resources 创建逆向配置文件 generator.properties generatorConfig.xml
-
generator.properties
jdbc.driverLocation=F:\\exe\\mysql-connector-java-5.1.47.jar # mysql驱动地址本地 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.connectionURL=jdbc:mysql://localhost:3306/jxc jdbc.userId=root jdbc.password=7719458
-
generatorConfig.xml 需要需改生成文件的包地址
<?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="generator.properties"></properties> <!--指定特定数据库的jdbc驱动jar包的位置--> <classPathEntry location="${jdbc.driverLocation}"/> <context id="default" targetRuntime="MyBatis3"> <plugin type="com.sh.common.generator.ServiceAndControllerGeneratorPlugin" > <property name="targetProject" value="./src/main/java"/> <property name="servicePackage" value="com.sh.jxc.service"/> <property name="serviceImplPackage" value="com.sh.jxc.service.impl"/> <property name="controllerPackage" value="com.sh.jxc.controller"/> <!--UserService,该值则为Service--> <property name="serviceSuffix" value="Service"/> <!--Service接口的父接口--> <!-- <property name="superServiceInterface" value="org.aurochsframework.boot.commons.service.GeneralService"/> <!–ServiceImpl的父类–> <property name="superServiceImpl" value="org.aurochsframework.boot.commons.service.AbstractGeneralService"/> <!–controller的父类接口–> <property name="superController" value="org.aurochsframework.boot.commons.controller.GeneralCrudController"/>--> </plugin> <!-- optional,旨在创建class时,对注释进行控制 自定义java --> <commentGenerator type="com.sh.common.generator.CommentGenerator"> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true"/> <property name="suppressDate" value="true"/> <property name="addRemarkComments" value="true"/> </commentGenerator> <!--jdbc的数据库连接 --> <jdbcConnection driverClass="${jdbc.driverClass}" connectionURL="${jdbc.connectionURL}" userId="${jdbc.userId}" password="${jdbc.password}"> </jdbcConnection> <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制--> <javaTypeResolver> <property name="forceBigDecimals" value="true"/> </javaTypeResolver> <!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类 targetPackage 指定生成的model生成所在的包名 targetProject 指定在该项目下所在的路径 --> <javaModelGenerator targetPackage="com.sh.jxc.entity" targetProject="src/main/java"> <!-- 是否允许子包,即targetPackage.schemaName.tableName --> <property name="enableSubPackages" value="false"/> <!-- 是否对model添加 构造函数 --> <property name="constructorBased" value="true"/> <!-- 是否对类CHAR类型的列的数据进行trim操作 --> <property name="trimStrings" value="true"/> <!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 --> <property name="immutable" value="false"/> </javaModelGenerator> <!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 --> <sqlMapGenerator targetPackage="mapper.jxc" targetProject="./src/main/resources"/> <!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码 type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 --> <javaClientGenerator targetPackage="com.sh.jxc.dao" targetProject="src/main/java" type="XMLMAPPER"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!-- <table tableName="company" domainObjectName="company" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table>--> <table tableName="company_notes" domainObjectName="CompanyNotes" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <!--<table tableName="inventory" domainObjectName="Inventory" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="inlibrary_notes" domainObjectName="InlibraryNotes" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="inlibrary_notes_detail" domainObjectName="InlibraryNotesDetail" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table>--> </context> </generatorConfiguration>
3.创建执行类
package com.sh.common.generator;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
/**
* 逆向生成 mybatis 开发包
* 1,修改 generator.properties 文件中内容 数据库链接 mysql驱动地址
* 2,修改 generatorConfig.xml 文件中 table节点的内容 表名和生成的entity 名
* 3,运行main
*/
public class GeneratorSqlmap {
public static void main(String[] args) throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
//MBG 执行过程中的警告信息
List<String> warnings = new ArrayList<>();
//当生成的代码重复时,覆盖原代码
boolean overwrite = true;
//读取我们的 MBG 配置文件
InputStream is = GeneratorSqlmap.class.getResourceAsStream("/generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(is);
is.close();
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
//创建 MBG
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
//执行生成代码
myBatisGenerator.generate(null);
//输出警告信息
for (String warning : warnings) {
System.out.println(warning);
}
}
}
- 给实体添加注释使用swagger
package com.sh.common.generator;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.internal.util.StringUtility;
import java.util.Properties;
public class CommentGenerator extends DefaultCommentGenerator {
private boolean addRemarkComments = false;
private static final String EXAMPLE_SUFFIX="Example";
private static final String API_MODEL_PROPERTY_FULL_CLASS_NAME="io.swagger.annotations.ApiModelProperty";
/**
* 设置用户配置的参数
*/
@Override
public void addConfigurationProperties(Properties properties) {
super.addConfigurationProperties(properties);
this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments"));
}
/**
* 给字段添加注释
*/
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn) {
String remarks = introspectedColumn.getRemarks();
//根据参数和备注信息判断是否添加备注信息
if(addRemarkComments&&StringUtility.stringHasValue(remarks)){
// addFieldJavaDoc(field, remarks);
//数据库中特殊字符需要转义
if(remarks.contains("\"")){
remarks = remarks.replace("\"","'");
}
//给model的字段添加swagger注解
field.addJavaDocLine("@ApiModelProperty(value = \""+remarks+"\")");
}
}
/**
* 给model的字段添加注释
*/
private void addFieldJavaDoc(Field field, String remarks) {
//文档注释开始
field.addJavaDocLine("/**");
//获取数据库字段的备注信息
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for(String remarkLine:remarkLines){
field.addJavaDocLine(" * "+remarkLine);
}
addJavadocTag(field, false);
field.addJavaDocLine(" */");
}
@Override
public void addJavaFileComment(CompilationUnit compilationUnit) {
super.addJavaFileComment(compilationUnit);
//只在model中添加swagger注解类的导入
if(!compilationUnit.isJavaInterface()&&!compilationUnit.getType().getFullyQualifiedName().contains(EXAMPLE_SUFFIX)){
compilationUnit.addImportedType(new FullyQualifiedJavaType(API_MODEL_PROPERTY_FULL_CLASS_NAME));
}
}
}
- 自定义生成 service和controller 配置 对应 generatorConfig 里的配置
package com.sh.common.generator;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.java.*;
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import java.util.ArrayList;
import java.util.List;
/**
* 生成service 和 controller 配置类
*/
public class ServiceAndControllerGeneratorPlugin extends PluginAdapter {
// 项目目录,一般为 src/main/java
private String targetProject;
// service包名,如:com.thinkj2ee.cms.service.service
private String servicePackage;
// service实现类包名,如:com.thinkj2ee.cms.service.service.impl
private String serviceImplPackage;
// Controlle类包名,如:com.thinkj2ee.cms.service.controller
private String controllerPackage;
// service接口名前缀
private String servicePreffix;
// service接口名后缀
private String serviceSuffix;
// service接口的父接口
//private String superServiceInterface;
// service实现类的父类
private String superServiceImpl;
// controller类的父类
private String superController;
// dao接口基类
private String superDaoInterface;
// Example类的包名
private String examplePacket;
private String recordType;
private String modelName;
private FullyQualifiedJavaType model;
private String serviceName;
private String serviceImplName;
private String controllerName;
@Override
public boolean validate(List<String> list) {
boolean valid = true;
targetProject = properties.getProperty("targetProject");
servicePackage = properties.getProperty("servicePackage");
serviceImplPackage = properties.getProperty("serviceImplPackage");
servicePreffix = properties.getProperty("servicePreffix");
servicePreffix = stringHasValue(servicePreffix) ? servicePreffix : "";
serviceSuffix = properties.getProperty("serviceSuffix");
serviceSuffix = stringHasValue(serviceSuffix) ? serviceSuffix : "";
//superServiceInterface = properties.getProperty("superServiceInterface");
superServiceImpl = properties.getProperty("superServiceImpl");
superDaoInterface = properties.getProperty("superDaoInterface");
controllerPackage = properties.getProperty("controllerPackage");
superController = properties.getProperty("superController");
return valid;
}
@Override
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
recordType = introspectedTable.getBaseRecordType();
modelName = recordType.substring(recordType.lastIndexOf(".") + 1);
model = new FullyQualifiedJavaType(recordType);
serviceName = servicePackage + "." + servicePreffix + modelName + serviceSuffix;
serviceImplName = serviceImplPackage + "." + modelName + serviceSuffix+"Impl";
examplePacket=recordType.substring(0,recordType.lastIndexOf("."));
controllerName=controllerPackage.concat(".").concat(modelName).concat("Controller");
List<GeneratedJavaFile> answer = new ArrayList<>();
GeneratedJavaFile gjf = generateServiceInterface(introspectedTable);
GeneratedJavaFile gjf2 = generateServiceImpl(introspectedTable);
GeneratedJavaFile gjf3 = generateController(introspectedTable);
answer.add(gjf);
answer.add(gjf2);
answer.add(gjf3);
return answer;
}
// 生成service接口
private GeneratedJavaFile generateServiceInterface(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType service = new FullyQualifiedJavaType(serviceName);
Interface serviceInterface = new Interface(service);
serviceInterface.setVisibility(JavaVisibility.PUBLIC);
// 添加父接口
/*if(stringHasValue(superServiceInterface)) {
String superServiceInterfaceName = superServiceInterface.substring(superServiceInterface.lastIndexOf(".") + 1);
serviceInterface.addImportedType(new FullyQualifiedJavaType(superServiceInterface));
serviceInterface.addImportedType(new FullyQualifiedJavaType(recordType));
serviceInterface.addSuperInterface(new FullyQualifiedJavaType(superServiceInterfaceName + "<" + modelName + ">"));
}*/
GeneratedJavaFile gjf = new GeneratedJavaFile(serviceInterface, targetProject, context.getJavaFormatter());
return gjf;
}
// 生成serviceImpl实现类
private GeneratedJavaFile generateServiceImpl(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType service = new FullyQualifiedJavaType(serviceName);
FullyQualifiedJavaType serviceImpl = new FullyQualifiedJavaType(serviceImplName);
TopLevelClass clazz = new TopLevelClass(serviceImpl);
//描述类的作用域修饰符
clazz.setVisibility(JavaVisibility.PUBLIC);
//描述类 引入的类
clazz.addImportedType(service);
//描述类 的实现接口类
clazz.addSuperInterface(service);
if(stringHasValue(superServiceImpl)) {
String superServiceImplName = superServiceImpl.substring(superServiceImpl.lastIndexOf(".") + 1);
clazz.addImportedType(superServiceImpl);
clazz.addImportedType(recordType);
clazz.setSuperClass(superServiceImplName + "<" + modelName + ">");
}
clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Service"));
clazz.addAnnotation("@Service");
String daoFieldType = introspectedTable.getMyBatis3JavaMapperType();
String daoFieldName = firstCharToLowCase(daoFieldType.substring(daoFieldType.lastIndexOf(".") + 1));
//描述类的成员属性
Field daoField = new Field(daoFieldName, new FullyQualifiedJavaType(daoFieldType));
clazz.addImportedType(new FullyQualifiedJavaType(daoFieldType));
clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));
//描述成员属性 的注解
daoField.addAnnotation("@Autowired");
//描述成员属性修饰符
daoField.setVisibility(JavaVisibility.PRIVATE);
clazz.addField(daoField);
//描述 方法名
GeneratedJavaFile gjf2 = new GeneratedJavaFile(clazz, targetProject, context.getJavaFormatter());
return gjf2;
}
// 生成controller类
private GeneratedJavaFile generateController(IntrospectedTable introspectedTable) {
FullyQualifiedJavaType controller = new FullyQualifiedJavaType(controllerName);
TopLevelClass clazz = new TopLevelClass(controller);
//描述类的作用域修饰符
clazz.setVisibility(JavaVisibility.PUBLIC);
//添加@Controller注解,并引入相应的类
clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.web.bind.annotation.RestController"));
clazz.addAnnotation("@RestController");
//添加@RequestMapping注解,并引入相应的类
clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.web.bind.annotation.RequestMapping"));
clazz.addAnnotation("@RequestMapping(\"/"+firstCharToLowCase(modelName)+"\")");
//添加@Api注解,并引入相应的类
clazz.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.Api"));
String controllerSimpleName = controllerName.substring(controllerName.lastIndexOf(".") + 1);
clazz.addAnnotation("@Api(tags = \""+controllerSimpleName+"\", description = \""+controllerSimpleName+"\")");
//引入controller的父类和model,并添加泛型
if(stringHasValue(superController)) {
clazz.addImportedType(superController);
clazz.addImportedType(recordType);
FullyQualifiedJavaType superInterfac = new FullyQualifiedJavaType(superController+"<"+modelName+">");
clazz.addSuperInterface(superInterfac);
}
//引入Service
FullyQualifiedJavaType service = new FullyQualifiedJavaType(serviceName);
clazz.addImportedType(service);
//添加Service成员变量
String serviceFieldName = firstCharToLowCase(serviceName.substring(serviceName.lastIndexOf(".") + 1));
Field daoField = new Field(serviceFieldName, new FullyQualifiedJavaType(serviceName));
clazz.addImportedType(new FullyQualifiedJavaType(serviceName));
clazz.addImportedType(new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired"));
//描述成员属性 的注解
daoField.addAnnotation("@Autowired");
//描述成员属性修饰符
daoField.setVisibility(JavaVisibility.PRIVATE);
clazz.addField(daoField);
GeneratedJavaFile gjf2 = new GeneratedJavaFile(clazz, targetProject, context.getJavaFormatter());
return gjf2;
}
private String firstCharToLowCase(String str) {
char[] chars = new char[1];
//String str="ABCDE1234";
chars[0] = str.charAt(0);
String temp = new String(chars);
if(chars[0] >= 'A' && chars[0] <= 'Z') {
return str.replaceFirst(temp,temp.toLowerCase());
}
return str;
}
}
完