MyBatis-Generator 使用
简介
之前我IDEA安装的mybatis-generator一键生成POJO,mapper以及XML文件的插件,但是换了一台电脑发现不行了,必须通过繁琐的配置才能使用懒人工具。
Maven依赖以及配置
pom.xml文件中修改两处:
- 引入依赖
<!-- 添加mybatis.generator依赖 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
- 增加build插件工具
<build>
<plugins>
<!--2、添加mybatis.generator插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<!--配置XML文件地址,以下为根目录,如果是resources,则为:src/main/resources/generatorConfig.xml -->
<!-- <configurationFile>generatorConfig.xml</configurationFile>-->
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<!--允许移动生成的文件 -->
<verbose>true</verbose>
<!--是否覆盖 -->
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
增加generatorConfig配置文件
<?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>
<!--1、指定特定数据库的jdbc驱动jar包的位置千万千万要指定正确,不然就创建不了文件-->
<classPathEntry location="E:\MavenSupports\mysql\mysql-connector-java\8.0.22\mysql-connector-java-8.0.22.jar"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 取消setter/getter方法生成 因为已经采用了lombok了 这里是自己重写的方法,看下面实现 -->
<plugin type="com.personloger.config.IngoreSetterAndGetterPlugin" />
<!-- 配置生成pojo的序列化的插件,mybatis支持很多插件,这些插件都在 org.mybatis.generator.plugins包下 -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<!-- type值为自定义的MyCommentGenerator-->
<commentGenerator type="com.personloger.config.MyCommentGenerator">
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="false"/>
<property name="suppressDate" value="false"/>
<!-- 是否添加数据表中字段的注释 true:是 : false:否 -->
<property name="addRemarkComments" value="true"/>
</commentGenerator>
<!--2、配置数据库连接信息 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/psop?serverTimezone=Asia/Shanghai"
userId="root"
password="123456">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--3、指定Model生成的位置 -->
<javaModelGenerator
targetPackage="com.personloger.system.pojo"
targetProject=".\src\main\java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--4、指定sql映射文件生成的位置 -->
<sqlMapGenerator
targetPackage="mapper"
targetProject=".\src\main\resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--4.1、如果放程序包中-->
<!-- <sqlMapGenerator -->
<!-- targetPackage="com.anson.mapper"-->
<!-- targetProject=".\src\main\java">-->
<!-- <property name="enableSubPackages" value="true"/>-->
<!-- </sqlMapGenerator>-->
<!--5、指定dao接口生成的位置 .mapper接口 -->
<!-- type生成类型含义,项目中基本都是用:XMLMAPPER
type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
targetPackage="" , 是你的mapper接口文件目录
-->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.personloger.system.mapper"
targetProject=".\src\main\java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 6-1、单个表生成策略 -->
<!-- options -->
<!-- <table tableName="options" domainObjectName="Options" enableCountByExample="false" enableUpdateByExample="false"-->
<!-- enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">-->
<!-- <property name="useActualColumnNames" value="true" />-->
<!-- </table>-->
<!-- audiLog -->
<table tableName="audilog" domainObjectName="AudiLog" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
<property name="useActualColumnNames" value="true" />
<!-- 逆向生成无法对longtext进行转义 -->
<columnOverride column="originalData" javaType="java.lang.String" jdbcType="VARCHAR" />
<columnOverride column="destData" javaType="java.lang.String" jdbcType="VARCHAR" />
</table>
<!-- 6-2、整个数据库批量生成策略 -->
<!-- <table tableName="%"-->
<!-- enableCountByExample="false"-->
<!-- enableUpdateByExample="false"-->
<!-- enableDeleteByExample="false"-->
<!-- enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false">-->
<!-- <property name="useActualColumnNames" value="false" />-->
<!-- <!– 数据库表主键 –>-->
<!-- <!– <generatedKey column="id" sqlStatement="Mysql" identity="true" /> –>-->
<!-- </table>-->
</context>
</generatorConfiguration>
注意的步骤已经在注释中写明
重写实现类
- MyCommentGenerator.java
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.mybatis.generator.internal.util.StringUtility;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
public class MyCommentGenerator implements CommentGenerator {
public static void main(String[] args) {
List<String> warnings = new ArrayList<>();
boolean overwrite = true;
// 给出generatorConfig.xml文件的位置,绝对地址或者类路径下
//File configFile = new File("E:\\xxxxxxxxx\\generatorConfig.xml");
File configFile = new File(MyCommentGenerator.class.getClassLoader().getResource("generatorConfig.xml").getFile());
ConfigurationParser cp = new ConfigurationParser(warnings);
try {
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
} catch (Exception e) {
e.printStackTrace();
}
}
private Properties properties;
private boolean suppressDate;
private boolean suppressAllComments;
/**
* If suppressAllComments is true, this option is ignored.
*/
private boolean addRemarkComments;
private SimpleDateFormat dateFormat;
public MyCommentGenerator() {
super();
properties = new Properties();
suppressDate = false;
suppressAllComments = false;
addRemarkComments = false;
}
/**
* 默认配置
*
* @param properties
*/
@Override
public void addConfigurationProperties(Properties properties) {
this.properties.putAll(properties);
suppressDate = isTrue(properties
.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
suppressAllComments = isTrue(properties
.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
addRemarkComments = isTrue(properties
.getProperty(PropertyRegistry.COMMENT_GENERATOR_ADD_REMARK_COMMENTS));
String dateFormatString = properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_DATE_FORMAT);
if (StringUtility.stringHasValue(dateFormatString)) {
dateFormat = new SimpleDateFormat(dateFormatString);
}
}
/**
* 实体类添加的注释
*
* @param topLevelClass
* @param introspectedTable
*/
@Override
public void addModelClassComment(TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
}
/**
* 实体类的属性注释,数据库中自定义注释
*
* @param field
* @param introspectedTable
* @param introspectedColumn
*/
@Override
public void addFieldComment(Field field,
IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn) {
if (suppressAllComments) {
return;
}
field.addJavaDocLine("/**"); //$NON-NLS-1$
String remarks = introspectedColumn.getRemarks();
if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator")); //$NON-NLS-1$
for (String remarkLine : remarkLines) {
field.addJavaDocLine(" * " + remarkLine); //$NON-NLS-1$
}
}
field.addJavaDocLine(" */"); //$NON-NLS-1$
}
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
if (suppressAllComments) {
return;
}
StringBuilder sb = new StringBuilder();
field.addJavaDocLine("/**"); //$NON-NLS-1$
sb.append(introspectedTable.getFullyQualifiedTable());
field.addJavaDocLine(" */"); //$NON-NLS-1$
}
@Override
public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
}
@Override
public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
}
@Override
public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
}
@Override
public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
}
// 不需要get方法的注释
@Override
public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
}
// 不需要set方法的注释
@Override
public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
}
@Override
public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> imports) {
}
@Override
public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {
}
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> imports) {
}
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {
}
@Override
public void addClassAnnotation(InnerClass innerClass, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> imports) {
}
@Override
public void addComment(XmlElement xmlElement) {
}
@Override
public void addRootComment(XmlElement rootElement) {
}
@Override
public void addJavaFileComment(CompilationUnit compilationUnit) {
}
}
- IngoreSetterAndGetterPlugin.java
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;
public class IngoreSetterAndGetterPlugin extends PluginAdapter {
@Override
public boolean validate(List<String> list) {
return true;
}
@Override
public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
//添加domain的import
topLevelClass.addImportedType("lombok.Data");
topLevelClass.addImportedType("lombok.NoArgsConstructor");
topLevelClass.addImportedType("lombok.AllArgsConstructor");
topLevelClass.addJavaDocLine("/**"); //$NON-NLS-1$
topLevelClass.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable().toString() + " 模板类"); //$NON-NLS-1$
topLevelClass.addJavaDocLine(" * @author " + System.getProperty("user.name"));
topLevelClass.addJavaDocLine(" * @since " + formatDateToStr(new Date()));
topLevelClass.addJavaDocLine(" */"); //$NON-NLS-1$
topLevelClass.addAnnotation("@Data"); //$NON-NLS-1$
topLevelClass.addAnnotation("@NoArgsConstructor");
topLevelClass.addAnnotation("@AllArgsConstructor");
return true;
}
@Override
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
//Mapper文件的注释
interfaze.addJavaDocLine("/**"); //$NON-NLS-1$
interfaze.addJavaDocLine(" * " + introspectedTable.getFullyQualifiedTable().toString() + " Mapper 接口"); //$NON-NLS-1$
interfaze.addJavaDocLine(" * @author " + System.getProperty("user.name"));
interfaze.addJavaDocLine(" * @since " + formatDateToStr(new Date()));
interfaze.addJavaDocLine(" */"); //$NON-NLS-1$
interfaze.addAnnotation("@Mapper");
return true;
}
@Override
public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
//不生成getter
return false;
}
@Override
public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
//不生成setter
return false;
}
private String formatDateToStr(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
}
启动测试
- 直接通过maven 启动build插件
- 通过Main方法启动
注意事项
- 建议另起工程专门用来生成文件,避免覆盖导致构造方法以及SQL语句的丢失
- 可能存在一些无法对应的字段类型,会出现POJO类将那个字段类型生成xxxWithBOM这样的类出现,可以自行百度在以下位置配置
目前我只发现一个longtext无法映射成String类型,肯定还有其他类型
结尾
懒人工具有很多,我只是习惯用这个了,还有很多类似MyBatisX,MyBatis Plus等,因为自定义的SQL语句比较多,还是比较习惯用这个一键生成增删改查SQL语句。