mybatis-plus3.3.1代碼生成器自定義配置的使用方法

分享myBatis-plus代碼生成器的使用步驟以及以其為基礎(chǔ)編寫的在線crud代碼生成器

1.pom文件中配置mybatis-plus-generator

使用代碼生成器時需要先把pom文件中mybatis-plus依賴注釋掉滋尉,并引入mybatis-plus-generaor依賴和模板引擎依賴,否則寫生成器代碼時候找不到對應(yīng)的包

    <!--<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>-->

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>

2.編寫代碼生成器

直接復(fù)制官方示例代碼的話需要修改代碼中使用freemarker模板引擎的地方換成velocity厂画,以下是修改后的代碼

package com.lfy.springboot;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: 李豐翼
 * @DateTime: 2020/5/18 0018 19:21
 * @Description: TODO
 */
public class CodeGenerator {

    public static void main(String[] args) {
        // 代碼生成器

        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("lfy");
        gc.setOpen(false);
        gc.setMapperName("%sDao");
        gc.setXmlName("%sDao");
        gc.setSwagger2(true); //實體屬性 Swagger2 注解
        gc.setFileOverride(true);
        gc.setBaseColumnList(true);
        gc.setBaseResultMap(true);
        mpg.setGlobalConfig(gc);

        // 數(shù)據(jù)源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/wenjuan?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");

        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.lfy.springboot");
        pc.setMapper("dao");
        mpg.setPackageInfo(pc);

        // 自定義配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        //String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
         String templatePath = "/templates/mapper.xml.vm";
        // 自定義輸出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定義配置會被優(yōu)先輸出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定義輸出文件名 们镜, 如果你 Entity 設(shè)置了前后綴结蟋、此處注意 xml 的名稱會跟著發(fā)生變化!!
                return projectPath + "/src/main/resources/mapper/" +
                        tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

/*        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判斷自定義文件夾是否需要創(chuàng)建
                checkDir("調(diào)用默認(rèn)方法創(chuàng)建的目錄诚些,自定義目錄用");
                if (fileType == FileType.MAPPER) {
                    // 已經(jīng)生成 mapper 文件判斷存在硝岗,不想重新生成返回 false
                    return !new File(filePath).exists();
                }
                // 允許生成模板文件
                return true;
            }
        });*/

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定義輸出模板
        //指定自定義模板路徑氢哮,注意不要帶上.ftl/.vm, 會根據(jù)使用的模板引擎自動識別
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);


        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 寫于父類中的公共字段
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        strategy.setRestControllerStyle(true);
        strategy.setSuperControllerClass("com.lfy.springboot.controller.BaseController");



        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new VelocityTemplateEngine());

        mpg.execute();
    }

}

更多詳細(xì)配置參考官方文檔
https://mp.baomidou.com/config/generator-config.html#%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE

3.編寫xml模板

創(chuàng)建mapper.xml.vm放在templates目錄下,這里只寫了mapper.xml的模板型檀,其他的部分也可以自定義模板文件
可以參考https://blog.csdn.net/kanglong129/article/details/98362009

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">

    #if(${enableCache})
           <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>

    #end
    #if(${baseResultMap})
        <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
        #foreach($field in ${table.fields})
            #if(${field.keyFlag})##生成主鍵排在第一位
               <id column="${field.name}" property="${field.propertyName}" />
            #end
        #end
        #foreach($field in ${table.commonFields})##生成公共字段
               <result column="${field.name}" property="${field.propertyName}" />
        #end
        #foreach($field in ${table.fields})
            #if(!${field.keyFlag})##生成普通字段
                <result column="${field.name}" property="${field.propertyName}" />
            #end
        #end
        </resultMap>
    #end
        <sql id="Base_Table_Name">
            ${table.name}
        </sql>
        <sql id="Base_Column_List">
#foreach($field in ${table.commonFields})
   #if(${field.name} == ${field.propertyName})${field.name}#else${field.name} AS ${field.propertyName}#end,
#end
        ${table.fieldNames}
        </sql>
</mapper>

mapper模板中可以使用的屬性可以參考源碼中com.baomidou.mybatisplus.generator.config.po.TableInfo中的屬性

/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.generator.config.po;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * 表信息冗尤,關(guān)聯(lián)到當(dāng)前字段信息
 *
 * @author YangHu
 * @since 2016/8/30
 */
@Data
@Accessors(chain = true)
public class TableInfo {

    private final Set<String> importPackages = new HashSet<>();
    private boolean convert;
    private String name;
    private String comment;
    private String entityName;
    private String mapperName;
    private String xmlName;
    private String serviceName;
    private String serviceImplName;
    private String controllerName;
    private List<TableField> fields;
    /**
     * 公共字段
     */
    private List<TableField> commonFields;
    private String fieldNames;

    public TableInfo setConvert(boolean convert) {
        this.convert = convert;
        return this;
    }

    protected TableInfo setConvert(StrategyConfig strategyConfig) {
        if (strategyConfig.containsTablePrefix(name) || strategyConfig.isEntityTableFieldAnnotationEnable()) {
            // 包含前綴
            this.convert = true;
        } else if (strategyConfig.isCapitalModeNaming(name)) {
            // 包含
            this.convert = false;
        } else {
            // 轉(zhuǎn)換字段
            if (NamingStrategy.underline_to_camel == strategyConfig.getColumnNaming()) {
                // 包含大寫處理
                if (StringUtils.containsUpperCase(name)) {
                    this.convert = true;
                }
            } else if (!entityName.equalsIgnoreCase(name)) {
                this.convert = true;
            }
        }
        return this;
    }

