canna-cloud【二】canna-cloud-mybatis-generator

项目地址:https://github.com/xuanshuangchen/canna-cloud.git

1、通过简化配置文件,方便开发

datasource.type=com.alibaba.druid.pool.DruidDataSource

datasource.driverJarPath=org/postgresql/postgresql/42.2.5/postgresql-42.2.5.jar
datasource.driverClassName=org.postgresql.Driver
datasource.url=jdbc:postgresql://127.0.0.1:5432/db_canna
datasource.username=postgres
datasource.password=postgres

TEMP_PROJECT_PATH=/temp/
GENERATOR_TABLE_CONF_NAME=generator/app.ini

driverJarPath直接读取maven的工程目录,减少了驱动可能不存在的问题。

2、表配置

[module_app]
modulePackage=com.flower.canna.cloud.service.app
contextName=canna-cloud-service-app
projectPath=/canna-cloud/canna-cloud-service/canna-cloud-service-app/
schema=public
moduleSchema=module_app
[table_common]
t_app_info=AppInfo

[column_t_app_info]
columnName=type
javaType=com.flower.canna.service.common.mybatis.EnumType
typeHandler=com.flower.canna.cloud.base.biz.mybatis.CommonEnumTypeHandler
suffix=::jsonb
operation=<=

同一个模块,只需指定工程的路径,便可直接生成全部相应的定制化程序。

对应自定义处理字段,可通过配置相应的处理方法,实现字段的映射。

3、生成后的配置文件如下:

