tags: [mybatis, mybatis generator]
categories: [mybatis]
前言
实际开发之中,虽然有很多CRUD工具,但是使用最多的还是Mybatis,而Mybatis Gerator
可以帮助你自动生成基本的单表CRUD代码,提高效率
但是生成的代码有些地方已经不符合当前的风格和标准,比如现在很多项目都是使用lombok
,而不是在实体类里面添加get/set方法,默认生成的注释信息不友好,这个时候我们可以通过一些修改来生成我们想要的结果
使用
引入依赖
后边的Plugn是以Maven生成的,若以代码形式来生成则无需配置
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<!--自定义路径,否则会自动识别GeneratorConfig.xml文件-->
<!-- <configurationFiile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>-->
<!--是为了运行mvn mybatis-generator:generate -e时显示具体过程-->
<verbose>true</verbose>
<!--为了生成文件时后一次生成的文件覆盖前一次生成的同名文件-->
<overwrite>true</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
</dependencies>
</plugin>
后边的Plugn是以Maven生成需要配置的,若以代码形式来生成则无需配置
我的存放目录如下
添加自定义插件
package com.bwensun.common.mybatis;
import org.mybatis.generator.api.IntrospectedColumn;
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.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* lombok插件
*
* @author bwensun
* @date 2019/12/16
*/
public class LombokPlugin extends PluginAdapter {
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
SimpleDateFormat dateFormatter = new SimpleDateFormat(properties.getProperty("dateFormat", "yyyy-MM-dd"));
//接口添加注释
interfaze.addJavaDocLine("/**");
interfaze.addJavaDocLine(" * " + introspectedTable.getRemarks());
interfaze.addJavaDocLine(" *");
interfaze.addJavaDocLine(" * @author " + properties.getProperty("author"));
interfaze.addJavaDocLine(" * @date " + dateFormatter.format(new Date()));
interfaze.addJavaDocLine(" */");
//dao添加注解
addAnnotations(interfaze, "org.springframework.stereotype.Repository", "@Repository");
return true;
}
@Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
if (Boolean.parseBoolean(this.properties.getProperty("data"))) {
addAnnotations(topLevelClass, "lombok.Data", "@Data");
} else {
addAnnotations(topLevelClass, "lombok.Getter", "@Getter");
addAnnotations(topLevelClass, "lombok.Setter", "@Setter");
addAnnotations(topLevelClass, "lombok.ToString", "@ToString");
}
if (Boolean.parseBoolean(this.properties.getProperty("builder"))) {
addAnnotations(topLevelClass, "lombok.Builder", "@Builder");
}
return true;
}
/**
* 关闭get方法生成
*/
@Override
public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
return false;
}
/**
* 关闭set方法生成
*/
@Override
public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
return false;
}
public void addSwaggerAnnotation(){
}
/**
* 设置类注解
*
* @param importedType 导包类型
* @param annotation 注解
*/
private void addAnnotations(TopLevelClass topLevelClass, String importedType, String annotation) {
topLevelClass.addImportedType(importedType);
topLevelClass.addAnnotation(annotation);
}
/**
* 设置接口注解
*
* @param importedType 导包类型
* @param annotation 注解
*/
private void addAnnotations(Interface interfaze, String importedType, String annotation) {
interfaze.addImportedType(new FullyQualifiedJavaType(importedType));
interfaze.addAnnotation(annotation);
}
private String date2Str(Date date) {
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
return format.format(date);
}
}
说明
Mybatis Generator的配置文件中包含了plugn标签,我们就可以通过手写插件来实现我们自己的功能,
重写注释部分注释方法
package com.bwensun.common.mybatis;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
* 增加 swagger 字段注释支持
*
* @author daiwenzh5
* @date 2019/9/8 18:56
*/
public class CustomCommentGenerator extends DefaultCommentGenerator {
private Properties properties;
public CustomCommentGenerator() {
properties = new Properties();
}
@Override
public void addConfigurationProperties(Properties properties) {
// 获取自定义的 properties
this.properties.putAll(properties);
}
/**
* 添加 swagger 字段注解
*
* @param field 字段
* @param introspectedTable 表
* @param introspectedColumn 列
* @param imports 导入类
*/
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {
imports.add(new FullyQualifiedJavaType("io.swagger.annotations.ApiModelProperty"));
String remarks = introspectedColumn.getRemarks();
field.addAnnotation(this.getSwaggerAnnotation(field.getName(), remarks));
super.addFieldAnnotation(field, introspectedTable, introspectedColumn, imports);
}
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) {
super.addFieldAnnotation(field, introspectedTable, set);
}
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
// 获取字段注释
String remarks = introspectedColumn.getRemarks();
field.addJavaDocLine("/**");
field.addJavaDocLine(" * " + remarks);
field.addJavaDocLine(" */");
}
@Override
public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
/* if (suppressAllComments) {
return;
}*/
String methodDoc = getMethodDoc(method, introspectedTable);
method.addJavaDocLine("/**");
method.addJavaDocLine(" * " + methodDoc);
method.addJavaDocLine(" *");
setMethodParam(method);
setMethodReturn(method, introspectedTable);
method.addJavaDocLine(" */");
}
@Override
public void addClassAnnotation(InnerClass innerClass, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) {
super.addClassAnnotation(innerClass, introspectedTable, set);
}
@Override
public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
String author = properties.getProperty("author");
String dateFormat = properties.getProperty("dateFormat", "yyyy-MM-dd");
SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat);
// 获取表注释
String remarks = introspectedTable.getRemarks();
topLevelClass.addJavaDocLine("/**");
topLevelClass.addJavaDocLine(" * " + remarks);
topLevelClass.addJavaDocLine(" *");
topLevelClass.addJavaDocLine(" * @author " + author);
topLevelClass.addJavaDocLine(" * @date " + dateFormatter.format(new Date()));
topLevelClass.addJavaDocLine(" */");
}
/**
* 获取 swagger 注解信息
*
* @param name 字段名
* @param remarks 注释信息
* @return 返回 swagger 注释字符串
*/
private String getSwaggerAnnotation(String name, String remarks) {
StringBuffer buffer = new StringBuffer("@ApiModelProperty(");
buffer.append("name = \"");
buffer.append(name);
if (StringUtility.stringHasValue(remarks)) {
buffer.append("\", value = \"");
buffer.append(remarks);
}
buffer.append("\")");
return buffer.toString();
}
private String getMethodDoc(Method method, IntrospectedTable introspectedTable) {
String remarks = introspectedTable.getRemarks();
String methodDoc;
switch (method.getName()){
case "deleteByPrimaryKey":
methodDoc = ("根据主键删除" + remarks + "记录");
break;
case "selectByPrimaryKey":
methodDoc = ("根据主键查询" + remarks + "记录");
break;
case "insert":
methodDoc = ("新增记录至" + remarks);
break;
case "selectAll":
methodDoc = ("查询" + remarks + "所有记录");
break;
case "updateByPrimaryKey":
methodDoc = ("根据主键更新" + remarks + "记录");
break;
default:
methodDoc = "description";
break;
}
return methodDoc;
}
/**
* 设置参数注释
*
* @param method 方法
*/
private void setMethodParam(Method method) {
List<Parameter> parameters = method.getParameters();
if (parameters.size() != 0){
parameters.forEach(x ->
method.addJavaDocLine(" * @param " + x.getName() + ("ID".equalsIgnoreCase(x.getName())?" 主键":" 记录") )
);
}
}
/**
* 设置返回值注释
*
* @param method 方法
* @param introspectedTable 表对象
*/
private void setMethodReturn(Method method, IntrospectedTable introspectedTable) {
String methodReturn;
String shortName = method.getReturnType().getShortName();
if ("int".equalsIgnoreCase(shortName)){
methodReturn = "受影响的记录数";
}else if (shortName.startsWith("java.util.List")){
methodReturn = introspectedTable.getRemarks() + "list";
}else {
methodReturn = introspectedTable.getRemarks() + "记录";
}
method.addJavaDocLine(" * @return " + methodReturn);
}
}
配置文件配置
<?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>
<!-- 数据库驱动:选择你的本地硬盘上面的数据库驱动包-->
<classPathEntry location="D:\ProgramFile\maven\maven_repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar"/>
<context id="CustomGenerator" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple">
<property name="autoDelimitKeywords" value="false"/>
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!-- 插件 -->
<plugin type="com.bwensun.common.mybatis.LombokPlugin">
<property name="author" value="bwensun"/>
<property name="builder" value="false"/>
<property name="data" value="false"/>
</plugin>
<commentGenerator type = "com.bwensun.common.mybatis.CustomCommentGenerator">
<property name="javaFileEncoding" value="UTF-8"/>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="false" />
<property name="author" value="郑建雄"/>
<property name="dateFormat" value="yyyy/MM/dd"/>
</commentGenerator>
<!--数据库链接URL,用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/blog?useSSL=true"
userId="root" password="285413">
<property name="useInformationSchema" value="true" />
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 生成模型的包名和位置-->
<javaModelGenerator targetPackage="com.bwensun.blog.domain" targetProject="BLOG_API/src/main/java">
<!-- 是否允许子包,即targetPackage.schemaName.tableName -->
<property name="enableSubPackages" value="true"/>
<!-- 是否对model添加 构造函数 -->
<property name="constructorBased" value="false"/>
<!-- 是否对类CHAR类型的列的数据进行trim操作 -->
<property name="trimStrings" value="true"/>
<!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 -->
<!--<property name="immutable" value="false"/>-->
</javaModelGenerator>
<!-- 生成映射文件的包名和位置-->
<sqlMapGenerator targetPackage="mapper" targetProject="BLOG_USER_SERVICE/src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- 生成DAO的包名和位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.bwensun.repository"
targetProject="BLOG_USER_SERVICE/src/main/java">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-->要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名<-->
<table tableName="USER" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>
执行生成代码
/**
* @author bwensun
* @date 2019/12/17
*/
public class MybatisGenerator {
public static void main(String[] args) {
String path = "D:\\ProgramFile\\idea_workspace\\DUBBO_TEST\\BLOG\\BLOG_USER_SERVICE\\src\\main\\resources\\generatorConfig.xml";
args = new String[]{"-configfile", path, "-overwrite"};
ShellRunner.main(args);
}
}