Mybatis Generator还可以这样用,再也不用担心自定义开发的XMl和Mapper方法被覆盖了

本文介绍了如何通过开发Mybatis Generator插件,避免在数据库变更时自定义的XML和Mapper方法被覆盖。通过创建基类并让生成的类继承基类,同时处理XML文件保留自定义节点,实现代码更新与自定义部分的分离。
摘要由CSDN通过智能技术生成

前言

说到ORM工具,Mybatis无疑是当下最流行的一款。搭建一个新的项目首先就要集成Mybatis,通过Mybatis Generator逆向生成基本的增删查改xml文件和Mapper接口文件,代码中可以直接使用其进行数据库操作可以说非常方便。但是基本的增删查改不能满足复杂的业务需求,当我们在xml文件和Mapper接口文件中编写了大量的自定义方法后,有一天需求需要变更字段,这时就需要重新生成xml文件和Mapper接口文件,如果在原项目目录中直接生成原来文件会被覆盖掉,我们编写的大量的自定义方法会因此而丢失。之前的做法是换一个目录生成,将生成的新文件内容拷贝到原来的文件中,这样做是可行的,但是原来的文件已经被自定义方法污染严重,生成的方法和自定义的方法交融在一起,需要很仔细的去寻找一不小心就回删除过多代码,导致程序出错。

本文将以一种全新的方式解决上面的问题,不需要人工拷贝代码替换。具体做法是通过开发Mybatis Generator Plugin的方式对原来的Mybatis Generator功能进行增强,使其完美解决各种现实开发场景遇到问题。

Mybatis Generator 插件介绍

Mybatis Generator工具除了具有基本的生成代码功能,还提供了插件功能,用户拓展其功能,工具内置了许多拓展插件,如下:

在这里插入图片描述

其中CachePlugin插件将为生成的Xml添加缓存支持相关代码,如MybatisGerneratorConfig.xml文件中添加代码如下:

<plugin type="org.mybatis.generator.plugins.CachePlugin" >
    <property name="cache_type" value="org.mybatis.caches.ehcache.LoggingEhcache"/>
</plugin>

添加代码后,MybatisGerneratorConfig.xml文件内容片段如下:

在这里插入图片描述

最终生成的xml文件片段如下:

在这里插入图片描述

接下来通过开发自己的Plugin来解决数据库变更后,再次使用Mybatis Generator生成代码导致文件覆盖的问题。

开发自己的插件

以生成t_test表为例,pojo类为Test.java,表结构如下:

CREATE TABLE `t_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `msg` varchar(32) DEFAULT NULL COMMENT '内容',
  PRIMARY KEY (`id`)
);

  1. 开发思路
    pojo类处理

增强代码使其生成的pojo类作为基类BaseTest.java,同时生成Test.java类继承至BaseTest.java,代码中pojo的引用全部为子类,自定义方法全部写在子类中,插件只更新基类不更新子类,当表结构变动时生成的pojo会覆盖BaseTest.java,而Test.java中的自定义方法全部保留。

mapper类处理

增强代码使其生成的Mapper接口作为基类BaseTestMapper.java,同时生成TestMapper.java类继承至BaseTestMapper.java,代码中Mapper的引用全部为子类,自定义方法全部写在子类中,插件只更新基类不更新子类,当表结构变动时生成的Mapper会覆盖BaseTestMapper.java,而TestMapper.java中的自定义方法全部保留。

xml文件处理

通过动态解析xml的方式获取文件中所有节点,通过节点Id属性判断节点是否为工具生成,是则替换,不是则表示节点为自定义节点保留,然后将新生成的节点和自定义节点合并后替换原来文件即可。

  1. 编写插件

定义插件

名称为:BaseClassPlugin继承至 org.mybatis.generator.api.PluginAdapter;为插件提供两个属性:useBaseEntity默认值为true表示采用基类的方式生成pojo类,false表示不使用基类方式生成pojo类;useBaseMapper默认值true表示采用基类方式生成mapper接口,false表示不使用基类形式生成mapper接口。

处理pojo类

重写org.mybatis.generator.api.PluginAdapterpublic void initialized(IntrospectedTable introspectedTable)方法,获取原pojo类全路径重置类全路径为基类全路径,创建子类并继承至基类,代码如下:

if(useBaseEntity){
    String baseRecordType = introspectedTable.getBaseRecordType();
    String[] split = baseRecordType.split("\.");
    StringBuilder sb = new StringBuilder();
    for (int i = 0,len = split.length; i < len; i++) {
        if(i == len - 1){
            sb.append("Base");
        }
        sb.append(split[i]);
        if(i != len - 1){
            sb.append(".");
        }
    }
    baseEntityName = sb.toString();
    introspectedTable.setBaseRecordType(baseEntityName);
    subEntityClass = new TopLevelClass(baseRecordType);
    subEntityClass.setVisibility(JavaVisibility.PUBLIC);
    subEntityClass.setSuperClass(baseEntityName);
}

重写org.mybatis.generator.api.PluginAdapterpublic List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable)方法,将子类添加到带生成Java文件集合中,代码如下:

List<GeneratedJavaFile> awser = new ArrayList<>(2);
String targetProject = introspectedTable.getContext().getJavaModelGeneratorConfiguration().getTargetProject();
File subEntityFile = new File(targetProject + "/" + subEntityClass.getType().getFullyQualifiedName().replace(".", "/") + ".java");
if(useBaseEntity && !subEntityFile.exists()){
    GeneratedJavaFile javaEntityFile = new GeneratedJavaFile(subEntityClass,targetProject,new DefaultJavaFormatter());
    awser.add(javaEntityFile);
}
return awser;

处理mapper类

重写org.mybatis.generator.api.PluginAdapterpublic void initialized(IntrospectedTable introspectedTable)方法,获取原mapper类全路径重置类全路径为基类全路径,创建子类并继承至基类,代码如下:

if(useBaseMapper){
    String myBatis3JavaMapperType = introspectedTable.
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值