<?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>
    <classPathEntry location="/maven/repo/org/postgresql/postgresql/42.2.5/postgresql-42.2.5.jar"/>
    <context id="canna-cloud-service-app" targetRuntime="com.flower.canna.cloud.generator.mybatis.runtime.CannaTableMyBatis3">
        <plugin type="com.flower.canna.cloud.generator.mybatis.plugins.ModelMapperPlugin"/>
        <plugin type="com.flower.canna.cloud.generator.mybatis.plugins.MapperXmlMapperPlugin"/>
        <plugin type="com.flower.canna.cloud.generator.mybatis.plugins.ExpandMapperXmlMapperPlugin"/>
        <plugin type="com.flower.canna.cloud.generator.mybatis.plugins.biz.JavaServicePlugin"/>
        <plugin type="com.flower.canna.cloud.generator.mybatis.plugins.biz.JavaEnumPlugin"/>
        <plugin type="com.flower.canna.cloud.generator.mybatis.plugins.CommonMapperPlugin"/>
        <commentGenerator type="com.flower.canna.cloud.generator.mybatis.rewrite.RemarkDefaultCommentGenerator">
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <jdbcConnection driverClass="org.postgresql.Driver" connectionURL="jdbc:postgresql://120.78.61.232:35432/db_wallet" userId="postgres" password="postgres">
            <property name="remarksReporting" value="true"/>
            <property name="useInformationSchema" value="true"/>
        </jdbcConnection>
        <javaModelGenerator targetPackage="com.flower.canna.cloud.service.app.api.model" targetProject="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-api/src/main/java">
            <property name="enableSubPackages" value="false"/>
            <property name="rootClass" value="com.flower.canna.cloud.base.biz.model.Identifiable"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <sqlMapGenerator targetPackage="mybatis.postgresql.com.flower.canna.cloud.service.app" targetProject="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-producer/src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <javaClientGenerator targetPackage="com.flower.canna.cloud.service.app.producer.mapper" targetProject="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-producer/src/main/java" type="CANNA_MAPPER">
            <property name="enableSubPackages" value="false"/>
            <property name="rootInterface" value="com.flower.canna.cloud.base.biz.mapper.BaseMapper"/>
        </javaClientGenerator>
        <table tableName="t_app_info" domainObjectName="AppInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" catalog="catalog" alias="t">
            <property name="runtimeSchema" value="${module_app}"/>
            <property name="enableSubPackages" value="false"/>
            <property name="serviceGenerator-targetPackage" value="com.flower.canna.cloud.service.app.api.service"/>
            <property name="serviceGenerator-targetProject" value="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-api/src/main/java"/>
            <property name="serviceGenerator-template" value="common/service.vm"/>
            <property name="serviceGenerator-serviceName" value="AppInfoService"/>
            <property name="serviceGenerator-serviceFullName" value="com.flower.canna.cloud.service.app.api.service.AppInfoService"/>
            <property name="serviceGenerator-firstLowServiceName" value="appInfoService"/>
            <property name="serviceGenerator-firstLowConsumerServiceName" value="appInfoConsumerService"/>
            <property name="serviceGenerator-restPath" value="/app/info"/>
            <property name="serviceGenerator-feignClientName" value="T-APP-INFO"/>
            <property name="serviceImplGenerator-targetPackage" value="com.flower.canna.cloud.service.app.producer.service"/>
            <property name="serviceImplGenerator-targetProject" value="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-producer/src/main/java"/>
            <property name="serviceImplGenerator-template" value="common/service-impl.vm"/>
            <property name="serviceImplGenerator-serviceName" value="AppInfoService"/>
            <property name="serviceImplGenerator-serviceFullName" value="com.flower.canna.cloud.service.app.api.service.AppInfoService"/>
            <property name="serviceImplGenerator-firstLowServiceName" value="appInfoService"/>
            <property name="serviceImplGenerator-firstLowConsumerServiceName" value="appInfoConsumerService"/>
            <property name="serviceImplGenerator-restPath" value="/app/info"/>
            <property name="serviceImplGenerator-feignClientName" value="T-APP-INFO"/>
            <property name="producerControllerGenerator-targetPackage" value="com.flower.canna.cloud.service.app.producer.controller"/>
            <property name="producerControllerGenerator-targetProject" value="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-producer/src/main/java"/>
            <property name="producerControllerGenerator-template" value="eurake-base/producer-controller.vm"/>
            <property name="producerControllerGenerator-serviceName" value="AppInfoService"/>
            <property name="producerControllerGenerator-serviceFullName" value="com.flower.canna.cloud.service.app.api.service.AppInfoService"/>
            <property name="producerControllerGenerator-firstLowServiceName" value="appInfoService"/>
            <property name="producerControllerGenerator-firstLowConsumerServiceName" value="appInfoConsumerService"/>
            <property name="producerControllerGenerator-restPath" value="/app/info"/>
            <property name="producerControllerGenerator-feignClientName" value="T-APP-INFO"/>
            <property name="consumerControllerGenerator-targetPackage" value="com.flower.canna.cloud.service.app.consumer.controller"/>
            <property name="consumerControllerGenerator-targetProject" value="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-consumer/src/main/java"/>
            <property name="consumerControllerGenerator-template" value="eurake-base/consumer-controller.vm"/>
            <property name="consumerControllerGenerator-serviceName" value="AppInfoService"/>
            <property name="consumerControllerGenerator-serviceFullName" value="com.flower.canna.cloud.service.app.api.service.AppInfoService"/>
            <property name="consumerControllerGenerator-firstLowServiceName" value="appInfoService"/>
            <property name="consumerControllerGenerator-firstLowConsumerServiceName" value="appInfoConsumerService"/>
            <property name="consumerControllerGenerator-restPath" value="/app/info"/>
            <property name="consumerControllerGenerator-feignClientName" value="T-APP-INFO"/>
            <property name="consumerRemoteGenerator-targetPackage" value="com.flower.canna.cloud.service.app.consumer.remote"/>
            <property name="consumerRemoteGenerator-targetProject" value="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-consumer/src/main/java"/>
            <property name="consumerRemoteGenerator-template" value="eurake-base/consumer-remote.vm"/>
            <property name="consumerRemoteGenerator-serviceName" value="AppInfoService"/>
            <property name="consumerRemoteGenerator-serviceFullName" value="com.flower.canna.cloud.service.app.api.service.AppInfoService"/>
            <property name="consumerRemoteGenerator-firstLowServiceName" value="appInfoService"/>
            <property name="consumerRemoteGenerator-firstLowConsumerServiceName" value="appInfoConsumerService"/>
            <property name="consumerRemoteGenerator-restPath" value="/app/info"/>
            <property name="consumerRemoteGenerator-feignClientName" value="T-APP-INFO"/>
            <property name="consumerServiceGenerator-targetPackage" value="com.flower.canna.cloud.service.app.consumer.service"/>
            <property name="consumerServiceGenerator-targetProject" value="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-consumer/src/main/java"/>
            <property name="consumerServiceGenerator-template" value="eurake-base/consumer-service.vm"/>
            <property name="consumerServiceGenerator-serviceName" value="AppInfoService"/>
            <property name="consumerServiceGenerator-serviceFullName" value="com.flower.canna.cloud.service.app.api.service.AppInfoService"/>
            <property name="consumerServiceGenerator-firstLowServiceName" value="appInfoService"/>
            <property name="consumerServiceGenerator-firstLowConsumerServiceName" value="appInfoConsumerService"/>
            <property name="consumerServiceGenerator-restPath" value="/app/info"/>
            <property name="consumerServiceGenerator-feignClientName" value="T-APP-INFO"/>
            <property name="enumsGenerator-targetPackage" value="com.flower.canna.cloud.service.app.api.enums"/>
            <property name="enumsGenerator-targetProject" value="/canna-cloud/canna-cloud-service/canna-cloud-service-app/canna-cloud-service-app-api/src/main/java"/>
            <property name="enumsGenerator-template" value="not-exist-enum.vm"/>
            <property name="enumsGenerator-serviceName" value="AppInfoService"/>
            <property name="enumsGenerator-serviceFullName" value="com.flower.canna.cloud.service.app.api.service.AppInfoService"/>
            <property name="enumsGenerator-firstLowServiceName" value="appInfoService"/>
            <property name="enumsGenerator-firstLowConsumerServiceName" value="appInfoConsumerService"/>
            <property name="enumsGenerator-restPath" value="/app/info"/>
            <property name="enumsGenerator-feignClientName" value="T-APP-INFO"/>
            <generatedKey column="id" sqlStatement="JDBC"/>
            <columnOverride column="type" javaType="com.flower.canna.service.common.mybatis.EnumType" typeHandler="com.flower.canna.cloud.base.biz.mybatis.CommonEnumTypeHandler" delimitedColumnName="false">
                <property name="operation" value="&amp;lt;="/>
            </columnOverride>
        </table>
    </context>
