Maven 项目中用了 mybatis 框架, 因此自然的用到了代码生成工具 mybatis-generator-core-1.3.2.jar.
我们一开始的做法是配置好 generatorConfig.xml 文件后, 打开 cmd 命令窗口进入到生成文件所在的子项目目录中, 执行命令: mvn mybatis-generator:generate.
这种生成方式的操作太麻烦了, 除了要打开命令窗口进入生成目录运行命令, 还要提前删除已经生成的的 xml 文件, 如果你的 dao 层 mapper 文件中类继承了父接口, 还要因为被覆盖而需要重新写入继承代码, 总之就是挺麻烦的, 于是花了点时间进行优化.
下面一步步介绍实现过程.
1, 首先是看看我们的项目结构, 我们生成的代码是在 common 子项目中的
image.png
2,pom.xml 文件中引入下面的依赖 (数据库驱动包, 我们是 mysql 数据库, 其他数据库引用对应的依赖就可以了)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
3, 看下图, 我们需要创建两个配置文件, log4j.properties 放在 src/main/java 目录下, generatorConfig.xml 放在 src/main/resources 目录下, 后面附上两个文件代码
image.png
log4j.properties 代码
log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
myGeneratorConfig.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">
<!-- 生成数据库表对应文件说明: 1, 配置生成的表 2, 执行类 GeneratorSqlmapUtil -->
<generatorConfiguration>
<!-- 配置一个代码生成操作, 如果生成的目录或是数据库不一样, 只需要参考增加一个 context 节点即可 -->
<context id="context1">
<!-- 这里的 type 里写的是你的实现类的类全路径, 注: 如果不配置 type 属性, 则会使用默认的 CommentGenerator
实现类 -->
<commentGenerator>
<!-- 去除自动生成的注释 -->
<!-- <property name="suppressAllComments" value="true" />
-->
<!-- 是否生成注释代时间戳 -->
<property name="suppressDate" value="true" />
</commentGenerator>
<!-- 配置数据库, driverClass 请根据所使用的数据库配置 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://xxx.xxx.xxx:3306 / 数据库名称? useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true"
userId="数据库用户名" password="数据库登陆密码">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 配置实体类, example 类生成的路径 -->
<javaModelGenerator targetPackage="com.xxx.xxx.model.common" targetProject="src/main/java"
/>
<!-- 配置 mapper.xml 文件生成的路径 (注: 此处的 targetPackage 只要在 base/mybatis / 后面设置上面类文件包路径中最后一个名称就可以了)
-->
<sqlMapGenerator targetPackage="base/mybatis/common" targetProject="src/main/resources"
/>
<!-- 配置 mapper 接口生成的路径, 此处必须配置在 javaModelGenerator 和 sqlMapGenerator 后面,
不然会报错 并且为生成的接口添加一个父接口, 此处配置的父接口多一个下划线, 以备生成后提示错误以引导手动去完成正确的接口继承 (继承 BaseMapper
并且将泛型类设置为对应的实体类, example 类, 并且删除生成的方法) -->
<javaClientGenerator targetPackage="com.xxx.xxx.dao.common" type="XMLMAPPER"
targetProject="src/main/java">
<!-- <property name="rootInterface" value="com.xxx.xxx.dao.base.BaseMapper_"
/>
-->
</javaClientGenerator>
<!-- 配置生成的表格, 同时生成多张表可以配置多个 < table> 标签 -->
<table schema="database" tableName="common_table1" />
</context>
</generatorConfiguration>
4, 在 src/main/java 目录下任意包创建两个 java 类, 下面分别贴上代码并简单介绍.
(1)GeneratorSqlmap.java 类, 该类主要是读取配置文件, 对目标表已经生成的 xml 文件进行删除, 对 mapper 文件进行备份, 恢复, 调用生成工具执行生成操作, 具体过程请阅读下面的源码.
package com.xxx.xxx.util.generator;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.aspectj.util.FileUtil;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.JavaClientGeneratorConfiguration;
import org.mybatis.generator.config.JavaModelGeneratorConfiguration;
import org.mybatis.generator.config.SqlMapGeneratorConfiguration;
import org.mybatis.generator.config.TableConfiguration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.springframework.util.ResourceUtils;
import com.xxx.xxx.util.StringUtil;
/**
* 根据数据库表生成 model,example,mapper.xml 文件
* @author 北北
* @date 2017 年 12 月 8 日下午 3:30:54
*/
public class GeneratorSqlmap {
/**
* 根据配置的数据库表生成源码
* @author 北北
* @date 2018 年 1 月 17 日上午 11:04:26
* @throws Exception
*/
public void generator() throws Exception {
List < String > warnings = new ArrayList < String > ();
boolean overwrite = true;
// 读取配置文件
File configFile = ResourceUtils.getFile("classpath:myGeneratorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
// 删除需要生成的 xml 文件
this.deleteOldXmlFile(config);
// 对 Mapper 文件备份处理
Map < String,
String > mapperFileValue = this.backupMapperFile(config);
// 生成代码执行
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
// 恢复已经存在的 Mapper 文件
this.recoverMapperFile(mapperFileValue);
}
/**
* 恢复已经存在的 Mapper 文件
* @author 北北
* @date 2018 年 1 月 17 日下午 4:13:22
* @param mapperFileValue
*/
private void recoverMapperFile(Map < String, String > mapperFileValue) {
for (Entry < String, String > fileValue: mapperFileValue.entrySet()) {
String filePath = fileValue.getKey();
String content = fileValue.getValue();
File file = new File(filePath);
FileUtil.writeAsString(file, content);
}
}
/**
* 对已经生成过的 Mapper 文件进行缓存备份
* @author 北北
* @date 2018 年 1 月 17 日下午 4:59:02
* @param config
* @return
*/
private Map < String,
String > backupMapperFile(Configuration config) {
List < Context > contextList = config.getContexts();
Map < String,
String > fileValueMap = new HashMap < >();
for (Context context: contextList) {
JavaClientGeneratorConfiguration mapperConfig = context.getJavaClientGeneratorConfiguration();
String mapperProject = mapperConfig.getTargetProject();
String mapperPackage = mapperConfig.getTargetPackage();
List < TableConfiguration > tableList = context.getTableConfigurations();
for (TableConfiguration table: tableList) {
// 提取文件名
String fileName = table.getDomainObjectName();
if (fileName == null) {
fileName = StringUtil.camelName(table.getTableName());
}
fileName += "Mapper.java";
// 将包中的. 全部替换为 /
mapperPackage = mapperPackage.replaceAll("\\.", "/");
String mapperPath = mapperProject + "/" + mapperPackage + "/" + StringUtil.upperCaseFirst(fileName);
File mapperFile = new File(mapperPath);
// 如果已经存在的 Mapper 文件, 备份
if (mapperFile.exists()) {
String content;
try {
content = FileUtil.readAsString(mapperFile);
fileValueMap.put(mapperPath, content);
System.out.println("备份文件:" + mapperFile);
} catch(IOException e) {
e.printStackTrace();
}
}
}
}
return fileValueMap;
}
/**
* 删除旧的 xml 文件, 避免内容重复
* @author 北北
* @date 2018 年 1 月 17 日下午 3:51:35
* @param config
*/
private void deleteOldXmlFile(Configuration config) {
List < Context > contextList = config.getContexts();
for (Context context: contextList) {
SqlMapGeneratorConfiguration sqlConfig = context.getSqlMapGeneratorConfiguration();
String sqlProject = sqlConfig.getTargetProject();
String sqlPackage = sqlConfig.getTargetPackage();
List < TableConfiguration > tableList = context.getTableConfigurations();
for (TableConfiguration table: tableList) {
// 提取文件名
String fileName = table.getDomainObjectName();
if (fileName == null) {
fileName = StringUtil.camelName(table.getTableName());
}
fileName += "Mapper.xml";
// 根据 xml 文件相对路径创建 file 对象
String xmlPath = sqlProject + "/" + sqlPackage + "/" + StringUtil.upperCaseFirst(fileName);
File xmlFile = new File(xmlPath);
// 如果已经存在的 Xml 文件, 删除
if (xmlFile.exists()) {
xmlFile.delete();
System.out.println("删除文件:" + xmlPath);
}
}
}
}
}
(2)GeneratorSqlmapUtil.java 该类是入口主函数所在, 里面调用了上面类中生成代码的方法.
package com.xxx.xxx.util.generator;
/**
* 生成 sql 映射代码主程序
* @author 北北
* @date 2018 年 1 月 17 日下午 5:34:03
*/
public class GeneratorSqlmapUtil {
/**
* 生成代码入口
* @author 北北
* @date 2018 年 1 月 17 日下午 5:35:49
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
try {
GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
generatorSqlmap.generator();
} catch(Exception e) {
e.printStackTrace();
}
}
}
至此, 只需要在 generatorConfig.xml 文件中配置好了需要生成的表及生成目录, 就可以 run GeneratorSqlmapUtil.java 类来生成表对应的实体类, example 类, mapper 类, xml 文件了.
来源: http://www.jianshu.com/p/d625d0c777bf