一二三应用开发平台——代码生成(3)——生成代码1

生成代码

接下来具体说一说生成代码的处理。前文提到过,平台的代码生成功能是基于MybatisPlus组件的代码生成器改造的,大框架还是遵循原组件的模式,不过还是做了比较多的集成和改造工作。

实现服务接口的方法是generateCode,源码如下:

@Override
    public void generateCode(String entityCode) {

        // 获取实体配置信息
        Entity entity = entityService.getByCode(entityCode);
        // 获取模块配置信息
        Module module = moduleService.query(entity.getModule());
        // 获取模型列表
        List<EntityModel> entityModelList = entityModelService.getByEntityId(entity.getId());
        // 未找到模型,抛出异常
        if (CollectionUtils.isEmpty(entityModelList)) {
            throw new CustomException(EntityException.MODEL_NOT_FOUND, entity.getName());
        }

        for (EntityModel entityModel : entityModelList) {
            // 创建代码生成器对象
            AutoGenerator codeGenerator = getCodeGenerator();
            
            // 配置全局信息
            configGlobal(codeGenerator, entity.getAuthor());

            // 配置包
            configPackage(codeGenerator, module.getPackagePath(), module.getCode());

            // 配置模板
            configTemplate(codeGenerator);

            // 配置注入
            configInjection(codeGenerator, entity, module.getApp().toLowerCase(), module.getCode(), entityModel);

            // 策略配置
            configStrategy(codeGenerator, entity.getCode(), module.getAbbreviation(), entityModel);

            // 使用Freemarker替代默认的Velocity模板引擎
            MyFreemarkerTemplateEngine freemarkerTemplateEngine = new MyFreemarkerTemplateEngine();

            // 生成代码
            codeGenerator.execute(freemarkerTemplateEngine);
        }

    }

处理过程与前面说的生成数据库表类似,也是先根据实体编码,获取实体对应的配置信息及其归属的模块配置信息,然后读取下属的数据模型,根据数据模型配置信息来生成代码。

代码生成器初始化

代码生成器使用的是MybatisPlus组件提供的AutoGenerator,初始化工作如下:

    /**
     * 获取代码生成器
     *
     * @return 代码生成器
     */
    @NotNull
    private AutoGenerator getCodeGenerator() {

        // 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(dataSource)
                .databaseQueryClass(SQLQuery.class)
                .typeConvert(new MySqlTypeConvert())
                .keyWordsHandler(new MySqlKeyWordsHandler())
                .build();
        // 实例化代码生成器
        return new AutoGenerator(dataSourceConfig);    
    }

初始化工作比较简单,指定数据源,然后类型转换和关键字处理设置为MySql数据库对应的类。

配置全局信息

将全局信息单独重构为一个方法,传入代码生成器的对象以及从实体配置中获取到的作者信息,如下:

// 配置全局信息
configGlobal(codeGenerator, entity.getAuthor());

该方法的内容如下:

    /**
     * 配置全局信息
     *
     * @param codeGenerator 代码生成器
     * @param author        作者
     */
    private void configGlobal(AutoGenerator codeGenerator, String author) {
        // 定义输出路径
        String outputDir = System.getProperty("user.dir") + "/output";       
        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig.Builder()
                // 指定输出路径
                .outputDir(outputDir)
                // 生成代码结束后,禁止自动打开目录
                .disableOpenDir()
                // 设置代码编写人
                .author(author)           
                // 定义日期类型为java8的LocalDateTime
                .dateType(DateType.TIME_PACK)
                // 设置注释日期格式
                .commentDate("yyyy-MM-dd")
                .build();

        codeGenerator.global(globalConfig);
    }

上述代码的几个设置项可以参见注释,清晰明了,其中的时间类型DateType枚举值,通过查看源码,含义更清楚,如下:

package com.baomidou.mybatisplus.generator.config.rules;

/**
 * 数据库时间类型 到 实体类时间类型 对应策略
 *
 * @author miemie
 * @since 2018/5/22
 */
public enum DateType {
    /**
     * 只使用 java.util.date 代替
     */
    ONLY_DATE,
    /**
     * 使用 java.sql 包下的
     */
    SQL_PACK,
    /**
     * 使用 java.time 包下的
     * <p>java8 新的时间类型</p>
     */
    TIME_PACK
}

配置包

调用传入参数如下:

// 配置包
configPackage(codeGenerator, module.getPackagePath(), module.getCode());

方法源码如下:

   /**
     * 配置包
     *
     * @param codeGenerator 代码生成器
     * @param parentPackage 父包
     * @param moduleCode    模块编码
     */
    private void configPackage(AutoGenerator codeGenerator, String parentPackage, String moduleCode) {
        PackageConfig packageConfig = new PackageConfig.Builder()
                .parent(parentPackage)
                .moduleName(moduleCode)
                // 实体类的包名
                .entity("entity")
                // 服务类的包名
                .service("service")
                // 服务实现类的包名
                .serviceImpl("service.impl")
                // Mybatis的mapper接口包名
                .mapper("mapper")
                // Mybatis的xml包名
                .xml("mapper")
                // 控制器类的包名
                .controller("controller")
                .build();
        codeGenerator.packageInfo(packageConfig);
    }

这个方法主要设置生成的各层代码的包名,这里我们遵循的最常见的规范,使用entity、service、service.impl、mapper、controller来作为包名。

其中,对于mybatis的mapper对应的xml文件,常见的有两种处理方式,一种是放到resources目录下,一种是放在mapper接口包下,考虑到相关性和操作的便利性,平台这里采用了后一种方式。

配置模板

调用传入参数如下:

// 配置模板
configTemplate(codeGenerator);

方法源码如下:

/**
 * 配置模板
 *
 * @param codeGenerator 代码生成器
 */
private void configTemplate(AutoGenerator codeGenerator) {
    TemplateConfig templateConfig = new TemplateConfig.Builder()
            .entity("/templates/entity.java")
            .service("/templates/service.java")
            .serviceImpl("/templates/serviceImpl.java")
            .mapper("/templates/mapper.java")
            .controller("/templates/controller.java")
            .build();
    codeGenerator.template(templateConfig);
}

这里实际是指定各层代码的模板。

这些模板从哪来呢?

最初的版本,实际是从MybatisPlus的代码生成器对应的mybatis-plus-generator-3.5.3.jar中拿到的,如下:

MybatisPlus支持多种模板,如Freemaker、Velocity等,平台选择的是Freemaker,因此将后缀名为ftl的模板文件拷贝到平台实体配置模块下的resouces目录下,然后根据自己的需要进行修改,如下图:

开发平台资料

平台名称:一二三应用开发平台
简介: 企业级通用低代码应用开发平台,免费全开源可商用
设计资料:csdn专栏
开源地址:Gitee
开源协议:MIT

如果您在阅读本文时获得了帮助或受到了启发,我衷心希望您能够喜欢并收藏这篇文章,为它点赞,并在评论区与我分享您的想法和心得。让我们一起交流学习,不断进步,遇见更加优秀的自己!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行者无疆1982

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值