java-MyBatisGenerator-(一)插件开发生成自定的代码

(一)插件开发生成自定的代码

(二)开发一个支持tkmybatis的插件 

java-MyBatisGenerator-(一)插件开发生成自定的代码

MyBatisGenerator 为我们减少庞大且容易出错的纯“体力”代码,关于它的配置和使用网上一大把就不介绍了。
这里主要说下它的插件机制,自己开发插件站在巨人的肩膀继续前进~~~

一、主要类介绍
不得不说它的设计非常好,万物介对象。它把一个java类代码拆解的非常细,对象可以划分为两类。
一类是表示数据库表、字段的对象;另一类是表示java类的对象;
数据库对象有:
    IntrospectedTable   表示一个数据库表
    IntrospectedColumn  表示一个表字段
java类对象有:
    CompilationUnit 一个接口表示一个独立的编译单元(java里就是类、接口、枚举),它有三个实现类;
    Interface   表示一个接口;
    TopLevelClass  表示一个普通的类;
    TopLevelEnumeration 表示一个枚举;
    FullyQualifiedJavaType  表示一个完全限定名(包名+类名=完全限定名);
    Field   表示类的一个成员属性;
    Method  表示一个独立的方法;

二、插件原理
1.插件架构简述
简单理解就是在主体逻辑的一些关键点,插入了可以修改上下文参数的回调函数,通过修改参数可以对原有逻辑进行增强。

2.插件中的类介绍
org.mybatis.generator.api.Plugin 插件的顶级接口,里面定义了大几十个函数(真NB!!!)
org.mybatis.generator.api.PluginAdapter 适配层开发插件需要继承它(如果你想重写小一百个方法直接实现Plugin接口也可以)
org.mybatis.generator.plugins.* 这个包下面是一些支持的插件,学习插件开发非常好的借鉴代码。
org.mybatis.generator.internal.PluginAggregator 插件聚合器,代码生成过程中通过调用这个类的方法,从而触发xml中配置的所有插件;

3.xml中配置插件的位置
插件配置在xml的这个位置:
generatorConfiguration/context/plugin
如:生成的表实体对象重写ToString方法的一个内置插件
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>

三、生成一个最简单的类
现在通过一个简单示例,看下怎么自定义生成一个java文件。
关注下这个方法:这个方法可以在组件基础上添加自己的文件描述对象;
org.mybatis.generator.api.PluginAdapter#contextGenerateAdditionalJavaFiles(org.mybatis.generator.api.IntrospectedTable)
直接上代码了!
 

public class TkMybatisPlugin extends PluginAdapter {
    /** 可以生成自定义的文件 */
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();
        answer.add(getTestJaveFile(introspectedTable));//测试用的
        return answer;
    }
    /** 生成一个自定义文件 */
    private GeneratedJavaFile getTestJaveFile(IntrospectedTable introspectedTable){
        String typeName = MessageFormat.format("{0}.TestInfo",_packageName);
        //类的完全限定名(决定生成的文件的目录接口)
        TopLevelClass c = new TopLevelClass(typeName);
        //导入的依赖包
        c.addImportedType(new FullyQualifiedJavaType("java.io.File;//111"));
        c.addImportedType(new FullyQualifiedJavaType("java.io.File;//222"));
        //构建一个编译单元
        GeneratedJavaFile gjf = new GeneratedJavaFile(
                c,
                context.getJavaModelGeneratorConfiguration().getTargetProject(),
                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                context.getJavaFormatter());
        //类的成员属性怎么标识??
        Field f = new Field();
        f.setVisibility(JavaVisibility.PRIVATE);
        f.setInitializationString("\"aaa\"");
        f.setComment("//my field");
        f.setName("id");
        f.setType(FullyQualifiedJavaType.getStringInstance());
        c.addField(f);
        //类的方法
        Method fun = new Method();
        fun.addBodyLine("//hello word");
        fun.addBodyLine("return \"xxx\";");
        fun.setName("getId");
        fun.setReturnType(FullyQualifiedJavaType.getStringInstance());
        fun.addAnnotation("//@Service(111)");
        fun.addJavaDocLine("/** hello function */");
        c.addMethod(fun);
        return gjf;
    }    
}

