Mybatis Generator插件自动生成xml映射文件追加与覆盖的问题 - Ares - CSDN博客

参考:

mybatis generator 覆盖xml文件

使用Mybatis Generator可以快速根据数据库中已经建立好的表来创建mybatis代码,但是一旦数据库的表结构发生变动,就要重新运行Mybatis Generator插件。每次运行都会在已经生成的xml后追加一遍所有的内容(包括原来已经生成的代码,相当于一个xml中定义了两次老代码)。而po类文件和java接口文件会被完全覆盖。

首先,你可以在每次重新生成之前,手动删除原来所有的文件,这样可以解决追加重复内容的问题。但是如果你要实现一些自定义的数据库操作方法,那如果每次删除xml岂不是每次都要重新写自定义的方法?

那现在我希望的是,既可以不用每次都手动删除,又可以保留之前自定义的内容。

自定义MybatisGenerator插件解决重复追加内容的问题

在pom.xml引入jar包的依赖

   <!-- mybatis 集成-->        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis</artifactId>            <version>3.2.8</version>        </dependency>        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis-spring</artifactId>            <version>1.3.0</version>        </dependency>         <dependency>            <groupId>org.mybatis.generator</groupId>            <artifactId>mybatis-generator-core</artifactId>            <version>1.3.7</version>        </dependency>

然后自定义插件

public class OverwriteXmlPlugin extends PluginAdapter {    @Override    public boolean validate(List<String> warnings) {        return true;    }     @Override    public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {        sqlMap.setMergeable(false);        return super.sqlMapGenerated(sqlMap, introspectedTable);    }}

很简单,只要把Mergeable这个默认是true的值给设置成false就可以了。

将这个类放入到我们的项目中,然后在Gegerator的配置文件中进行配置(要在context节点下添加)

<!-- 覆盖xml文件 --><plugin type="com.springapp.mvc.dao.OverwriteXmlPlugin"></plugin>

然后运行generator插件,报错

Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.7:generate (default-cli) on project RemoteMonitoringJava: Execution default-cli of goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.7:generate failed: Cannot instantiate object of type com.springapp.mvc.dao.OverwriteXmlPlugin -> [Help 1] 

由于没有详细信息,这时候在maven后添加-e -X再试一下,查看详细报错

mybatis-generator:generate -e -X
Caused by: java.lang.RuntimeException: Cannot instantiate object of type com.springapp.mvc.dao.OverwriteXmlPlugin    at org.mybatis.generator.internal.ObjectFactory.createInternalObject(ObjectFactory.java:182)    at org.mybatis.generator.internal.ObjectFactory.createPlugin(ObjectFactory.java:219)    at org.mybatis.generator.config.Context.generateFiles(Context.java:500)    at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:269)    at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:189)    at org.mybatis.generator.maven.MyBatisGeneratorMojo.execute(MyBatisGeneratorMojo.java:229)    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)    ... 26 more

 发现在ObjectFactory中,通过反射生成对象的时候找不到类,看一下源码,发现这里使用

Thread.currentThread().getContextClassLoader()获取的classloader加载类实例,那我们这个自定义的插件类也没有被这个classloader加载啊,所以肯定是无法生成实例的。

查看一下网上关于自定义插件的教程。

首先,将刚才自定义的插件,提取出来,新建一个Java项目,然后将上面写的依赖也导入,再将刚才插件类放入项目中。

使用itellij或是eclipse的功能将项目打成jar包。

使用maven命令将这个jar包发布到本地的maven库中。

install:install-file -Dfile=f:/overwritexml.jar -DgroupId=com.ryan -DartifactId=overwritexml -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar

红色字体根据自己的情况调整。

发布成功后,在pom.xml配置mybatisGenerator插件的地方添加对这个jar包的依赖:

 <plugin>                <groupId>org.mybatis.generator</groupId>                <artifactId>mybatis-generator-maven-plugin</artifactId>                <version>1.3.7</version>                <dependencies>                    <dependency>                        <groupId>com.ryan</groupId>                        <artifactId>overwritexml</artifactId>                        <version>0.0.1-SNAPSHOT</version>                    </dependency>                </dependencies>                <configuration>                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>                    <verbose>true</verbose>                    <overwrite>true</overwrite>                </configuration>            </plugin>

Dependencies节点下的内容是新加的。

然后再试一次就可以啦,注意下面的这个包名要调整一下,和jar包中的保持一致。但是现在这个十分依赖本地的环境,如果是公司协同开发的话,可以考虑将这个jar包发布到公司搭建的私有maven仓库中。

<!-- 覆盖xml文件 --><plugin type="com.ryan.overwritexml.OverwriteXmlPlugin"></plugin>

解决覆盖自定义xml中内容的问题

现在每次运行插件就不用了 每次删除原有的xml文件了。但是我自己新定义的方法也被完全覆盖掉了。

这时候,我一般会使用一个方法(不一定是最合适最正确的,但我自己使用没什么问题,可以作为一个参考的方法)。

比如有个用户表UserTable,通过generator会生成三个文件,一个mapper映射文件,UserMapper.xml;一个Po类文件,User.java;一个Java interface的mapper接口文件,UserMapper.java.

此时再UserMapper.xml中,mapper节点namespace属性的值是UserMapper.java的包名+类名。

这时我如果想新加入一个查询注册时间在2018年且性别为男性所有用户的方法,如果还是在UserMapper.xml和UserMapper.java直接加代码,下次再用generator生成文件的时候就会把我们自定义的内容覆盖掉。

那这时我可以新建一个ExUserMapper.java的接口类,然后定义一个新的方法getUsers(String gender,long startTimestamp,long endTimestamp),然后和UserMapper.java放在相同的包下。

再定义一个ExUserMapper.xml,从UserMapper.xml复制过来resultMap标签下的内容,然后将namespace的值从UserMapper接口类的全路径改成ExUserMapper接口类的全路径,并添加一个id为getUsers的select查询。

在代码里可以完全使用ExUserMapper.java来生命对象并使用,因为ExUserMapper.java继承了UserMapper.java,所以UserMapper中提供的基本操作用ExUserMapper也可以获取到。

唯一的问题就是,如果表结构发生改变了,别忘了把ExUserMapper.xml中的ResultMap同步更新一下。


Original url: Access
Created at: 2019-03-27 14:44:15
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论