    public String getEntityPath() {
        return entityName.substring(0, 1).toLowerCase() + entityName.substring(1);
    }

    public TableInfo setEntityName(StrategyConfig strategyConfig, String entityName) {
        this.entityName = entityName;
        this.setConvert(strategyConfig);
        return this;
    }

    public TableInfo setFields(List<TableField> fields) {
        if (CollectionUtils.isNotEmpty(fields)) {
            this.fields = fields;
            // 收集導(dǎo)入包信息
            for (TableField field : fields) {
                if (null != field.getColumnType() && null != field.getColumnType().getPkg()) {
                    importPackages.add(field.getColumnType().getPkg());
                }
                if (field.isKeyFlag()) {
                    // 主鍵
                    if (field.isConvert() || field.isKeyIdentityFlag()) {
                        importPackages.add(com.baomidou.mybatisplus.annotation.TableId.class.getCanonicalName());
                    }
                    // 自增
                    if (field.isKeyIdentityFlag()) {
                        importPackages.add(com.baomidou.mybatisplus.annotation.IdType.class.getCanonicalName());
                    }
                } else if (field.isConvert()) {
                    // 普通字段
                    importPackages.add(com.baomidou.mybatisplus.annotation.TableField.class.getCanonicalName());
                }
                if (null != field.getFill()) {
                    // 填充字段
                    importPackages.add(com.baomidou.mybatisplus.annotation.TableField.class.getCanonicalName());
                    importPackages.add(com.baomidou.mybatisplus.annotation.FieldFill.class.getCanonicalName());
                }
            }
        }
        return this;
    }

    public TableInfo setImportPackages(String pkg) {
        importPackages.add(pkg);
        return this;
    }

    /**
     * 邏輯刪除
     */
    public boolean isLogicDelete(String logicDeletePropertyName) {
        return fields.parallelStream().anyMatch(tf -> tf.getName().equals(logicDeletePropertyName));
    }

    /**
     * 轉(zhuǎn)換filed實體為 xml mapper 中的 base column 字符串信息
     */
    public String getFieldNames() {
        if (StringUtils.isBlank(fieldNames)
            && CollectionUtils.isNotEmpty(fields)) {
            StringBuilder names = new StringBuilder();
            IntStream.range(0, fields.size()).forEach(i -> {
                TableField fd = fields.get(i);
                if (i == fields.size() - 1) {
                    names.append(fd.getName());
                } else {
                    names.append(fd.getName()).append(", ");
                }
            });
            fieldNames = names.toString();
        }
        return fieldNames;
    }
}

4.生成的效果如下

目錄

image.png

mapper.xml文件
image.png

5.使用完畢后將pom文件中的生成器依賴注釋,改為mybatis-plus

6.學(xué)習(xí)完之后胀溺,個人根據(jù)代碼生成器編寫了一個小的在線代碼生成開源項目

參數(shù).png

Gitee地址:https://gitee.com/li_feng_yi/code-generation 求star~~
項目地址:http://generator.lifengyi.cn/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裂七,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仓坞,更是在濱河造成了極大的恐慌背零,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,294評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件无埃,死亡現(xiàn)場離奇詭異徙瓶,居然都是意外死亡毛雇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評論 3 385
  • 文/潘曉璐 我一進(jìn)店門侦镇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灵疮,“玉大人,你說我怎么就攤上這事虽缕∈寂海” “怎么了?”我有些...
    開封第一講書人閱讀 157,790評論 0 348
  • 文/不壞的土叔 我叫張陵氮趋,是天一觀的道長伍派。 經(jīng)常有香客問我,道長剩胁,這世上最難降的妖魔是什么诉植? 我笑而不...
    開封第一講書人閱讀 56,595評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮昵观,結(jié)果婚禮上晾腔,老公的妹妹穿的比我還像新娘。我一直安慰自己啊犬,他們只是感情好灼擂,可當(dāng)我...
    茶點故事閱讀 65,718評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著觉至,像睡著了一般剔应。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上语御,一...
    開封第一講書人閱讀 49,906評論 1 290
  • 那天峻贮,我揣著相機(jī)與錄音茁计,去河邊找鬼漓藕。 笑死,一個胖子當(dāng)著我的面吹牛活烙,可吹牛的內(nèi)容都是我干的碉纺。 我是一名探鬼主播船万,決...
    沈念sama閱讀 39,053評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼骨田!你這毒婦竟也來了耿导?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,797評論 0 268
  • 序言:老撾萬榮一對情侶失蹤盛撑,失蹤者是張志新(化名)和其女友劉穎碎节,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抵卫,經(jīng)...
    沈念sama閱讀 44,250評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡狮荔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,570評論 2 327
  • 正文 我和宋清朗相戀三年胎撇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殖氏。...
    茶點故事閱讀 38,711評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡晚树,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雅采,到底是詐尸還是另有隱情爵憎,我是刑警寧澤,帶...
    沈念sama閱讀 34,388評論 4 332
  • 正文 年R本政府宣布婚瓜,位于F島的核電站宝鼓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏巴刻。R本人自食惡果不足惜愚铡,卻給世界環(huán)境...
    茶點故事閱讀 40,018評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胡陪。 院中可真熱鬧沥寥,春花似錦、人聲如沸柠座。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妈经。三九已至淮野,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狂塘,已是汗流浹背录煤。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評論 1 266
  • 我被黑心中介騙來泰國打工鳄厌, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留荞胡,地道東北人。 一個月前我還...
    沈念sama閱讀 46,461評論 2 360
  • 正文 我出身青樓了嚎,卻偏偏與公主長得像泪漂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子歪泳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,595評論 2 350