上面这个插件可以生成如下的代码:
 

package gen.tkmybatis;

import java.io.File;//111;
import java.io.File;//222;

class TestInfo {
    private String id = "aaa";

    /** hello function */
    //@Service(111)
    String getId() {
        //hello word
        return "xxx";
    }
}

四、一个完整的xml(table.mapperName\entityName\xmlName\interName被我魔改了支持占位符,可以自定义前缀后缀)
 


<?xml version="1.0" encoding="UTF-8"?>
<!--

       Copyright ${license.git.copyrightYears} the original author or authors.

       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

          http://www.apache.org/licenses/LICENSE-2.0

       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.

-->
<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 该配置文件说明插件需要如何生成,以及生成对应的包名,路径等信息。
      还有重要的就是我们要生成的实体类所对应的的表或者视图 -->

<!--
注:该配置文件中有两个要注意的地方:
a、配置文件中的注释应该为:不能在注释里面再嵌套–之类的符号,比如:,否则运行时会提示报错信息。
b、标签里面元素是有顺序的,如果顺序乱了也会报错的,顺序依次为:
property——>plugin——>commentGenerator——>jdbcConnection——>
javaTypeResolver——>javaModelGenerator——>sqlMapGenerator——>
javaClientGenerator——>table+
c、对于generatorConfig.xml文件中引入的mybatis_generator.properties文件,里面主要是数据库连接信息和生成的文件的目录信息,我们可以在generatorConfig.xml的同目录下创建该文件
-->
<generatorConfiguration>
    <!--可以将数据先关内容放到配置文件中-->
    <properties resource="MyTest/mybatis_generator.properties" />
    <context id="MBG" targetRuntime="MyBatis3" defaultModelType="conditional">
        <!-- 注意以下标签的顺序:property*,plugin*,commentGenerator?,jdbcConnection,
                javaTypeResolver?,javaModelGenerator,sqlMapGenerator?,
                javaClientGenerator?,table+ -->

        <!-- property -->
        <!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表;
        一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
     -->
        <property name="autoDelimitKeywords" value="false"/>
        <!-- 生成的Java文件的编码 -->
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 格式化java代码 -->
        <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
        <!-- 格式化XML代码 -->
        <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>

        <!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <!-- property-end -->
        <!--
        plugin插件声明位置:支持的插件在 org.mybatis.generator.plugins 包下定义;
        生成的表实体对象重写了 ToString 方法
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        生成的表实体对象增加了,equals和hashCode方法
        <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
        <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
        -->
        <plugin type="org.mybatis.generator.myplugins.TkMybatisPlugin"/>

        <!--生成注解配置-->
        <commentGenerator type="MyCommentGenerator">
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="false"/>
            <!-- 不希望生成的注释中包含时间戳 -->
            <property name="suppressDate" value="true" />
            <!-- 是否自动为每一个生成的类创建一个构造方法-->
            <property name="constructorBased" value="false"/>
            <!-- ??? -->
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>
        <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
        <!-- 数据库连接 -->
        <jdbcConnection
                driverClass="${appstore.driver}"
                connectionURL="${appstore.url}"
                userId="${appstore.username}"
                password="${appstore.password}">
            <!--获取表的表注释,需要设置该值为 true-->
            <property name="useInformationSchema" value="true"/>
        </jdbcConnection>
        <!-- java类型处理器
        用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
        注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和 NUMERIC数据类型;-->
        <javaTypeResolver  type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
            <!--
            true:使用BigDecimal对应DECIMAL和 NUMERIC数据类型
            false:默认,
                scale>0;length>18:使用BigDecimal;
                scale=0;length[10,18]:使用Long;
                scale=0;length[5,9]:使用Integer;
                scale=0;length<5:使用Short;-->
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!--1.生成表名实体对象 -->
        <javaModelGenerator
                targetPackage="${modelPackage}"
                targetProject="${targetProject}">
            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
            <property name="enableSubPackages" value="true"/>
            <!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
            <property name="trimStrings" value="false"/>
        </javaModelGenerator>
        <!--2.生成 mapper.xml 文件  -->
        <sqlMapGenerator
                targetPackage="${sqlMapperPackage}"
                targetProject="${targetProject}" >
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--3.生成 dao.java 接口文件 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="${daoMapperPackage}"
                             targetProject="${targetProject}" >
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!--table 可选参数:
        tableName:数据库表名,支持sql模糊查询 % 占位符;如,txt_% 生成所有 txt_ 开头的表名
        表明完全限定名:catalog名.schema名.table名
        1,schema:数据库的schema;
        2,catalog:数据库的catalog;
        3,alias:为数据表设置的别名,如果设置了alias,那么生成的所有的SELECT SQL语句中,列名会变成:alias_actualColumnName
        4,domainObjectName:生成的domain类的名字,如果不设置,直接使用表名作为domain类的名字;可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面;
        5,enableInsert(默认true):指定是否生成insert语句;
        6,enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get);
        7,enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句;
        8,enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update);
        9,enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete);
        10,enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句;
        11,enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询);
        12,enableUpdateByExample(默认true):MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性);
        13,modelType:参考context元素的defaultModelType,相当于覆盖;
        14,delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,如果类似MYSQL这样的数据库,使用的是`(反引号,那么还需要设置context的beginningDelimiter和endingDelimiter属性)
        15,delimitAllColumns:设置是否所有生成的SQL中的列名都使用标识符引起来。默认为false,delimitIdentifiers参考context的属性
        16,mapperName:1.3.5 新增
        注意,table里面很多参数都是对javaModelGenerator,context等元素的默认属性的一个复写;
        自定义节点:支持{0}占位符操作,mapperName 属性将不起作用
               entityName="{0}Model",表实体对象格式
               xmlName="{0}Mapper",xml文件名格式
               interName="I{0}Dao",接口文件名格式
        -->
        <!--需要生成的表-->
        <!--<table tableName="Ctrip%"-->
            <!--schema=""   数据库名-->
            <!--delimitAllColumns="fals"-->
            <!--mapperName="{0}Xxx"-->
            <!--entityName="{0}Model"-->
            <!--xmlName="{0}Mapper"-->
            <!--interName="I{0}Dao"-->
            <!--enableInsert ="true"-->
            <!--enableSelectByPrimaryKey ="true"-->
            <!--enableUpdateByPrimaryKey ="true"-->
            <!--enableDeleteByPrimaryKey ="true"-->
            <!--selectByPrimaryKeyQueryId ="false"-->
            <!--selectByExampleQueryId ="false"-->
            <!--enableDeleteByExample ="false"-->
            <!--enableCountByExample ="false"-->
            <!--enableUpdateByExample ="false"-->
            <!--enableSelectByExample ="false"/>-->
        <!-- 需要生成的表 -->
        <table tableName="myTableName"
               delimitAllColumns="false"
               mapperName="{0}xxx"
               entityName="{0}Do"
               xmlName="{0}Mapper"
               interName="{0}Dao"
               enableInsert ="true"
               enableSelectByPrimaryKey ="false"
               enableUpdateByPrimaryKey ="false"
               enableDeleteByPrimaryKey ="false"
               selectByPrimaryKeyQueryId ="false"
               selectByExampleQueryId ="false"
               enableDeleteByExample ="false"
               enableCountByExample ="false"
               enableUpdateByExample ="false"
               enableSelectByExample ="false"/>


    </context>
</generatorConfiguration>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值