Maven項(xiàng)目中用了mybatis框架乾巧,因此自然的用到了代碼生成工具mybatis-generator-core-1.3.2.jar。
我們一開(kāi)始的做法是配置好generatorConfig.xml文件后预愤,打開(kāi)cmd命令窗口進(jìn)入到生成文件所在的子項(xiàng)目目錄中沟于,執(zhí)行命令: mvn mybatis-generator:generate。
這種生成方式的操作太麻煩了植康,除了要打開(kāi)命令窗口進(jìn)入生成目錄運(yùn)行命令旷太,還要提前刪除已經(jīng)生成的的xml文件,如果你的dao層mapper文件中類繼承了父接口,還要因?yàn)楸桓采w而需要重新寫入繼承代碼供璧,總之就是挺麻煩的存崖,于是花了點(diǎn)時(shí)間進(jìn)行優(yōu)化。
下面一步步介紹實(shí)現(xiàn)過(guò)程睡毒。
1来惧、首先是看看我們的項(xiàng)目結(jié)構(gòu),我們生成的代碼是在common子項(xiàng)目中的
2演顾、pom.xml文件中引入下面的依賴(數(shù)據(jù)庫(kù)驅(qū)動(dòng)包供搀,我們是mysql數(shù)據(jù)庫(kù),其他數(shù)據(jù)庫(kù)引用對(duì)應(yīng)的依賴就可以了)
<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钠至、看下圖葛虐,我們需要?jiǎng)?chuàng)建兩個(gè)配置文件,log4j.properties放在src/main/java目錄下棉钧,generatorConfig.xml放在src/main/resources目錄下屿脐,后面附上兩個(gè)文件代碼
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 代碼,要特別注意其中的注釋說(shuō)明
<?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" >
<!--
生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)文件說(shuō)明:
1掰盘、配置生成的表
2摄悯、執(zhí)行類 GeneratorSqlmapUtil
-->
<generatorConfiguration>
<!-- 配置一個(gè)代碼生成操作,如果生成的目錄或是數(shù)據(jù)庫(kù)不一樣愧捕,只需要參考增加一個(gè)context節(jié)點(diǎn)即可 -->
<context id="context1">
<!-- 這里的type里寫的是你的實(shí)現(xiàn)類的類全路徑,注:如果不配置type屬性,則會(huì)使用默認(rèn)的CommentGenerator實(shí)現(xiàn)類 -->
<commentGenerator>
<!-- 去除自動(dòng)生成的注釋 -->
<!-- <property name="suppressAllComments" value="true" /> -->
<!-- 是否生成注釋代時(shí)間戳-->
<property name="suppressDate" value="true"/>
</commentGenerator>
<!-- 配置數(shù)據(jù)庫(kù)奢驯,driverClass請(qǐng)根據(jù)所使用的數(shù)據(jù)庫(kù)配置 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://xxx.xxx.xxx:3306/數(shù)據(jù)庫(kù)名稱?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true"
userId="數(shù)據(jù)庫(kù)用戶名"
password="數(shù)據(jù)庫(kù)登陸密碼">
</jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 配置實(shí)體類、example類生成的路徑 -->
<javaModelGenerator targetPackage="com.xxx.xxx.model.common" targetProject="src/main/java" />
<!-- 配置mapper.xml文件生成的路徑(注:此處的targetPackage只要在base/mybatis/后面設(shè)置上面類文件包路徑中最后一個(gè)名稱就可以了) -->
<sqlMapGenerator targetPackage="base/mybatis/common" targetProject="src/main/resources" />
<!--
配置mapper接口生成的路徑, 此處必須配置在javaModelGenerator和sqlMapGenerator后面,不然會(huì)報(bào)錯(cuò)
并且為生成的接口添加一個(gè)父接口,此處配置的父接口多一個(gè)下劃線,
以備生成后提示錯(cuò)誤以引導(dǎo)手動(dòng)去完成正確的接口繼承(繼承BaseMapper并且將泛型類設(shè)置為對(duì)應(yīng)的實(shí)體類次绘、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>
<!-- 配置生成的表格, 同時(shí)生成多張表可以配置多個(gè)<table>標(biāo)簽 -->
<table schema="database" tableName="common_table1" />
</context>
</generatorConfiguration>
4瘪阁、在src/main/java目錄下任意包創(chuàng)建兩個(gè)java類,下面分別貼上代碼并簡(jiǎn)單介紹邮偎。
(1)GeneratorSqlmap.java類管跺,該類主要是讀取配置文件,對(duì)目標(biāo)表已經(jīng)生成的xml文件進(jìn)行刪除禾进,對(duì)mapper文件進(jìn)行備份豁跑、恢復(fù),調(diào)用生成工具執(zhí)行生成操作泻云,具體過(guò)程請(qǐng)閱讀下面的源碼艇拍。
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;
/**
* 根據(jù)數(shù)據(jù)庫(kù)表生成model、example宠纯、mapper.xml文件
* @author 北北
* @date 2017年12月8日下午3:30:54
*/
public class GeneratorSqlmap {
/**
* 根據(jù)配置的數(shù)據(jù)庫(kù)表生成源碼
* @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);
//對(duì)Mapper文件備份處理
Map<String, String> mapperFileValue = this.backupMapperFile(config);
//生成代碼執(zhí)行
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
//恢復(fù)已經(jīng)存在的Mapper文件
this.recoverMapperFile(mapperFileValue);
}
/**
*恢復(fù)已經(jīng)存在的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);
}
}
/**
* 對(duì)已經(jīng)生成過(guò)的Mapper文件進(jìn)行緩存?zhèn)浞? * @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);
//如果已經(jīng)存在的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文件, 避免內(nèi)容重復(fù)
* @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";
//根據(jù)xml文件相對(duì)路徑創(chuàng)建file對(duì)象
String xmlPath = sqlProject + "/" + sqlPackage + "/" + StringUtil.upperCaseFirst(fileName);
File xmlFile = new File(xmlPath);
//如果已經(jīng)存在的Xml文件, 刪除
if(xmlFile.exists()){
xmlFile.delete();
System.out.println("刪除文件:" + xmlPath);
}
}
}
}
}
(2)GeneratorSqlmapUtil.java 該類是入口主函數(shù)所在卸夕,里面調(diào)用了上面類中生成代碼的方法。
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類來(lái)生成表對(duì)應(yīng)的實(shí)體類贡羔、example類、mapper類个初、xml文件了乖寒。
注:
1、如果要提取數(shù)據(jù)庫(kù)字段的注釋作為生成實(shí)體類的注釋院溺,請(qǐng)參考文章:
Mybatis-generator自動(dòng)生成代碼時(shí)候提取數(shù)據(jù)庫(kù)的字段注釋作為實(shí)體類字段宵统、getter/setter方法的注釋
2、如果用的是intellij編輯器覆获,會(huì)有一個(gè)生成路徑的問(wèn)題,具體描述及解決方法請(qǐng)參考文章:
Mybatis-generator自動(dòng)生成代碼工具嵌入maven項(xiàng)目中瓢省,在eclipse和intellij中獲取的路徑不一樣問(wèn)題