如果你想在mybatis generator 自动生成mapper xml model等的时候,调整生成java的数据库类型(数据类型转换)、生成分页语句、or连接的多列模糊查询、含中文特殊字符处理。末尾有源码的地址和jar.
准备工作
下载源码:https://github.com/mybatis/generator
其中,mybatis-generator-core目录 是该项目的源码,主要修改这里。
注:本例是对mybatis-generator-core1.4.1的扩展,其他版本修改过程类似。
目录如下:
修改 mybatis-generator 中数据库类型和 Java 类型的映射关系
本例是将原本数据库的TIMESTAMP 映射为 Date 类型, 改为 数据库的TIMESTAMP 映射为 LocalDateTime类型。
注: 仅为示例,其他类型修改类似。 mybatis generator 本身可直接将TIMESTAMP映射为LocalDateTime。具体使用方法请参考http://mybatis.org/generator/configreference/javaTypeResolver.html
修改文件位置为src\main\java\org\mybatis\generator\internal\types\JavaTypeResolverDefaultImpl.java
// typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP", //$NON-NLS-1$
// new FullyQualifiedJavaType(Date.class.getName())));
typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP", //$NON-NLS-1$
new FullyQualifiedJavaType(LocalDateTime.class.getName())));
这样就会将数据库的TIMESTAMP映射为java的LocalDateTime。
增加物理分页
适用于targetRuntime=“MyBatis3”
增加代码位置
src\main\java\org\mybatis\generator\codegen\mybatis3\xmlmapper\elements\SelectByExampleWithBLOBsElementGenerator.java
和 src\main\java\org\mybatis\generator\codegen\mybatis3\xmlmapper\elements\SelectByExampleWithoutBLOBsElementGenerator.java
ifElement = new XmlElement("if"); //$NON-NLS-1$
ifElement.addAttribute(new Attribute("test", "limitStart >= 0 and limitEnd > 0")); //$NON-NLS-1$ //$NON-NLS-2$
ifElement.addElement(new TextElement("limit ${limitStart},${limitEnd}")); //$NON-NLS-1$
answer.addElement(ifElement);
生成效果
增加“or连接的多列模糊查询”getMultiseriateOrLike和“and连接的多列模糊查询”getMultiseriateAndLike
增加代码位置src\main\java\org\mybatis\generator\codegen\mybatis3\model\ExampleGenerator.java
找到getSetNotLikeMethod
方法,在起下面或上面增加getMultiseriateOrLike方法和getMultiseriateAndLike,代码如下
getMultiseriateAndLike
// Generate the multiseriateAndLike() method
private Method getMultiseriateAndLike() {
// Set method name
StringBuilder sb = new StringBuilder();
sb.append("andMultiseriateAndLike");
Method method = new Method(sb.toString());
// Sets the access level of the method
method.setVisibility(JavaVisibility.PUBLIC);
// Sets the method's parameters, which are of type hashMap and named map
method.addParameter(
new Parameter(new FullyQualifiedJavaType("java.util.HashMap<String, String>"), "map")); //$NON-NLS-1$
// Sets the return type of the method
method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
// clear sb;
sb.setLength(0);
method.addBodyLine("if(map.isEmpty()) return (Criteria) this;");
method.addBodyLine("StringBuilder sb = new StringBuilder();");
method.addBodyLine("sb.append(\"(\");");
method.addBodyLine("java.util.Set<String> keySet = map.keySet();");
method.addBodyLine("for (String str : keySet) {");
method.addBodyLine("sb.append(\" and \"+str+\" like '%%\"+map.get(str)+\"%%'\");");
method.addBodyLine("}");
method.addBodyLine("sb.append(\")\");");
method.addBodyLine("int index = sb.indexOf(\"and\");");
method.addBodyLine("sb.delete(index, index+3);");
method.addBodyLine("addCriterion(sb.toString());");
method.addBodyLine("return (Criteria) this;");
return method;
}
getMultiseriateOrLike
// Generate the multiseriateOrLike() method
private Method getMultiseriateOrLike() {
// Set method name
StringBuilder sb = new StringBuilder();
sb.append("andMultiseriateOrLike");
Method method = new Method(sb.toString());
// Sets the access level of the method
method.setVisibility(JavaVisibility.PUBLIC);
// Sets the method's parameters, which are of type hashMap and named map
method.addParameter(
new Parameter(new FullyQualifiedJavaType("java.util.HashMap<String, String>"), "map")); //$NON-NLS-1$
// Sets the return type of the method
method.setReturnType(FullyQualifiedJavaType.getCriteriaInstance());
// clear sb;
sb.setLength(0);
method.addBodyLine("if(map.isEmpty()) return (Criteria) this;");
method.addBodyLine("StringBuilder sb = new StringBuilder();");
method.addBodyLine("sb.append(\"(\");");
method.addBodyLine("java.util.Set<String> keySet = map.keySet();");
method.addBodyLine("for (String str : keySet) {");
method.addBodyLine("sb.append(\" or \"+str+\" like '%%\"+map.get(str)+\"%%'\");");
method.addBodyLine("}");
method.addBodyLine("sb.append(\")\");");
method.addBodyLine("int index = sb.indexOf(\"or\");");
method.addBodyLine("sb.delete(index, index+2);");
method.addBodyLine("addCriterion(sb.toString());");
method.addBodyLine("return (Criteria) this;");
return method;
}
修改getGeneratedCriteriaInnerClass方法内代码
找到getGeneratedCriteriaInnerClass
代码位置,在方法return anwer;
之前加入以下代码
answer.addMethod(getMultiseriateOrLike());
answer.addMethod(getMultiseriateAndLike());
效果
example文件将会增加一个andMultiseriateAndLike() 方法和andMultiseriateOrLike()方法。
使用
andMultiseriateAndLike() 方法和andMultiseriateOrLike()方法
接收一个HashMap
使用此方法与使用example其他方法一样:
TestgenExample example = new TestgenExample();
TestgenExample.Criteria criteria = example.createCriteria();
HashMap<String, String> map = new HashMap<>();
Field[] fileds = filter.getClass().getDeclaredFields();
map.put("col1", "h");
map.put("col2", "a");
criteria.andMultiseriateAndLike(map);
mapper.selectByExample(example)
增加中文字段特殊字符转化
特殊字符替换,中文转拼音首字母大写,重复加“_”
先增加标记数据库对象名的符号
beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号;
增加处理中文字段特殊字符转化的标记
修改路径 src\main\java\org\mybatis\generator\config\PropertyRegistry.java
public static final String TABLE_USE_GG_COLUMN_NAMES = "useGGColumnNames"; //$NON-NLS-1$
增加ChineseCharToEn.java
在src\main\java\org\mybatis\generator\internal\util下增加ChineseCharToEn.java
package org.mybatis.generator.internal.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class ChineseCharToEn {
/**
* 汉字转拼音缩写
*
* @param str 要转换的汉字字符串
* @return String 拼音缩写
*/
public static String getPYString(String str) {
String tempStr = "";
str = matchCheck(str);
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c >= 33 && c <= 126) {// 字母和符号原样保留
tempStr += String.valueOf(c);
} else {// 累加拼音声母
tempStr += getPYChar(String.valueOf(c));
}
}
return tempStr;
}
/**
* 取单个字符的拼音声母
*
* @param c //要转换的单个汉字
* @return String 拼音声母
*/
public static String getPYChar(String c) {
byte[] array = new byte[2];
array = String.valueOf(c).getBytes();
int i = (short) (array[0] - '\0' + 256) * 256 + ((short) (array[1] - '\0' + 256));
if (i < 0xB0A1)
return "_";
if (i < 0xB0C5)
return "A";
if (i < 0xB2C1)
return "B";
if (i < 0xB4EE)
return "C";
if (i < 0xB6EA)
return "D";
if (i < 0xB7A2)
return "E";
if (i < 0xB8C1)
return "F";
if (i < 0xB9FE)
return "G";
if (i < 0xBBF7)
return "H";
if (i < 0xBFA6)
return "J";
if (i < 0xC0AC)
return "K";
if (i < 0xC2E8)
return "L";
if (i < 0xC4C3)
return "M";
if (i < 0xC5B6)
return "N";
if (i < 0xC5BE)
return "O";
if (i < 0xC6DA)
return "P";
if (i < 0xC8BB)
return "Q";
if (i < 0xC8F6)
return "R";
if (i < 0xCBFA)
return "S";
if (i < 0xCDDA)
return "T";
if (i < 0xCEF4)
return "W";
if (i < 0xD1B9)
return "X";
if (i < 0xD4D1)
return "Y";
if (i < 0xD7FA)
return "Z";
return "_";
}
public static String matchCheck(String a) {
// 正则表达式
// String regEx =
// "[\n`~!@#$%^&*()+=\\-|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。, 、?]";
Pattern pattern = Pattern.compile("[^\\x{4e00}-\\x{9fa5}a-zA-Z0-9_]");
Matcher matcher = pattern.matcher(a);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(buffer, "");
}
// 合法部分添加到缓冲区
matcher.appendTail(buffer);
return buffer.toString();
}
}
修改src\main\java\org\mybatis\generator\internal\db\DatabaseIntrospector.java
增加calculateExtraColumnInformationProcessingDuplicateValues方法
在calculateExtraColumnInformation方法下方增加calculateExtraColumnInformationProcessingDuplicateValues方法
private void calculateExtraColumnInformationProcessingDuplicateValues(String introspectedColumnJavaProperty,
Map.Entry<ActualTableName, List<IntrospectedColumn>> entry) {
int count = 0;
for (IntrospectedColumn introspectedColumn : entry.getValue()) {
if (introspectedColumn.getJavaProperty().equals(introspectedColumnJavaProperty)) {
count++;
if (count > 1) {
introspectedColumn.setJavaProperty(introspectedColumnJavaProperty + "_");
calculateExtraColumnInformationProcessingDuplicateValues(introspectedColumnJavaProperty + "_",
entry);
}
}
}
}
修改calculateExtraColumnInformation方法
else if (isTrue(tc.getProperty(PropertyRegistry.TABLE_USE_GG_COLUMN_NAMES))) {
introspectedColumn.setJavaProperty(ChineseCharToEn.getPYString(calculatedColumnName));
introspectedColumn.setColumnNameDelimited(true);
}
for (IntrospectedColumn introspectedColumn : entry.getValue()) {
calculateExtraColumnInformationProcessingDuplicateValues(introspectedColumn.getJavaProperty(), entry);
}
使用
效果
使用前
使用后
mvn打包
修改pom.xml
打包
mvn clean install
或
mvn package
使用
使用jar包
mysql-connector-java-8.0.19.jar 下载地址
刚刚生成好的mybatis-generator-core-1.4.1-GG2.jar 下载地址
generatorConfig.xml
详细写法请参考http://mybatis.org/generator/configreference/xmlconfig.html
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<classPathEntry location="mysql-connector-java-8.0.19.jar" />
<context id="MySql" defaultModelType="flat" targetRuntime="MyBatis3">
<property name="mergeable" value="false"></property>
<property name="beginningDelimiter" value="`" /><!-- 增加标记` -->
<property name="endingDelimiter" value="`" />
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/gen-test?characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true" userId="root" password="123456">
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<javaModelGenerator targetPackage="com.gen.springbootserver.mybatis.model" targetProject="../src/main/java"></javaModelGenerator>
<sqlMapGenerator targetPackage="mapper" targetProject="../src/main/resources"></sqlMapGenerator>
<javaClientGenerator targetPackage="com.gen.springbootserver.mybatis.dao" targetProject="../src/main/java" type="XMLMAPPER"></javaClientGenerator>
<table tableName="testgen" domainObjectName="Testgen">
<property name="modelOnly" value="false"/>
<property name="useGGColumnNames" value="true" /><!-- 中文字段转首字母大写,特殊字符替换 -->
<generatedKey column="id" sqlStatement="Mysql" identity="true"/> <!-- 插入或修改返回主键 -->
</table>
</context>
</generatorConfiguration>
执行命令
进入目标文件目录,cmd执行
java -jar mybatis-generator-core-1.4.1-GG.jar -configfile generatorConfig.xml -overwrite
源码下载地址