MyBatis Generator(MBG)是MyBatis MyBatis 和 iBATIS的代码生成器。它将为所有版本的MyBatis以及版本2.2.0之后的iBATIS版本生成代码。它将内省数据库表(或许多表),并将生成可用于访问表的工件。这减少了设置对象和配置文件以与数据库表交互的初始麻烦。MBG寻求对简单CRUD(创建,检索,更新,删除)的大部分数据库操作产生重大影响。您仍然需要为连接查询或存储过程手动编写SQL和对象代码。
创建 maven 项目
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<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>com.fjx.coder</groupId>
<artifactId>coder</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.31</version>
</dependency>
</dependencies>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>${project.build.directory}</outputDirectory>
<verbose>true</verbose>
<tableNames>%</tableNames>
</configuration>
</plugin>
</plugins>
</build>
</project>
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>
<context id="MysqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!-- 指定生成的java文件的编码,没有直接生成到项目时中文可能会乱码 -->
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 生成的pojo,将implements Serializable -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
<!-- 这里的type里写的是你的实现类的类全路径 -->
<!--<commentGenerator type="com.MyCommentGenerator">-->
<!--<property name="suppressDate" value="true"/>-->
<!--</commentGenerator>-->
<commentGenerator>
<property name="suppressDate" value="true"/>
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://192.168.183.137/prize?tinyInt1isBit=false"
userId="root"
password="root">
</jdbcConnection>
<!-- <javaTypeResolver type="com.JavaTypeResolverDefaultImpl">-->
<!-- </javaTypeResolver>-->
<!-- entity 包路径 -->
<javaModelGenerator targetPackage="com.fjx.db.entity" targetProject="MAVEN">
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- xml 路径-->
<sqlMapGenerator targetPackage="com.fjx.db.xml.mapper" targetProject="MAVEN"/>
<!-- dao路径 -->
<!--<javaClientGenerator type="XMLMAPPER" targetPackage="com.fjx.dao1" targetProject="MAVEN"/>-->
<!--<javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="com.fjx.dao2" targetProject="MAVEN"/>-->
<javaClientGenerator type="MIXEDMAPPER" targetPackage="com.fjx.db.mapper" targetProject="MAVEN"/>
<table tableName="%">
<generatedKey column="id" sqlStatement="Mysql" identity="true"/>
</table>
</context>
</generatorConfiguration>
配置文件详解
生成代码
打开项目目录
我们打开一个实体类发现字段类型与数据库中的不一致
此时我们需要通过 JavaTypeResolverDefaultImpl 类去声明一下,默认将 tinyint 类型的字段转化为integer。
JavaTypeResolverDefaultImpl
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.internal.util.StringUtility;
import java.math.BigDecimal;
import java.util.*;
public class JavaTypeResolverDefaultImpl implements JavaTypeResolver {
protected List<String> warnings;
protected Properties properties = new Properties();
protected Context context;
protected boolean forceBigDecimals;
protected boolean useJSR310Types;
protected Map<Integer, JdbcTypeInformation> typeMap = new HashMap();
private static final int TIME_WITH_TIMEZONE = 2013;
private static final int TIMESTAMP_WITH_TIMEZONE = 2014;
public JavaTypeResolverDefaultImpl() {
this.typeMap.put(2003, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("ARRAY", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(-5, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("BIGINT", new FullyQualifiedJavaType(Long.class.getName())));
this.typeMap.put(-2, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("BINARY", new FullyQualifiedJavaType("byte[]")));
this.typeMap.put(-7, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("BIT", new FullyQualifiedJavaType(Boolean.class.getName())));
this.typeMap.put(2004, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("BLOB", new FullyQualifiedJavaType("byte[]")));
this.typeMap.put(16, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("BOOLEAN", new FullyQualifiedJavaType(Boolean.class.getName())));
this.typeMap.put(1, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("CHAR", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(2005, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("CLOB", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(70, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("DATALINK", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(91, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("DATE", new FullyQualifiedJavaType(Date.class.getName())));
this.typeMap.put(3, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("DECIMAL", new FullyQualifiedJavaType(BigDecimal.class.getName())));
this.typeMap.put(2001, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("DISTINCT", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(8, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("DOUBLE", new FullyQualifiedJavaType(Double.class.getName())));
this.typeMap.put(6, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("FLOAT", new FullyQualifiedJavaType(Double.class.getName())));
this.typeMap.put(4, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("INTEGER", new FullyQualifiedJavaType(Integer.class.getName())));
this.typeMap.put(2000, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("JAVA_OBJECT", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(-16, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("LONGNVARCHAR", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(-4, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("LONGVARBINARY", new FullyQualifiedJavaType("byte[]")));
this.typeMap.put(-1, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("LONGVARCHAR", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(-15, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("NCHAR", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(2011, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("NCLOB", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(-9, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("NVARCHAR", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(0, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("NULL", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(2, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("NUMERIC", new FullyQualifiedJavaType(BigDecimal.class.getName())));
this.typeMap.put(1111, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("OTHER", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(7, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("REAL", new FullyQualifiedJavaType(Float.class.getName())));
this.typeMap.put(2006, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("REF", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(5, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("SMALLINT", new FullyQualifiedJavaType(Integer.class.getName())));
this.typeMap.put(2002, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("STRUCT", new FullyQualifiedJavaType(Object.class.getName())));
this.typeMap.put(92, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TIME", new FullyQualifiedJavaType(Date.class.getName())));
this.typeMap.put(93, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TIMESTAMP", new FullyQualifiedJavaType(Date.class.getName())));
this.typeMap.put(-6, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TINYINT", new FullyQualifiedJavaType(Integer.class.getName())));
this.typeMap.put(-3, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("VARBINARY", new FullyQualifiedJavaType("byte[]")));
this.typeMap.put(12, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("VARCHAR", new FullyQualifiedJavaType(String.class.getName())));
this.typeMap.put(2013, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TIME_WITH_TIMEZONE", new FullyQualifiedJavaType("java.time.OffsetTime")));
this.typeMap.put(2014, new JavaTypeResolverDefaultImpl.JdbcTypeInformation("TIMESTAMP_WITH_TIMEZONE", new FullyQualifiedJavaType("java.time.OffsetDateTime")));
}
public void addConfigurationProperties(Properties properties) {
this.properties.putAll(properties);
this.forceBigDecimals = StringUtility.isTrue(properties.getProperty("forceBigDecimals"));
this.useJSR310Types = StringUtility.isTrue(properties.getProperty("useJSR310Types"));
}
public FullyQualifiedJavaType calculateJavaType(IntrospectedColumn introspectedColumn) {
FullyQualifiedJavaType answer = null;
JavaTypeResolverDefaultImpl.JdbcTypeInformation jdbcTypeInformation = (JavaTypeResolverDefaultImpl.JdbcTypeInformation)this.typeMap.get(introspectedColumn.getJdbcType());
if (jdbcTypeInformation != null) {
answer = jdbcTypeInformation.getFullyQualifiedJavaType();
answer = this.overrideDefaultType(introspectedColumn, answer);
}
return answer;
}
protected FullyQualifiedJavaType overrideDefaultType(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
FullyQualifiedJavaType answer = defaultType;
switch(column.getJdbcType()) {
case -7:
answer = this.calculateBitReplacement(column, defaultType);
break;
case 2:
case 3:
answer = this.calculateBigDecimalReplacement(column, defaultType);
break;
case 91:
answer = this.calculateDateType(column, defaultType);
break;
case 92:
answer = this.calculateTimeType(column, defaultType);
break;
case 93:
answer = this.calculateTimestampType(column, defaultType);
}
return answer;
}
protected FullyQualifiedJavaType calculateDateType(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
FullyQualifiedJavaType answer;
if (this.useJSR310Types) {
answer = new FullyQualifiedJavaType("java.time.LocalDate");
} else {
answer = defaultType;
}
return answer;
}
protected FullyQualifiedJavaType calculateTimeType(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
FullyQualifiedJavaType answer;
if (this.useJSR310Types) {
answer = new FullyQualifiedJavaType("java.time.LocalTime");
} else {
answer = defaultType;
}
return answer;
}
protected FullyQualifiedJavaType calculateTimestampType(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
FullyQualifiedJavaType answer;
if (this.useJSR310Types) {
answer = new FullyQualifiedJavaType("java.time.LocalDateTime");
} else {
answer = defaultType;
}
return answer;
}
protected FullyQualifiedJavaType calculateBitReplacement(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
FullyQualifiedJavaType answer;
if (column.getLength() > 1) {
answer = new FullyQualifiedJavaType("byte[]");
} else {
answer = defaultType;
}
return answer;
}
protected FullyQualifiedJavaType calculateBigDecimalReplacement(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
FullyQualifiedJavaType answer;
if (column.getScale() <= 0 && column.getLength() <= 18 && !this.forceBigDecimals) {
if (column.getLength() > 9) {
answer = new FullyQualifiedJavaType(Long.class.getName());
} else if (column.getLength() > 4) {
answer = new FullyQualifiedJavaType(Integer.class.getName());
} else {
answer = new FullyQualifiedJavaType(Short.class.getName());
}
} else {
answer = defaultType;
}
return answer;
}
public String calculateJdbcTypeName(IntrospectedColumn introspectedColumn) {
String answer = null;
JavaTypeResolverDefaultImpl.JdbcTypeInformation jdbcTypeInformation = (JavaTypeResolverDefaultImpl.JdbcTypeInformation)this.typeMap.get(introspectedColumn.getJdbcType());
if (jdbcTypeInformation != null) {
answer = jdbcTypeInformation.getJdbcTypeName();
}
return answer;
}
public void setWarnings(List<String> warnings) {
this.warnings = warnings;
}
public void setContext(Context context) {
this.context = context;
}
public static class JdbcTypeInformation {
private String jdbcTypeName;
private FullyQualifiedJavaType fullyQualifiedJavaType;
public JdbcTypeInformation(String jdbcTypeName, FullyQualifiedJavaType fullyQualifiedJavaType) {
this.jdbcTypeName = jdbcTypeName;
this.fullyQualifiedJavaType = fullyQualifiedJavaType;
}
public String getJdbcTypeName() {
return this.jdbcTypeName;
}
public FullyQualifiedJavaType getFullyQualifiedJavaType() {
return this.fullyQualifiedJavaType;
}
}
}
此时需要在配置文件中通过javaTypeResolver 标签指定
pom文件指定 JavaTypeResolverDefaultImpl 所在的模块的依赖
重新生成代码
MyCommentGenerator
package com;
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.JavaElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.MergeConstants;
import org.mybatis.generator.internal.DefaultCommentGenerator;
/**
* mybatis generator 自定义comment生成器.
* 基于MBG 1.3.2.
*
*/
public class MyCommentGenerator extends DefaultCommentGenerator {
public MyCommentGenerator() {
super();
}
public void addJavaFileComment(CompilationUnit compilationUnit) {
// add no file level comments by default
return;
}
/**
* Adds a suitable comment to warn users that the element was generated, and
* when it was generated.
*/
public void addComment(XmlElement xmlElement) {
return;
}
public void addRootComment(XmlElement rootElement) {
// add no document level comments by default
return;
}
/**
* This method adds the custom javadoc tag for. You may do nothing if you do
* not wish to include the Javadoc tag - however, if you do not include the
* Javadoc tag then the Java merge capability of the eclipse plugin will
* break.
*
* @param javaElement the java element
*/
protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
javaElement.addJavaDocLine(" *");
StringBuilder sb = new StringBuilder();
sb.append(" * ");
sb.append(MergeConstants.NEW_ELEMENT_TAG);
if (markAsDoNotDelete) {
sb.append(" do_not_delete_during_merge");
}
String s = getDateString();
if (s != null) {
sb.append(' ');
sb.append(s);
}
javaElement.addJavaDocLine(sb.toString());
}
public void addFieldComment(Field field, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn) {
StringBuilder sb = new StringBuilder();
field.addJavaDocLine("/**");
sb.append(" * ");
sb.append(introspectedColumn.getRemarks());
field.addJavaDocLine(sb.toString());
// addJavadocTag(field, false);
field.addJavaDocLine(" */");
}
public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
StringBuilder sb = new StringBuilder();
field.addJavaDocLine("/**");
sb.append(" * ");
sb.append(introspectedTable.getFullyQualifiedTable());
field.addJavaDocLine(sb.toString());
field.addJavaDocLine(" */");
}
}