代码生成器

在项目开发中,代码生成器能有效减少重复劳动,提高开发效率。以下基于提供的代码库,讲解两种常用代码生成方式:MyBatis 逆向工程自定义模板代码生成器

一、MyBatis 逆向工程(数据库表→实体 / 映射文件)

1. 作用

根据数据库表结构自动生成:

  • 实体类(Model)
  • Mapper 接口(Dao 层)
  • Mapper 映射文件(XML)

2. 核心代码与配置

(1)依赖配置(pom.xml)

xml

复制代码
<!-- MyBatis逆向工程核心依赖 -->
<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.3.6</version>
</dependency>
<!-- 数据库驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>
(2)逆向工程配置文件(generatorConfig.xml)

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">

<generatorConfiguration>
    <context id="mybatisGenerator">
        <!-- 去除自动生成的注释 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!-- 数据库连接配置 -->
        <jdbcConnection 
            driverClass="com.mysql.cj.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/ham?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"
            userId="root"
            password="123456">
        </jdbcConnection>

        <!-- 类型解析器(DECIMAL/NUMERIC转Integer) -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- 生成实体类的路径 -->
        <javaModelGenerator 
            targetPackage="com.qcby.model"
            targetProject=".\hami_core\src\main\java">
            <property name="trimStrings" value="true" /> <!-- 去除字符串前后空格 -->
        </javaModelGenerator>

        <!-- 生成Mapper映射文件的路径 -->
        <sqlMapGenerator 
            targetPackage="mapper"
            targetProject=".\hami_core\src\main\resources">
        </sqlMapGenerator>

        <!-- 生成Mapper接口的路径 -->
        <javaClientGenerator 
            type="XMLMAPPER" <!-- 接口与XML分离模式 -->
            targetPackage="com.qcby.dao"
            targetProject=".\hami_core\src\main\java">
        </javaClientGenerator>

        <!-- 指定要生成的表(关闭Example相关方法,简化代码) -->
        <table 
            tableName="album" 
            enableCountByExample="false"
            enableUpdateByExample="false" 
            enableDeleteByExample="false"
            enableSelectByExample="false" 
            selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>
(3)执行类(Generator.java)

java

运行