</generatorConfiguration>

4、通过一系列的自定义插件,完成相对应的代码生成

使用lombok,简化getter/setter,同时引入builder

public class ModelMapperPlugin extends PluginAdapter {

    public ModelMapperPlugin() {
        super();
    }

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
                                                 IntrospectedTable introspectedTable) {

        topLevelClass.addImportedType("lombok.AllArgsConstructor");
        topLevelClass.addImportedType("lombok.Builder");
        topLevelClass.addImportedType("lombok.Getter");
        topLevelClass.addImportedType("lombok.NoArgsConstructor");
        topLevelClass.addImportedType("lombok.Setter");

        topLevelClass.addAnnotation("@AllArgsConstructor");
        topLevelClass.addAnnotation("@Builder");
        topLevelClass.addAnnotation("@NoArgsConstructor");
        topLevelClass.addAnnotation("@Setter");
        topLevelClass.addAnnotation("@Getter");

        return true;
    }

    @Override
    public boolean modelFieldGenerated(Field field,
                                       TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
                                       IntrospectedTable introspectedTable,
                                       ModelClassType modelClassType) {
        // 添加日期操作
        if ("Date".equals(introspectedColumn.getFullyQualifiedJavaType().getShortName())) {

            Field fieldPrefix = new Field(field.getName() + CommonConstants.DATE_PREFIX, FullyQualifiedJavaType.getStringInstance()); //$NON-NLS-1$
            fieldPrefix.setVisibility(JavaVisibility.PRIVATE);

            Field fieldSuffix = new Field(field.getName() + CommonConstants.DATE_SUFFIX, FullyQualifiedJavaType.getStringInstance()); //$NON-NLS-1$
            fieldSuffix.setVisibility(JavaVisibility.PRIVATE);

            topLevelClass.addField(fieldPrefix);
            topLevelClass.addField(fieldSuffix);

            try {
                IntrospectedColumn columnPrefix = BeanTransferUtils.transferColumn(introspectedColumn, IntrospectedColumn.class, IntrospectedColumn.class);
                columnPrefix.setActualColumnName(columnPrefix.getActualColumnName() + CommonConstants.DATE_PREFIX);
                columnPrefix.setRemarks( columnPrefix.getRemarks() + "-起始" );

                IntrospectedColumn columnSuffix = BeanTransferUtils.transferColumn(introspectedColumn, IntrospectedColumn.class, IntrospectedColumn.class);
                columnSuffix.setActualColumnName(columnPrefix.getActualColumnName() + CommonConstants.DATE_SUFFIX);
                columnSuffix.setRemarks( columnSuffix.getRemarks() + "-截止" );

                context.getCommentGenerator().addFieldComment(fieldPrefix, introspectedTable, columnPrefix);
                context.getCommentGenerator().addFieldComment(fieldSuffix, introspectedTable, columnSuffix);
            }catch (Exception e) {
                e.printStackTrace();
            }

        }
        return true;
    }

    @Override
    public boolean modelSetterMethodGenerated(Method method,
                                              TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
                                              IntrospectedTable introspectedTable,
                                              ModelClassType modelClassType) {
        // 取消get/set
        return false;
    }

    @Override
    public boolean modelGetterMethodGenerated(Method method,
                                              TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
                                              IntrospectedTable introspectedTable,
                                              ModelClassType modelClassType) {
        // 取消get/set
        return false;
    }

}

字段枚举的生成,避免在需要使用字段时,引入字符串,增加代码可读性

public class JavaEnumPlugin extends PluginAdapter {

    public JavaEnumPlugin() {
        super();
    }

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
        this.generatorEnum(introspectedTable);

