参考博文:
http://generator.sturgeon.mopaas.com/reference/extending.html
http://blog.csdn.net/wu6660563/article/details/52093364
http://www.blogjava.net/bolo/archive/2015/04/10/424271.html
下载下来generator-master.zip文件,解压开如下:
然后把mybatis-generator-core项目用idea打开,因为我用到了MySQL,所以在pom.xml文件中需要引入 mysql驱动,我用到的阿里源mybatis最新只有3.4.2,项目是最新3.5版本
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.9version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.2version>
dependency>
这块是核心的东西,我们真正需要改的东西。
需要修改类org.mybatis.generator.api.dom.OutputUtilities
public static void xmlIndent(StringBuilder sb, int indentLevel) {
for (int i = 0; i < indentLevel; i++) {
sb.append(" ").append(" "); //添加了2个空格
}
}
需要修改类org.mybatis.generator.api.dom.java.InnerClass
public String getFormattedContent(int indentLevel, CompilationUnit compilationUnit) {
...
sb.append(" {"); //$NON-NLS-1$
indentLevel++;
OutputUtilities.newLine(sb); // 这个是第一个属性与类声明之间的空行
Iterator fldIter = fields.iterator();
while (fldIter.hasNext()) {
OutputUtilities.newLine(sb);
Field field = fldIter.next();
sb.append(field.getFormattedContent(indentLevel, compilationUnit));
if (fldIter.hasNext()) {
OutputUtilities.newLine(sb); // 这个是属性之间的空行
}
}
......
}
需要修改类org.mybatis.generator.api.dom.java.InnerClass
public List getGeneratedXmlFiles() {
List answer = new ArrayList();
if (xmlMapperGenerator != null) {
Document document = xmlMapperGenerator.getDocument();
GeneratedXmlFile gxf = new GeneratedXmlFile(document,
getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(),
context.getSqlMapGeneratorConfiguration().getTargetProject(),
false, context.getXmlFormatter()); // 用来控制是否合并生成xml文件
if (context.getPlugins().sqlMapGenerated(gxf, this)) {
answer.add(gxf);
}
}
但我们将它改成false后,一定要在执行的命令行里加上overwrite参数,这样才能够让shellCallback.isOverwriteEnabled()生效,从而实现我们的xml文件覆盖生成。
相关的类org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl
一开始我的table配置很简单,
,一直出现多余的带Example后缀的类,于是乎我去改了代码,把ExampleGenerator返回null,(⊙﹏⊙)b
public List getGeneratedJavaFiles() {
List answer = new ArrayList();
/**
* 生成数据库映射实体类
*/
for (AbstractJavaGenerator javaGenerator : javaModelGenerators) {
List compilationUnits = javaGenerator
.getCompilationUnits();
if (compilationUnits == null) {
// ExampleGenerator 直接返回null
}else{
for (CompilationUnit compilationUnit : compilationUnits) {
GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,
context.getJavaModelGeneratorConfiguration()
.getTargetProject(),
context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
context.getJavaFormatter());
answer.add(gjf);
}
}
}
我按照菠萝大象在xml配置了
<table tableName="nami_user_and_web_site" enableCountByExample="false" enableDeleteByExample="false" enableUpdateByExample="false"
enableSelectByExample="false" selectByExampleQueryId="false">
table>
就OK了,xml中生成的一堆id=”xxxByExample”的东西也都没有了,世界清静多了
需要修改类org.mybatis.generator.internal.DefaultCommentGenerator
这个类是各种加注解的方法,
addComment xml文件注解
addJavaFileComment java文件注解
addClassComment 类注解
因为源码本身不加类注释的,所以在org.mybatis.generator.codegen.mybatis3.model.BaseRecordGenerator的64行添加
commentGenerator.addClassComment(topLevelClass,introspectedTable);
当然也学各位前辈加入了注解的字段,在实体类生成时,注解就是从数据库的注解拿来的信息,嘻嘻,这很好。
我们需要在FullyQualifiedTable实体类里面添加remarks字段,然后在类DatabaseIntrospector的calculateIntrospectedTables方法中添加
Statement stmt = null;
try {
stmt = databaseMetaData.getConnection().createStatement();
ResultSet rs = stmt.executeQuery("SHOW TABLE STATUS LIKE '" + atn.getTableName() + "'");
while (rs.next()) {
table.setRemarks(rs.getString("COMMENT"));
}
closeResultSet(rs);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
因为我的表名格式是:项目名_表名
所以在执行
String domainName = fullyQualifiedTable.getDomainObjectName()
的时候取出来是xxx_user这样的,我在类org.mybatis.generator.api.getDomainObjectName中修改
public String getDomainObjectName() {
if (stringHasValue(domainObjectName)) {
return domainObjectName;
} else if (stringHasValue(runtimeTableName)) {
return getCamelCaseStringByIronC(runtimeTableName, true);
} else {
return getCamelCaseStringByIronC(introspectedTableName, true);
}
}
这个getCamelCaseStringByIronC方法是在类org.mybatis.generator.internal.util.JavaBeansUtil中添加方法
public static String getCamelCaseStringByIronC(String inputString,
boolean firstCharacterUppercase) {
String substring = inputString.substring(inputString.indexOf("_")+1, inputString.length()); // 把表名中的项目名截掉
return getCamelCaseString(substring, firstCharacterUppercase);
}
当然这个可以在配置文件中配置
<table tableName="nami_tag" domainObjectName="tag" enableCountByExample="false" enableDeleteByExample="false" enableUpdateByExample="false"
enableSelectByExample="false" selectByExampleQueryId="false">
<columnOverride column="tag_status" jdbcType="TINYINT" javaType="java.lang.Integer"/>
table>
需要修改类
org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator和org.mybatis.generator.codegen.mybatis3.javamapper.JavaMapperGenerator
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);
// addSelectByExampleWithBLOBsElement(answer);
// addSelectByExampleWithoutBLOBsElement(answer);
addSelectByPrimaryKeyElement(answer);
addDeleteByPrimaryKeyElement(answer);
// addDeleteByExampleElement(answer);
addInsertElement(answer);
addInsertSelectiveElement(answer);
// addCountByExampleElement(answer);
// addUpdateByExampleSelectiveElement(answer);
// addUpdateByExampleWithBLOBsElement(answer);
// addUpdateByExampleWithoutBLOBsElement(answer);
addUpdateByPrimaryKeySelectiveElement(answer);
// addUpdateByPrimaryKeyWithBLOBsElement(answer);
// addUpdateByPrimaryKeyWithoutBLOBsElement(answer);
return answer;
}
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);
}
// addCountByExampleMethod(interfaze);
// addDeleteByExampleMethod(interfaze);
addDeleteByPrimaryKeyMethod(interfaze);
addInsertMethod(interfaze);
addInsertSelectiveMethod(interfaze);
// addSelectByExampleWithBLOBsMethod(interfaze);
// addSelectByExampleWithoutBLOBsMethod(interfaze);
addSelectByPrimaryKeyMethod(interfaze);
// addUpdateByExampleSelectiveMethod(interfaze);
// addUpdateByExampleWithBLOBsMethod(interfaze);
// addUpdateByExampleWithoutBLOBsMethod(interfaze);
addUpdateByPrimaryKeySelectiveMethod(interfaze);
// addUpdateByPrimaryKeyWithBLOBsMethod(interfaze);
// addUpdateByPrimaryKeyWithoutBLOBsMethod(interfaze);
List<CompilationUnit> answer = new ArrayList<CompilationUnit>();
if (context.getPlugins().clientGenerated(interfaze, null,
introspectedTable)) {
answer.add(interfaze);
}
List<CompilationUnit> extraCompilationUnits = getExtraCompilationUnits();
if (extraCompilationUnits != null) {
answer.addAll(extraCompilationUnits);
}
return answer;
}
上面提到了一些简单,实用的修改,整体上就是依葫芦画瓢,先做简单记录,目前我只是直接用测试类跑,生成代码后copy到自己项目需要的路径下。
代码