Mybatis-generator自動(dòng)生成代碼工具嵌入Maven項(xiàng)目中,實(shí)現(xiàn)一鍵生成數(shù)據(jù)庫(kù)表對(duì)應(yīng)的java弹谁、xml文件

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)目中的


image.png

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è)文件代碼

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 代碼,要特別注意其中的注釋說(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&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;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)題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弄息,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子勤婚,更是在濱河造成了極大的恐慌摹量,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馒胆,死亡現(xiàn)場(chǎng)離奇詭異缨称,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)祝迂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門睦尽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人型雳,你說(shuō)我怎么就攤上這事当凡。” “怎么了纠俭?”我有些...
    開(kāi)封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵沿量,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我冤荆,道長(zhǎng)朴则,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任钓简,我火速辦了婚禮乌妒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涌庭。我一直安慰自己芥被,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布坐榆。 她就那樣靜靜地躺著拴魄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匹中,一...
    開(kāi)封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天夏漱,我揣著相機(jī)與錄音,去河邊找鬼顶捷。 笑死挂绰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的服赎。 我是一名探鬼主播葵蒂,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼重虑!你這毒婦竟也來(lái)了践付?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缺厉,失蹤者是張志新(化名)和其女友劉穎永高,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體提针,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡命爬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辐脖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饲宛。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嗜价,靈堂內(nèi)的尸體忽然破棺而出落萎,到底是詐尸還是另有隱情,我是刑警寧澤炭剪,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布练链,位于F島的核電站,受9級(jí)特大地震影響奴拦,放射性物質(zhì)發(fā)生泄漏媒鼓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一错妖、第九天 我趴在偏房一處隱蔽的房頂上張望绿鸣。 院中可真熱鬧,春花似錦暂氯、人聲如沸潮模。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)擎厢。三九已至究流,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間动遭,已是汗流浹背芬探。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厘惦,地道東北人偷仿。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宵蕉,于是被迫代替她去往敵國(guó)和親酝静。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis 羡玛? MyBatis 是支持定制化 SQL形入、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,532評(píng)論 0 4
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)缝左,斷路器,智...
    卡卡羅2017閱讀 134,715評(píng)論 18 139
  • 文|四月默 梁山伯是憨厚老實(shí)、知世故而不世故挪钓,祝家九妹一顆心都撲在他身上是越。 月老廟躲雨的那場(chǎng)邂逅,月老就為二人拉了...
    四月默閱讀 7,437評(píng)論 119 158
  • 我想要一座房子碌上,面朝大海倚评,春暖花開(kāi)。但我并不想從明天起馏予,喂馬天梧,劈柴。
    張琦zzq閱讀 147評(píng)論 0 0
  • 文字,這個(gè)事兒 其實(shí)我不行蛹尝, 雖然后豫,男人不能說(shuō)自己不行, 那我只能手動(dòng)滑稽了突那。 主要是挫酿,每次開(kāi)頭我都能想半天,卻又...
    誰(shuí)是擺渡人閱讀 338評(píng)論 1 4