复制代码
package com.qcby.util;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Generator {
    public void generator() throws Exception {
        List<String> warnings = new ArrayList<>();
        boolean overwrite = true; // 允许覆盖已有文件
        // 加载配置文件
        File configFile = new File("hami_core/src/main/resources/generatorConfig.xml");
        ConfigurationParser parser = new ConfigurationParser(warnings);
        Configuration config = parser.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        // 执行生成
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }

    // 入口方法
    public static void main(String[] args) throws Exception {
        try {
            Generator generator = new Generator();
            generator.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. 生成结果说明

album表为例,生成以下文件:

  • 实体类com.qcby.model.Album.java(包含字段、getter/setter)
  • Mapper 接口com.qcby.dao.AlbumMapper.java(继承BaseDao<Album>
  • 映射文件resources/mapper/AlbumMapper.xml(包含 CRUD 的 SQL 语句)

二、自定义模板代码生成器(实体→Service / 实现类)

1. 作用

根据实体类名自动生成:

  • Service 接口
  • Service 实现类
  • Mapper 接口(补充逆向工程未覆盖的逻辑)

2. 核心代码(SourceGenerator.java)

复制代码
package com.qcby.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

/**
 * 基于模板文件生成代码(通过IO流替换占位符)
 */
public class SourceGenerator {
    // 入口方法:生成指定实体类的相关代码
    public static void main(String[] args) throws Exception {
        generatorSource("Songer"); // 生成Songer相关的Service和Dao
    }

    // 统一生成入口
    public static void generatorSource(String objName) throws Exception {
        generateDao(objName);       // 生成Mapper接口
        generateService(objName);   // 生成Service接口
        generateServiceImpl(objName); // 生成Service实现类
    }

    // 生成Mapper接口(基于DemoMapper.tpl模板)
    public static void generateDao(String objName) throws Exception {
        // 读取模板文件
        BufferedReader br = new BufferedReader(new FileReader("hami_core/src/test/resources/tpl/DemoMapper.tpl"));
        // 输出目标文件(如com/qcby/dao/SongerMapper.java)
        BufferedWriter bw = new BufferedWriter(new FileWriter("hami_core/src/main/java/com/qcby/dao/" + objName + "Mapper.java"));
        
        String line;
        while ((line = br.readLine()) != null) {
            line = line.replace("Demo", objName); // 替换占位符Demo为实体名
            bw.write(line);
            bw.newLine();
        }
        bw.close();
        br.close();
    }

    // 生成Service接口(基于DemoService.tpl模板)
    public static void generateService(String objName) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader("hami_core/src/test/resources/tpl/DemoService.tpl"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("hami_core/src/main/java/com/qcby/service/" + objName + "Service.java"));
        
        String line;
        while ((line = br.readLine()) != null) {
            line = line.replace("Demo", objName);
            bw.write(line);
            bw.newLine();
        }
        bw.close();
        br.close();
    }

    // 生成Service实现类(基于DemoServiceImpl.tpl模板)
    public static void generateServiceImpl(String objName) throws Exception {
        // 生成首字母小写的变量名(如Songer→songer)
        String lowerObjName = objName.substring(0, 1).toLowerCase() + objName.substring(1);
        
        BufferedReader br = new BufferedReader(new FileReader("hami_core/src/test/resources/tpl/DemoServiceImpl.tpl"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("hami_core/src/main/java/com/qcby/service/impl/" + objName + "ServiceImpl.java"));
        
        String line;
        while ((line = br.readLine()) != null) {
            line = line.replace("Demo", objName);       // 替换类名
            line = line.replace("demo", lowerObjName);  // 替换变量名
            bw.write(line);
            bw.newLine();
        }
        bw.close();
        br.close();
    }
}

3. 模板文件说明(以 Service 实现类为例)

假设DemoServiceImpl.tpl模板内容如下:

复制代码
package com.qcby.service.impl;

import com.qcby.model.Demo;
import com.qcby.service.DemoService;
import com.qcby.dao.DemoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DemoServiceImpl extends BaseServiceImpl<Demo> implements DemoService {
    private DemoMapper demoMapper;

    @Autowired
    public void setDemoMapper(DemoMapper demoMapper) {
        this.demoMapper = demoMapper;
        this.baseDao = demoMapper;
    }
}

生成SongerServiceImpl.java时,会自动替换:

  • DemoSonger(类名)
  • demosonger(变量名)

三、两种生成方式对比

类型 输入 输出 适用场景
MyBatis 逆向工程 数据库表 实体类、Mapper 接口 / XML 数据库表结构→基础 CRUD 代码
自定义模板生成器 实体类名 Service 接口 / 实现类、扩展 Mapper 实体类→业务层模板代码

四、使用流程

  1. 通过逆向工程生成基础代码

    • 配置generatorConfig.xml(指定数据库表)
    • 运行Generator.main()生成实体类、Mapper 接口和 XML
  2. 通过模板生成器补充业务层代码

    • 准备模板文件(DemoMapper.tpl等)
    • 运行SourceGenerator.main("实体类名")生成 Service 相关代码
  3. 扩展自定义方法

    • 在生成的接口中添加特殊业务方法(如MtypeServiceImpl中的selectAll()

通过代码生成器,可将重复的模板化代码自动生成,开发者只需关注核心业务逻辑,大幅提升开发效率。

相关推荐
Slow菜鸟2 小时前
Java开发规范(五)| 接口设计规范—前后端/跨服务协作的“架构级契约”
java·状态模式·设计规范
草原印象2 小时前
Spring Boot Spring MVC MyBatis MyBatis Plus框架编写项目实战案例
spring boot·spring·mybatis·springmvc·mybatisplus
Slow菜鸟2 小时前
SpringBoot教程(三十五)| SpringBoot集成TraceId(追踪ID)
java·spring boot·后端
__万波__2 小时前
二十三种设计模式(二)--工厂方法模式
java·设计模式·工厂方法模式
汤姆yu2 小时前
基于SpringBoot的餐饮财务管理系统的设计与实现
java·spring boot·后端
3***31212 小时前
Spring Boot 整合 MyBatis 与 PostgreSQL 实战指南
spring boot·postgresql·mybatis
q***31142 小时前
【JAVA进阶篇教学】第十二篇:Java中ReentrantReadWriteLock锁讲解
java·数据库·python
带刺的坐椅2 小时前
Solon AI 开发学习8 - chat - Vision(理解)图片、声音、视频
java·ai·solon·mcp