在网上查看的各种逆向工程的文章, 发现基本上都是用xml配置的方式实现的, 现在基本上项目都是使用java类方式实现xml配置, 所以整理下 纯java注解的实现方式, 一定要注意 java 代码的实现方式都是基于xml 所以本文开头先把xml注解添加进来比较,
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"/>
<!-- 数据库驱动位置 -->
<classPathEntry location="${classPath}" />
<!-- 一个数据库一个context, targetRuntime:此属性用于指定生成的代码的运行时环境 ,MyBatis3:*这是默认值*,MyBatis3Simple不生成Example查询(避免后面一个一个表设置) defaultModelType:如何生成实体类,flat表示为每一张表生成一个实体类,推荐使用-->
<context id="mysqlTables" targetRuntime="com.practice.mybatis.TkMyBatis3Impl" defaultModelType="flat">
<!-- 注释 type表示自定义注释-->
<commentGenerator type="com.practice.mybatis.MyCommentGenerator">
<!-- 生成文件的编码 (eclipse插件的时候这里并没有什么卵用,需要在eclipse根目录的eclipse.ini最后添加 -Dfile.encoding=UTF-8 )-->
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 是否取消注释 -->
<property name="suppressAllComments" value="false" />
<property name="addRemarkComments" value="true"/>
<!-- 是否生成注释代时间戳 -->
<property name="suppressDate" value="true" />
<!-- 当表名或者字段名为SQL关键字的时候,可以设置该属性为true,MBG会自动给表名或字段名添加**分隔符** -->
<property name="autoDelimitKeywords" value="true"></property>
<!-- 由于beginningDelimiter和endingDelimiter的默认值为双引号("),在Mysql中不能这么写,所以还要将这两个默认值改为**反单引号(`)** -->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
</commentGenerator>
<!-- 数据库的url、用户名、密码 -->
<jdbcConnection driverClass="${jdbc.driver}"
connectionURL="${jdbc.url}"
userId="${jdbc.user}"
password="${jdbc.password}">
</jdbcConnection>
<!-- 类型转换 -->
<javaTypeResolver >
<!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 生成模型的包名和位置 -->
<javaModelGenerator targetPackage="${package_domain}" targetProject="${project}">
<!-- 是否在当前路径下新加一层schema,eg:fase路径com.goshop.domain", true:com.goshop.domain".[schemaName] -->
<property name="enableSubPackages" value="false" />
<!-- 是否针对string类型的字段在set的时候进行trim调用 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成的映射文件包名和位置 -->
<sqlMapGenerator targetPackage="${package_mapper}" targetProject="${resource}">
<!-- 是否在当前路径下新加一层schema,eg:fase路径com.goshop.domain", true:com.goshop.domain".[schemaName] -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 生成DAO的包名和位置 type 1、ANNOTATEDMAPPER注解形式 2、XMLMAPPER xml配置文件形式-->
<javaClientGenerator type="XMLMAPPER" targetPackage="${package_dao}" targetProject="${project}">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 生成那些表 tableName表名 mapperName 生成dao的名称,domainObjectName应于数据库表的javaBean类名,enable*ByExample是否生成 example类 -->
<!-- <table tableName="sys_user" domainObjectName="SysUser" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/> -->
<!-- 忽略列,不生成bean 字段
<ignoreColumn column="FRED" />-->
<!-- 指定列的java数据类型
<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />-->
<table tableName="%" mapperName="{0}DAO">
<columnOverride column="remarks" jdbcType="VARCHAR" />
</table>
</context>
</generatorConfiguration>
前期准备
首先pom添加依赖和插件
<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>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
mybatis-generator-core
MyBatisGenerator
Mybatis 生成器主要接口, 使用的时候只需要创建类实例, 调用generate() 方法即可, 类中内置了大量属性
/** 自定义配置类 */
private Configuration configuration;
/** 回调. */
private ShellCallback shellCallback;
/**生成java文件. */
private List<GeneratedJavaFile> generatedJavaFiles;
/** 生成xml文件 */
private List<GeneratedXmlFile> generatedXmlFiles;
/** 警号信息. */
private List<String> warnings;
/** 项目信息. */
private Set<String> projects;
/**
* Constructs a MyBatisGenerator object.
*
* @param configuration
* The configuration for this invocation
* @param shellCallback
* an instance of a ShellCallback interface. You may specify
* <code>null</code> in which case the DefaultShellCallback will
* be used.
* @param warnings
* Any warnings generated during execution will be added to this
* list. Warnings do not affect the running of the tool, but they
* may affect the results. A typical warning is an unsupported
* data type. In that case, the column will be ignored and
* generation will continue. You may specify <code>null</code> if
* you do not want warnings returned.
* @throws InvalidConfigurationException
* if the specified configuration is invalid
*/
public MyBatisGenerator(Configuration configuration, ShellCallback shellCallback,
List<String> warnings) throws InvalidConfigurationException {
super();
if (configuration == null) {
throw new IllegalArgumentException(getString("RuntimeError.2")); //$NON-NLS-1$
} else {
this.configuration = configuration;
}
if (shellCallback == null) {
this.shellCallback = new DefaultShellCallback(false);
} else {
this.shellCallback = shellCallback;
}
if (warnings == null) {
this.warnings = new ArrayList<String>();
} else {
this.warnings = warnings;
}
generatedJavaFiles = new ArrayList<GeneratedJavaFile>();
generatedXmlFiles = new ArrayList<GeneratedXmlFile>();
projects = new HashSet<String>();
this.configuration.validate();
}
构造器方法只提供了一个构造, 传入三个参数的构造. 所以本文只关注这三个属性
Configuration
/** The contexts. */
private List<Context> contexts;
/** The class path entries. */
private List<String> classPathEntries;
Context
提供了大量的配置类, 包括JDBC连接配置类, Sql映射配置类, Java模型生成配置类等, 具体要如何配置要自己参考源码, 本文主要提供一种基础生成方式.
/**
* The Class Context.
* * @author Jeff Butler
*/
public class Context extends PropertyHolder {
/** The id. */
private String id;
/** The jdbc connection configuration. */
private JDBCConnectionConfiguration jdbcConnectionConfiguration;
private ConnectionFactoryConfiguration connectionFactoryConfiguration;
/** The sql map generator configuration. */
private SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration;
/** The java type resolver configuration. */
private JavaTypeResolverConfiguration javaTypeResolverConfiguration;
/** The java model generator configuration. */
private JavaModelGeneratorConfiguration javaModelGeneratorConfiguration;
/** The java client generator configuration. */
private JavaClientGeneratorConfiguration javaClientGeneratorConfiguration;
/** The table configurations. */
private ArrayList<TableConfiguration> tableConfigurations;
/** The default model type. */
private ModelType defaultModelType;
/** The beginning delimiter. */
private String beginningDelimiter = "\""; //$NON-NLS-1$
/** The ending delimiter. */
private String endingDelimiter = "\""; //$NON-NLS-1$
/** The comment generator configuration. */
private CommentGeneratorConfiguration commentGeneratorConfiguration;
/** The comment generator. */
private CommentGenerator commentGenerator;
/** The plugin aggregator. */
private PluginAggregator pluginAggregator;
/** The plugin configurations. */
private List<PluginConfiguration> pluginConfigurations;
/** The target runtime. */
private String targetRuntime;
/** The introspected column impl. */
private String introspectedColumnImpl;
/** The auto delimit keywords. */
private Boolean autoDelimitKeywords;
/** The java formatter. */
private JavaFormatter javaFormatter;
/** The xml formatter. */
private XmlFormatter xmlFormatter;
...(省略)
defaultModelType: 规定了实体生成的策略, 每一种对应了一种规则
- hierarchical: 有主键, 生成单独主键实体类, 有blob, text类型, 生成一个包含所有BLOB, text字段的单独的实体类, 其他属性生成一个实体(HierarchicalModelRules)
- conditional (默认值): 与hierarchical基本相同, 不同之处是当 表只有一个属性, 则只生成一个基本实体类(就算这个字段是主键, 也不生成主键实体类)(ConditionalModelRules)
- flat: 每一张表只生成一个实体类。这个实体类包含表中的所有字段(FlatModelRules)
测试实现
package com.huntkey.rx.sceo.generator;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.*;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.util.ArrayList;
import java.util.List;
/**
* @description: mybatis 逆向工程测试
* @author: wangml
* @date: 2021/7/24 09:31
*/
public class MybatisGeneratorTest {
public static final String PROJECT_SOURCES_ROOT_DIR = "D:\\workspace\\HuntKey\\springbootDemo\\src\\main\\java";
public static final String PROJECT_RESOURCES_ROOT_DIR = "D:\\workspace\\HuntKey\\springbootDemo\\src\\main\\resources";
public static void main(String[] args) throws Exception {
// 警告信息
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
Configuration config = new Configuration();
// Mybatis实体生成策略(CONDITIONAL)
Context context = new Context(ModelType.CONDITIONAL);
context.setId("myTest");
//是否将数据库的表和列的备注生成到实体中
CommentGeneratorConfiguration commentGeneratorConfiguration = new CommentGeneratorConfiguration();
// addRemarkComments 为 CommentGenerator存在的属性, 只是在java类中没有申明, 要自己去按需开启(不能定义不存在的属性)
commentGeneratorConfiguration.addProperty("addRemarkComments", "true");
context.setCommentGeneratorConfiguration(commentGeneratorConfiguration);
//配置数据库连接
JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
jdbcConnectionConfiguration.setDriverClass("com.mysql.cj.jdbc.Driver");
jdbcConnectionConfiguration.setConnectionURL("jdbc:mysql://localhost:3306/sceo?useSSL=true");
jdbcConnectionConfiguration.setUserId("root");
jdbcConnectionConfiguration.setPassword("root");
context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
//配置实体类生成策略
JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
// 指定实体继承的父类(父类的属性在表中要存在)
// javaModelGeneratorConfiguration.addProperty("rootClass", "com.huntkey.rx.sceo.core.repository.entity.ResourceEntity");
//指定实体类所属的包名
javaModelGeneratorConfiguration.setTargetPackage("com.huntkey.rx.sceo.entity");
//指定工程的src目录
javaModelGeneratorConfiguration.setTargetProject(PROJECT_SOURCES_ROOT_DIR);
context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
//配置Sql文件的生成策略
SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
sqlMapGeneratorConfiguration.setTargetPackage("mapper");
sqlMapGeneratorConfiguration.setTargetProject(PROJECT_RESOURCES_ROOT_DIR);
context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
//配置DAO接口的生成策略
JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
//接口实现方式:XMLMAPPER、MIXEDMAPPER、ANNOTATEDMAPPER
javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
// javaClientGeneratorConfiguration.addProperty("rootInterface", "com.huntkey.rx.sceo.core.repository.dao.Mapper");
javaClientGeneratorConfiguration.setTargetPackage("com.huntkey.rx.sceo.dao");
javaClientGeneratorConfiguration.setTargetProject(PROJECT_SOURCES_ROOT_DIR);
context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
//生成实体的其他规则配置
TableConfiguration tableConfiguration = new TableConfiguration(context);
tableConfiguration.setDomainObjectName("User");
//是否直接使用数据库列名作为属性名,false时会转驼峰
tableConfiguration.setTableName("user_test");
context.addTableConfiguration(tableConfiguration);
config.addContext(context);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
System.out.println("success");
}
}
运行main 就可在对应目录下得到生成的 java 文件
总结
- xml注解的实现方法 和 java 配置的方法 都可以实现功能(xml的方式有很多博客)
- 理解底层实现 才能方便我们驾驭代码, 使用时游刃有余
参考文章:
https://www.cnblogs.com/liaojie970/p/8029000.html
https://blog.csdn.net/wl_627292578/article/details/54895587