mybatis-generator扩展
程序员文章站
2022-12-23 19:00:08
在新公司的新项目想用mybatis-generator来生成DAO层,有同事提出一些改进意见,遂获得源码后进行小幅改造。 目标: 中文注释,精简注释 Model类使用lombok简化 增加selectOneByExample方法(较多的使用唯一索引查询场景) 首先获得源码 在任一项目中引入jar包, ......
在新公司的新项目想用mybatis-generator来生成dao层,有同事提出一些改进意见,遂获得源码后进行小幅改造。
目标:
- 中文注释,精简注释
- model类使用lombok简化
- 增加selectonebyexample方法(较多的使用唯一索引查询场景)
首先获得源码
在任一项目中引入jar包,使用maven download sources获取源码,最新版本1.3.7
<dependency> <groupid>org.mybatis.generator</groupid> <artifactid>mybatis-generator-core</artifactid> <version>1.3.7</version> </dependency>
构建项目
新建一个maven项目,设置groupid和artifactid
<groupid>com.mine.generator</groupid> <artifactid>mybatis-generator-core</artifactid> <version>1.0-snapshot</version>
把解压后的源码复制到目录
在pom.xml中添加项目依赖
<dependencies> <dependency> <groupid>log4j</groupid> <artifactid>log4j</artifactid> <scope>provided</scope> <version>1.2.17</version> <optional>true</optional> </dependency> <dependency> <groupid>org.slf4j</groupid> <artifactid>slf4j-api</artifactid> <scope>provided</scope> <version>1.7.25</version> <optional>true</optional> </dependency> <dependency> <groupid>org.apache.logging.log4j</groupid> <artifactid>log4j-api</artifactid> <scope>provided</scope> <version>2.11.0</version> <optional>true</optional> </dependency> <dependency> <groupid>commons-logging</groupid> <artifactid>commons-logging</artifactid> <scope>provided</scope> <version>1.2</version> <optional>true</optional> </dependency> <dependency> <groupid>org.apache.ant</groupid> <artifactid>ant</artifactid> <scope>provided</scope> <version>1.10.4</version> <optional>true</optional> </dependency> <dependency> <groupid>org.junit.vintage</groupid> <artifactid>junit-vintage-engine</artifactid> <version>5.2.0</version> <scope>test</scope> </dependency> <dependency> <groupid>org.hsqldb</groupid> <artifactid>hsqldb</artifactid> <version>2.4.1</version> <scope>test</scope> </dependency> <dependency> <groupid>com.github.javaparser</groupid> <version>3.6.12</version> <artifactid>javaparser-core</artifactid> </dependency> </dependencies>
功能拓展
model中文注释、精简其他注释
修改生成注释默认用的defaultcommentgenerator
package org.mybatis.generator.internal; import org.mybatis.generator.api.commentgenerator; import org.mybatis.generator.api.introspectedcolumn; import org.mybatis.generator.api.introspectedtable; import org.mybatis.generator.api.mybatisgenerator; import org.mybatis.generator.api.dom.java.*; import org.mybatis.generator.api.dom.xml.xmlelement; import org.mybatis.generator.internal.util.stringutility; import java.text.simpledateformat; import java.time.zoneddatetime; import java.time.format.datetimeformatter; import java.util.date; import java.util.properties; import java.util.set; /** * @author jeff butler */ public class defaultcommentgenerator implements commentgenerator { private simpledateformat dateformat = new simpledateformat("yyyy-mm-dd hh:mm:ss"); public defaultcommentgenerator() { super(); } @override public void addjavafilecomment(compilationunit compilationunit) { } @override public void addcomment(xmlelement xmlelement) { } @override public void addrootcomment(xmlelement rootelement) { } @override public void addconfigurationproperties(properties properties) { } protected string getdatestring() { return dateformat.format(new date()); } @override public void addclasscomment(innerclass innerclass, introspectedtable introspectedtable) { } @override public void addclasscomment(innerclass innerclass, introspectedtable introspectedtable, boolean markasdonotdelete) { } @override public void addmodelclasscomment(toplevelclass toplevelclass, introspectedtable introspectedtable) { toplevelclass.addjavadocline("/**"); toplevelclass.addjavadocline(" * 生成日期:" + getdatestring()); toplevelclass.addjavadocline(" * 表名: " + introspectedtable.getfullyqualifiedtable().tostring()); toplevelclass.addjavadocline(" */"); } @override public void addenumcomment(innerenum innerenum, introspectedtable introspectedtable) { } @override public void addfieldcomment(field field, introspectedtable introspectedtable, introspectedcolumn introspectedcolumn) { field.addjavadocline("/**"); field.addjavadocline(" * " + introspectedcolumn.getremarks()); field.addjavadocline(" */"); } @override public void addfieldcomment(field field, introspectedtable introspectedtable) { } @override public void addgeneralmethodcomment(method method, introspectedtable introspectedtable) { } @override public void addgettercomment(method method, introspectedtable introspectedtable, introspectedcolumn introspectedcolumn) { } @override public void addsettercomment(method method, introspectedtable introspectedtable, introspectedcolumn introspectedcolumn) { } @override public void addgeneralmethodannotation(method method, introspectedtable introspectedtable, set<fullyqualifiedjavatype> imports) { imports.add(new fullyqualifiedjavatype("javax.annotation.generated")); string comment = "source table: " + introspectedtable.getfullyqualifiedtable().tostring(); method.addannotation(getgeneratedannotation(comment)); } @override public void addgeneralmethodannotation(method method, introspectedtable introspectedtable, introspectedcolumn introspectedcolumn, set<fullyqualifiedjavatype> imports) { imports.add(new fullyqualifiedjavatype("javax.annotation.generated")); string comment = "source field: " + introspectedtable.getfullyqualifiedtable().tostring() + "." + introspectedcolumn.getactualcolumnname(); method.addannotation(getgeneratedannotation(comment)); } @override public void addfieldannotation(field field, introspectedtable introspectedtable, set<fullyqualifiedjavatype> imports) { imports.add(new fullyqualifiedjavatype("javax.annotation.generated")); string comment = "source table: " + introspectedtable.getfullyqualifiedtable().tostring(); field.addannotation(getgeneratedannotation(comment)); } @override public void addfieldannotation(field field, introspectedtable introspectedtable, introspectedcolumn introspectedcolumn, set<fullyqualifiedjavatype> imports) { imports.add(new fullyqualifiedjavatype("javax.annotation.generated")); string comment = "source field: " + introspectedtable.getfullyqualifiedtable().tostring() + "." + introspectedcolumn.getactualcolumnname(); field.addannotation(getgeneratedannotation(comment)); string remarks = introspectedcolumn.getremarks(); if (stringutility.stringhasvalue(remarks)) { field.addjavadocline("/**"); field.addjavadocline(" * database column remarks:"); string[] remarklines = remarks.split(system.getproperty("line.separator")); for (string remarkline : remarklines) { field.addjavadocline(" * " + remarkline); } field.addjavadocline(" */"); } } @override public void addclassannotation(innerclass innerclass, introspectedtable introspectedtable, set<fullyqualifiedjavatype> imports) { imports.add(new fullyqualifiedjavatype("javax.annotation.generated")); string comment = "source table: " + introspectedtable.getfullyqualifiedtable().tostring(); innerclass.addannotation(getgeneratedannotation(comment)); } private string getgeneratedannotation(string comment) { stringbuilder buffer = new stringbuilder(); buffer.append("@generated("); buffer.append("value=\""); buffer.append(mybatisgenerator.class.getname()); buffer.append('\"'); buffer.append(", date=\""); buffer.append(datetimeformatter.iso_offset_date_time.format(zoneddatetime.now())); buffer.append('\"'); buffer.append(", comments=\""); buffer.append(comment); buffer.append('\"'); buffer.append(')'); return buffer.tostring(); } }
model类使用lombok简化
修改baserecordgenerator的getcompilationunits的方法即可
public list<compilationunit> getcompilationunits() { fullyqualifiedtable table = introspectedtable.getfullyqualifiedtable(); progresscallback.starttask(getstring( "progress.8", table.tostring())); //$non-nls-1$ plugin plugins = context.getplugins(); commentgenerator commentgenerator = context.getcommentgenerator(); fullyqualifiedjavatype type = new fullyqualifiedjavatype( introspectedtable.getbaserecordtype()); toplevelclass toplevelclass = new toplevelclass(type); toplevelclass.addimportedtype("lombok.getter");// 导入lombok类 toplevelclass.addimportedtype("lombok.setter"); toplevelclass.setvisibility(javavisibility.public); commentgenerator.addjavafilecomment(toplevelclass); fullyqualifiedjavatype superclass = getsuperclass(); if (superclass != null) { toplevelclass.setsuperclass(superclass); toplevelclass.addimportedtype(superclass); } commentgenerator.addmodelclasscomment(toplevelclass, introspectedtable); toplevelclass.addannotation("@getter");// 增加lombok注解 toplevelclass.addannotation("@setter"); list<introspectedcolumn> introspectedcolumns = getcolumnsinthisclass(); if (introspectedtable.isconstructorbased()) { addparameterizedconstructor(toplevelclass, introspectedtable.getnonblobcolumns()); if (includeblobcolumns()) { addparameterizedconstructor(toplevelclass, introspectedtable.getallcolumns()); } if (!introspectedtable.isimmutable()) { adddefaultconstructor(toplevelclass); } } string rootclass = getrootclass(); for (introspectedcolumn introspectedcolumn : introspectedcolumns) { if (rootclassinfo.getinstance(rootclass, warnings) .containsproperty(introspectedcolumn)) { continue; } field field = getjavabeansfield(introspectedcolumn, context, introspectedtable); if (plugins.modelfieldgenerated(field, toplevelclass, introspectedcolumn, introspectedtable, plugin.modelclasstype.base_record)) { toplevelclass.addfield(field); toplevelclass.addimportedtype(field.gettype()); } } list<compilationunit> answer = new arraylist<>(); if (context.getplugins().modelbaserecordclassgenerated( toplevelclass, introspectedtable)) { answer.add(toplevelclass); } return answer;
}
增加selectonebyexample
首先查看类似的方法selectbyexample是怎么生成的,然后参考增加这个方法。
在introspectedtable中增加方法
public string getselectonebyexamplestatementid() { return "selectonebyexample";//可以跟其他源码一样设置成常量,这里简单处理 }
增加一个selectonebyexamplemethodgenerator
/** * copyright 2006-2016 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. */ package org.mybatis.generator.codegen.mybatis3.javamapper.elements; import org.mybatis.generator.api.dom.java.*; import java.util.set; import java.util.treeset; /** * * @author jeff butler * */ public class selectonebyexamplemethodgenerator extends abstractjavamappermethodgenerator { public selectonebyexamplemethodgenerator() { super(); } @override public void addinterfaceelements(interface interfaze) { set<fullyqualifiedjavatype> importedtypes = new treeset<>(); fullyqualifiedjavatype type = new fullyqualifiedjavatype( introspectedtable.getexampletype()); importedtypes.add(type); importedtypes.add(fullyqualifiedjavatype.getnewlistinstance()); method method = new method(); method.setvisibility(javavisibility.public); fullyqualifiedjavatype returntype = introspectedtable.getrules() .calculateallfieldsclass(); method.setreturntype(returntype); method.setname(introspectedtable.getselectonebyexamplestatementid()); method.addparameter(new parameter(type, "example")); //$non-nls-1$ context.getcommentgenerator().addgeneralmethodcomment(method, introspectedtable); addmapperannotations(interfaze, method); if (context.getplugins() .clientselectbyexamplewithblobsmethodgenerated(method, interfaze, introspectedtable)) { addextraimports(interfaze); interfaze.addimportedtypes(importedtypes); interfaze.addmethod(method); } } public void addmapperannotations(interface interfaze, method method) { } public void addextraimports(interface interfaze) { } }
增加一个selectonebyexampleelementgenerator
/** * copyright 2006-2016 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. */ package org.mybatis.generator.codegen.mybatis3.xmlmapper.elements; import org.mybatis.generator.api.dom.xml.attribute; import org.mybatis.generator.api.dom.xml.textelement; import org.mybatis.generator.api.dom.xml.xmlelement; import static org.mybatis.generator.internal.util.stringutility.stringhasvalue; /** * * @author jeff butler * */ public class selectonebyexampleelementgenerator extends abstractxmlelementgenerator { public selectonebyexampleelementgenerator() { super(); } @override public void addelements(xmlelement parentelement) { string fqjt = introspectedtable.getexampletype(); xmlelement answer = new xmlelement("select"); //$non-nls-1$ answer.addattribute(new attribute("id", //$non-nls-1$ introspectedtable.getselectonebyexamplestatementid())); answer.addattribute(new attribute( "resultmap", introspectedtable.getbaseresultmapid())); //$non-nls-1$ answer.addattribute(new attribute("parametertype", fqjt)); //$non-nls-1$ context.getcommentgenerator().addcomment(answer); answer.addelement(new textelement("select")); //$non-nls-1$ xmlelement ifelement = new xmlelement("if"); //$non-nls-1$ ifelement.addattribute(new attribute("test", "distinct")); //$non-nls-1$ //$non-nls-2$ ifelement.addelement(new textelement("distinct")); //$non-nls-1$ answer.addelement(ifelement); stringbuilder sb = new stringbuilder(); if (stringhasvalue(introspectedtable .getselectbyexamplequeryid())) { sb.append('\''); sb.append(introspectedtable.getselectbyexamplequeryid()); sb.append("' as queryid,"); //$non-nls-1$ answer.addelement(new textelement(sb.tostring())); } answer.addelement(getbasecolumnlistelement()); sb.setlength(0); sb.append("from "); //$non-nls-1$ sb.append(introspectedtable .getaliasedfullyqualifiedtablenameatruntime()); answer.addelement(new textelement(sb.tostring())); answer.addelement(getexampleincludeelement()); ifelement = new xmlelement("if"); //$non-nls-1$ ifelement.addattribute(new attribute("test", "orderbyclause != null")); //$non-nls-1$ //$non-nls-2$ ifelement.addelement(new textelement("order by ${orderbyclause}")); //$non-nls-1$ answer.addelement(ifelement); if (context.getplugins() .sqlmapselectbyexamplewithoutblobselementgenerated(answer, introspectedtable)) { parentelement.addelement(answer); } answer.addelement(new textelement("limit 1")); } }
修改javamappergenerator,在getcompilationunits方法中增加addselectonebyexamplemethod(interfaze),这里顺带把生成的代码排了个序,并且把不常用的几个方法给注释掉了。
@override
public list<compilationunit> getcompilationunits() {
progresscallback.starttask(getstring("progress.17", //$non-nls-1$
introspectedtable.getfullyqualifiedtable().tostring()));
commentgenerator commentgenerator = context.getcommentgenerator();
fullyqualifiedjavatype type = new fullyqualifiedjavatype(
introspectedtable.getmybatis3javamappertype());
interface interfaze = new interface(type);
interfaze.setvisibility(javavisibility.public);
commentgenerator.addjavafilecomment(interfaze);
string rootinterface = introspectedtable
.gettableconfigurationproperty(propertyregistry.any_root_interface);
if (!stringhasvalue(rootinterface)) {
rootinterface = context.getjavaclientgeneratorconfiguration()
.getproperty(propertyregistry.any_root_interface);
}
if (stringhasvalue(rootinterface)) {
fullyqualifiedjavatype fqjt = new fullyqualifiedjavatype(
rootinterface);
interfaze.addsuperinterface(fqjt);
interfaze.addimportedtype(fqjt);
}
addinsertselectivemethod(interfaze);
adddeletebyprimarykeymethod(interfaze);
adddeletebyexamplemethod(interfaze);
addupdatebyprimarykeyselectivemethod(interfaze);
addupdatebyexampleselectivemethod(interfaze);
addselectbyprimarykeymethod(interfaze);
addselectonebyexamplemethod(interfaze); //由addselectbyexamplewithoutblobsmethod改造而来
addselectbyexamplewithoutblobsmethod(interfaze);
addselectbyexamplewithblobsmethod(interfaze);
addcountbyexamplemethod(interfaze);
//addinsertmethod(interfaze);
//addupdatebyexamplewithblobsmethod(interfaze);
//addupdatebyexamplewithoutblobsmethod(interfaze);
//addupdatebyprimarykeywithblobsmethod(interfaze);
//addupdatebyprimarykeywithoutblobsmethod(interfaze);
list<compilationunit> answer = new arraylist<>();
if (context.getplugins().clientgenerated(interfaze, null,
introspectedtable)) {
answer.add(interfaze);
}
list<compilationunit> extracompilationunits = getextracompilationunits();
if (extracompilationunits != null) {
answer.addall(extracompilationunits);
}
return answer;
}
//增加方法
protected void addselectonebyexamplemethod(interface interfaze) { abstractjavamappermethodgenerator methodgenerator = new selectonebyexamplemethodgenerator(); initializeandexecutegenerator(methodgenerator, interfaze); }
同样地,修改xmlmappergenerator
protected xmlelement getsqlmapelement() { fullyqualifiedtable table = introspectedtable.getfullyqualifiedtable(); progresscallback.starttask(getstring( "progress.12", table.tostring())); //$non-nls-1$ xmlelement answer = new xmlelement("mapper"); //$non-nls-1$ string namespace = introspectedtable.getmybatis3sqlmapnamespace(); answer.addattribute(new attribute("namespace", //$non-nls-1$ namespace)); context.getcommentgenerator().addrootcomment(answer); addresultmapwithoutblobselement(answer); addresultmapwithblobselement(answer); addexamplewhereclauseelement(answer); addmybatis3updatebyexamplewhereclauseelement(answer); addbasecolumnlistelement(answer); addblobcolumnlistelement(answer); addinsertselectiveelement(answer); adddeletebyprimarykeyelement(answer); adddeletebyexampleelement(answer); addupdatebyprimarykeyselectiveelement(answer); addupdatebyexampleselectiveelement(answer); addselectbyprimarykeyelement(answer); addselectonebyexampleelement(answer); addselectbyexamplewithoutblobselement(answer); addselectbyexamplewithblobselement(answer); addcountbyexampleelement(answer); //addselectbyexamplewithblobselement(answer); //addinsertelement(answer); //addupdatebyexamplewithblobselement(answer); //addupdatebyexamplewithoutblobselement(answer); //addupdatebyprimarykeywithblobselement(answer); //addupdatebyprimarykeywithoutblobselement(answer); return answer; }
//增加方法 protected void addselectonebyexampleelement(xmlelement parentelement) { if (introspectedtable.getrules().generateselectbyexamplewithoutblobs()) { abstractxmlelementgenerator elementgenerator = new selectonebyexampleelementgenerator(); initializeandexecutegenerator(elementgenerator, parentelement); } }
投入使用
deploy项目打包,然后在需要使用的项目中,修改pom.xml引入,再使用generator的generate命令即可
<plugin> <groupid>org.mybatis.generator</groupid> <artifactid>mybatis-generator-maven-plugin</artifactid> <version>1.3.7</version> <dependencies> <dependency> <groupid>com.mine.generator</groupid> <artifactid>mybatis-generator-core</artifactid> <version>1.0-snapshot</version> </dependency> </dependencies> </plugin>
下一篇: python学习day2