        return true;
    }

    private void generatorEnum(IntrospectedTable introspectedTable) {
        String tagName = TagConstants.ENUMS_GENERATOR;
        Properties properties = introspectedTable.getTableConfiguration().getProperties();
        String targetPackage = properties.getProperty(tagName + "-" + AttrConstants.TARGET_PACKAGE);
        String targetProject = properties.getProperty(tagName + "-" + AttrConstants.TARGET_PROJECT);
        String domainObjectName = introspectedTable.getTableConfiguration().getDomainObjectName();

        String enumColumnJava = CannaUtils.getFullName(targetProject, targetPackage, domainObjectName,"Enum.java");

        String packageLine = "package " + targetPackage + ";";

        String enumName = "public enum " + domainObjectName + "Enum {";

        List<String> resultList = new ArrayList<>();

        resultList.add(packageLine);
        resultList.add(enumName);
        for ( IntrospectedColumn introspectedColumn: introspectedTable.getAllColumns() ) {
            resultList.add("    " + introspectedColumn.getActualColumnName().toUpperCase() + ",");
        }
        resultList.add("}");
        try {
            FileUtils.writeLines(new File(enumColumnJava), CommonConstants.DEFAULT_CHARSET, resultList);
        } catch (IOException e) {
            System.err.println(e);
        }
    }


}

5、继承代码生成逻辑,添加自定义Mapper生成器

public class CannaTableMyBatis3 extends IntrospectedTableMyBatis3Impl {

    @Override
    public List<GeneratedXmlFile> getGeneratedXmlFiles() {
        List<GeneratedXmlFile> answer = new ArrayList<>();

        if (xmlMapperGenerator != null) {
            Document document = xmlMapperGenerator.getDocument();
            GeneratedXmlFile gxf = new GeneratedXmlFile(document,
                    getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(),
                    context.getSqlMapGeneratorConfiguration().getTargetProject(),
                    false, context.getXmlFormatter());
            if (context.getPlugins().sqlMapGenerated(gxf, this)) {
                answer.add(gxf);
            }
        }

        return answer;
    }

    protected AbstractJavaClientGenerator createJavaClientGenerator() {
        if (context.getJavaClientGeneratorConfiguration() == null) {
            return null;
        }

        String type = context.getJavaClientGeneratorConfiguration()
                .getConfigurationType();

        AbstractJavaClientGenerator javaGenerator;
        if ("XMLMAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new JavaMapperGenerator(getClientProject());
        } else if ("MIXEDMAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new MixedClientGenerator(getClientProject());
        } else if ("ANNOTATEDMAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new AnnotatedClientGenerator(getClientProject());
        } else if ("MAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new JavaMapperGenerator(getClientProject());
        } else if ("CANNA_MAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new CannaJavaMapperGenerator(getClientProject());
        } else {
            javaGenerator = (AbstractJavaClientGenerator) ObjectFactory
                    .createInternalObject(type);
        }

        return javaGenerator;
    }

}

6、自动生成apidoc,方便前后端对接

public class RemarkDefaultCommentGenerator extends DefaultCommentGenerator {

	@Override
	public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
		innerClass.addJavaDocLine("/**");
		innerClass.addJavaDocLine(" * @apiDefine SUCCESS_" + introspectedTable.getFullyQualifiedTable().getDomainObjectName());
		List<IntrospectedColumn> introspectedColumnList = introspectedTable.getAllColumns();
		for (IntrospectedColumn introspectedColumn: introspectedColumnList){
			innerClass.addJavaDocLine(" * @apiSuccess {" + introspectedColumn.getFullyQualifiedJavaType().getShortName() + "} " + introspectedColumn.getJavaProperty() + " " + introspectedColumn.getRemarks());
		}

		innerClass.addJavaDocLine(" */");

		innerClass.addJavaDocLine("/**");
		innerClass.addJavaDocLine(" * @apiDefine PARAM_" + introspectedTable.getFullyQualifiedTable().getDomainObjectName());
		for (IntrospectedColumn introspectedColumn: introspectedColumnList){
			innerClass.addJavaDocLine(" * @apiParam {" + introspectedColumn.getFullyQualifiedJavaType().getShortName() + "} " + introspectedColumn.getJavaProperty() + " " + introspectedColumn.getRemarks());
		}

		innerClass.addJavaDocLine(" */");
	}

	@Override
	public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		this.addClassComment(topLevelClass, introspectedTable);
	}



	@Override
	public void addFieldComment(Field field, IntrospectedTable introspectedTable,
			IntrospectedColumn introspectedColumn) {

		field.addJavaDocLine("/**"); //$NON-NLS-1$
		if (introspectedColumn.getRemarks() != null) {
			field.addJavaDocLine(" * " + introspectedColumn.getRemarks()); //$NON-NLS-1$
		}

		field.addJavaDocLine(" */"); //$NON-NLS-1$
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值