【SpringBoot DB系列】Mybatis-Plus 代碼自動生成


【SpringBoot DB系列】Mybatis-Plus 代碼自動生成

一個簡單的實例工程,介紹利用 mybatis-plus 的代碼自動生成插件,根據表結構來生成對應的類和 xml 配置文件

I. 代碼生成

本文主要內容來自官方教程,通過實例方式介紹代碼生成過程

1. 准備

准備兩張表,用於測試

CREATE TABLE `userT0` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '用戶名',
  `pwd` varchar(26) NOT NULL DEFAULT '' COMMENT '密碼',
  `isDeleted` tinyint(1) NOT NULL DEFAULT '0',
  `created` varchar(13) NOT NULL DEFAULT '0',
  `updated` varchar(13) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `story_t0` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userId` int(20) unsigned NOT NULL DEFAULT '0' COMMENT '作者的userID',
  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '作者名',
  `title` varchar(26) NOT NULL DEFAULT '' COMMENT '密碼',
  `story` text COMMENT '故事內容',
  `is_deleted` tinyint(1) NOT NULL DEFAULT '0',
  `create_at` varchar(13) NOT NULL DEFAULT '0',
  `update_at` varchar(13) NOT NULL DEFAULT '0',
  `tag` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `userId` (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

請注意,上面兩張表的命名格式並不一樣,有的是駝峰,有的是下划線(主要為了演示不同表名,對於生成代碼的影響)

2. 配置依賴

首先需要在我們的 xml 文件中,添加相關的依賴

<dependencies>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.3.1.tmp</version>
    </dependency>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <!-- 下面兩個,用於測試生成后的代碼,在生成代碼時,可以不需要-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.2.0</version>
    </dependency>
</dependencies>

3. 代碼生成類

寫一個代碼生成類方法,主要邏輯如下

public class CodeGenerator {
    public static void main(String[] args) {
        // 代碼生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir") + "/spring-boot/106-mybatis-plus-generator";
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("YiHui");
        gc.setOpen(false);
        // 覆蓋寫
        gc.setFileOverride(false);
        mpg.setGlobalConfig(gc);

        // 數據源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        // 不額外指定模塊,如果指定為 test,則生成的xml會在 mapper/test/ 目錄下
        pc.setModuleName("");
        pc.setParent("com.git.hui.boot.mybatis.plus");
        mpg.setPackageInfo(pc);

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

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";

        // 自定義輸出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定義配置會被優先輸出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定義輸出文件名 , 如果你 Entity 設置了前后綴、此處注意 xml 的名稱會跟着發生變化!!
                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + "/" +
                        tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

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

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);
        // 不自動生成controller類
        templateConfig.setController(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // strategy.setSuperEntityClass("你自己的父類實體,沒有就不用設置!");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 公共父類
        // strategy.setSuperControllerClass("你自己的父類控制器,沒有就不用設置!");
        // 寫於父類中的公共字段
        // strategy.setSuperEntityColumns("id");

        // 設置需要生成的表名
        strategy.setInclude("userT0", "story_t0");
        strategy.setControllerMappingHyphenStyle(true);
        // strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}

上面的代碼,絕大部分都是通用的,下面着重說明需要注意的點

  • GlobalConfig#setOutputDir: 設置代碼輸出的項目根路徑,請根據具體的項目要求進行指定,不包含包名哦
  • GlobalConfig#setFileOverride(true): 設置為 true,則每次生成都會覆蓋之前生成的代碼,適用於表結構發生變化的場景
    • 注意:會導致之前添加的業務代碼被覆蓋掉,需要額外注意
    • 通常希望設置為 false,當表結構發生變化時,手動介入
  • DataSourceConfig: 數據源的設置,上面設置的是 mysql 的相關配置
  • PackageConfig: 包信息
    • setParent: java 包路徑
    • setModuleName: 設置模塊名,如設置為 test,則 xml 在mapper/test/目錄下; parent 包自動加上.test
  • FileOutConfig: xml 文件名
  • TemplateConfig: 模板配置
    • 可用默認的代碼生成模板,也可以使用自定義的模板
    • 不想生成某個模板類時,設置為 null 即可(如上面的不生成 controller)
  • StrategyConfig: 策略配置
    • 可以指定 db->pojo 字段名的映射規則
    • 可以指定 POJO/Controller 繼承自定義的基類

在 IDEA 中,直接右鍵執行上面的代碼,就會生成目標類,如下截圖

4. 輸出測試

測試我們生成的類,是否可以對 db 進行操作,則有必要寫一個啟動類

@RestController
@SpringBootApplication
@MapperScan("com.git.hui.boot.mybatis.plus.mapper")
public class Application {
    @Autowired
    private IUserT0Service userT0Service;

    @GetMapping
    public UserT0 hello(int id) {
        return userT0Service.getById(id);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

請注意上面的@MapperScan注解,其次對應的application.yml配置文件內容如下

spring:
  datasource:
    # 注意指定時區
    url: jdbc:mysql://127.0.0.1:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password:

mybatis-plus:
  configuration:
    # 執行的sql語句日志輸出
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

在 db 中插入一條數據

INSERT INTO `userT0` (`id`, `name`, `pwd`, `isDeleted`, `created`, `updated`)
VALUES
	(1, '一灰灰', 'yihuihuiblog', 0, '2020-04-06 15', '2020-04-06 15');

訪問 url: http://localhost:8080/?id=1

控制台輸出如下:

5. 特殊場景說明

上面的代碼生成,針對首次執行生成打碼時,問題不大;但是后續的業務開發中,總會有一些其他的情況,下面分別說明

a. 表結構修改

當表的結構發生變化時,我們需要一般需要重新生成對應的 Entity,這個時候,需要GlobalConfig#setFileOverride(true)

b. 繼承公用 POJO

我們可以定義一個通用的 PO 類,希望所有的表生成的 POJO 繼承它

@Data
public class BasePo implements Serializable {
    private static final long serialVersionUID = -1136173266983480386L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

}

在代碼自動生成類的策略配置中,添加下面的兩行設置即可

// 所有實體類繼承自 BasePo, 且id在父類中
StrategyConfig strategy = new StrategyConfig();
strategy.setSuperEntityClass(BasePo.class);
strategy.setSuperEntityColumns("id");

c. 生成部分代碼

有些時候,我並不希望生成service,xml,可能就只需要實體類 + mapper接口,這個時候可以設置TemplateConfig

TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setController(null);
templateConfig.setEntityKt(null);
templateConfig.setService(null);
templateConfig.setServiceImpl(null);

II. 其他

0. 項目

系列博文

源碼

1. 一灰灰 Blog

盡信書則不如,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現 bug 或者有更好的建議,歡迎批評指正,不吝感激

下面一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛

一灰灰blog


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM