参考:
使用Mybatis Generator可以快速根据数据库中已经建立好的表来创建mybatis代码,但是一旦数据库的表结构发生变动,就要重新运行Mybatis Generator插件。每次运行都会在已经生成的xml后追加一遍所有的内容(包括原来已经生成的代码,相当于一个xml中定义了两次老代码)。而po类文件和java接口文件会被完全覆盖。
首先,你可以在每次重新生成之前,手动删除原来所有的文件,这样可以解决追加重复内容的问题。但是如果你要实现一些自定义的数据库操作方法,那如果每次删除xml岂不是每次都要重新写自定义的方法?
那现在我希望的是,既可以不用每次都手动删除,又可以保留之前自定义的内容。
在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文件了。但是我自己新定义的方法也被完全覆盖掉了。
这时候,我一般会使用一个方法(不一定是最合适最正确的,但我自己使用没什么问题,可以作为一个参考的方法)。
比如有个用户表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
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论