前言: 使用Mybatis Generator自动生成
实体类和 mapper
数据库操作类
目录结构
使用过程
- maven引入jar包
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
<optional>true</optional>
</dependency>
- 增加配置文件
generatorConfig.xml
示例如下:
<?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>
<context id="entmobile" targetRuntime="MyBatis3">
<plugin type="com.itzhongzi.usernapp.plugins.AddLimitOffsetPlugin" />
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<commentGenerator>
<property name="suppressDate" value="true" />
<!-- remove comments -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://114.115.250.129:3306/coupun_shop?useUnicode=true&characterEncoding=UTF-8&useSSL=false"
userId="root" password="Huanghai@2019" />
<!-- java type resolver -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- gem entity -->
<!-- data -->
<javaModelGenerator targetPackage="com.itzhongzi.usernapp.domain"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="false" />
</javaModelGenerator>
<!-- -->
<!-- gem annotated mapper -->
<!-- data -->
<javaClientGenerator type="ANNOTATEDMAPPER"
targetPackage="com.itzhongzi.usernapp.mapper"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<table tableName="t_user">
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>
- 增加一个工具类
AddLimitOffsetPlugin.java
package com.itzhongzi.usernapp.plugins;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
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 java.util.List;
public class AddLimitOffsetPlugin extends PluginAdapter {
public boolean validate(List<String> warnings) {
return true;
}
public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
IntrospectedTable introspectedTable) {
FullyQualifiedJavaType offsetType = new FullyQualifiedJavaType(
"javax.annotation.Generated");
topLevelClass.addImportedType(offsetType);
topLevelClass.addAnnotation("@Generated(\"" + introspectedTable.getTableConfiguration().getTableName() + "\")");
PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper();
Field limit = new Field();
limit.setName("limit");
limit.setVisibility(JavaVisibility.PRIVATE);
limit.setType(integerWrapper);
topLevelClass.addField(limit);
Method limitSet = new Method();
limitSet.setVisibility(JavaVisibility.PUBLIC);
limitSet.setName("setLimit");
limitSet.addParameter(new Parameter(integerWrapper, "limit"));
limitSet.addBodyLine("this.limit = limit;");
topLevelClass.addMethod(limitSet);
Method limitGet = new Method();
limitGet.setVisibility(JavaVisibility.PUBLIC);
limitGet.setReturnType(integerWrapper);
limitGet.setName("getLimit");
limitGet.addBodyLine("return limit;");
topLevelClass.addMethod(limitGet);
Field offset = new Field();
offset.setName("offset");
offset.setVisibility(JavaVisibility.PRIVATE);
offset.setType(integerWrapper);
topLevelClass.addField(offset);
Method offsetSet = new Method();
offsetSet.setVisibility(JavaVisibility.PUBLIC);
offsetSet.setName("setOffset");
offsetSet.addParameter(new Parameter(integerWrapper, "offset"));
offsetSet.addBodyLine("this.offset = offset;");
topLevelClass.addMethod(offsetSet);
Method offsetGet = new Method();
offsetGet.setVisibility(JavaVisibility.PUBLIC);
offsetGet.setReturnType(integerWrapper);
offsetGet.setName("getOffset");
offsetGet.addBodyLine("return offset;");
topLevelClass.addMethod(offsetGet);
return true;
}
public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(
XmlElement element, IntrospectedTable introspectedTable) {
XmlElement isNotNullElement = new XmlElement("if");
isNotNullElement.addAttribute(new Attribute("test", "limit > 0"));
isNotNullElement.addElement(new TextElement("limit ${limit}"));
element.getElements().add(isNotNullElement);
isNotNullElement = new XmlElement("if");
isNotNullElement.addAttribute(new Attribute("test", "offset > 0"));
isNotNullElement.addElement(new TextElement("offset ${offset}"));
element.getElements().add(isNotNullElement);
return true;
}
}
- 增加一个启动类
Generator.java
示例如下: 启动generate
方法便可以在自己配置的目录生成 实体类 和 mapper类
package com.itzhongzi.usernapp.plugins;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.api.ProgressCallback;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* mybatis代码生成插件调用者.
*/
public class Generator {
@Test
public void generate() throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
InputStream stream = Generator.class.getClassLoader().getResourceAsStream("generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
InputStreamReader reader = new InputStreamReader(stream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(reader);
String line = bufferedReader.readLine();
StringBuffer buffer = new StringBuffer();
while (line != null) {
buffer.append(line + "\n");
line = bufferedReader.readLine();
}
String xmlWithParam = buffer.toString();
System.out.println("------- xml config begin -------");
System.out.println(xmlWithParam);
System.out.println("------- xml config end -------");
final Configuration config = cp.parseConfiguration(new ByteArrayInputStream(xmlWithParam.getBytes("utf-8")));
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
System.out.println("------- generator begin -------");
ProgressCallback cb = new ProgressCallback() {
private Pattern SqlProviderPattern = Pattern.compile("\\w*SqlProvider\\.java");
private List<String> taskNames = new ArrayList();
@Override
public void startTask(String taskName) {
/*
* 输出这些信息从而知道 生成那些类了
* Generating Example class for table demo
* Generating Primary Key class for table demo
* Generating Record class for table demo
* Generating Mapper Interface for table demo
* Generating SQL Provider for table demo
* Saving file DemoExample.java
* Saving file DemoKey.java Saving file Demo.java
* Saving file DemoMapper.java
* Saving file DemoSqlProvider.java
*/
// System.out.println(taskName);
taskNames.add( taskName);
}
@Override
public void saveStarted(int arg0) {}
@Override
public void introspectionStarted(int arg0) {}
@Override
public void generationStarted(int arg0) {}
@Override
public void done() {
for(String taskName : taskNames){
Matcher matcher = SqlProviderPattern.matcher(taskName);
if (matcher.find()) {
final String SqlProviderFilename = matcher.group();
System.out.println("处理生成文件,selectByExample 增加mysql分页: " + SqlProviderFilename);
List<Context> contexts = config.getContexts();
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return SqlProviderFilename.equalsIgnoreCase(name);
}
};
boolean done = false;
for (Context ctx : contexts) {
if(done){
break;
}
String targetProject = ctx.getJavaClientGeneratorConfiguration().getTargetProject();
String targetPackage = ctx.getJavaClientGeneratorConfiguration().getTargetPackage();
String dir = targetProject.replaceAll("\\.", "\\\\") + "\\" + targetPackage.replaceAll("\\.", "\\\\");
System.out.println(System.getProperty("user.dir") + dir);
File mapperDir = new File(System.getProperty("user.dir"), dir);
File[] files = mapperDir.listFiles(filter);
if (files != null && files.length > 0) {
File sqlProviderFile = files[0];
try {
Generator.addMysqlLimit(sqlProviderFile);
done = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
if(!done){
System.out.println("转换失败!!!! selectByExample 增加mysql分页: " + SqlProviderFilename);
} else {
System.out.println("转换成功!!!! selectByExample 增加mysql分页: " + SqlProviderFilename);
}
}
}
}
@Override
public void checkCancel() throws InterruptedException {}
};
myBatisGenerator.generate(cb);
for (String warning : warnings) {
System.out.println(warning);
}
System.out.println("------- generator end -------");
// System.out.println(config.getClassPathEntries());
}
private static void addMysqlLimit(File sqlProviderFile) throws Exception {
/*
* 这是自动生成的selectByExample 中的代码片段
if (example != null && example.getOrderByClause() != null) {
ORDER_BY(example.getOrderByClause()); // 整个文件唯一
}
return SQL();
* 将return SQL()改为下面片段即可:
String sqlString = SQL();
if (example != null && example.getLimit() != null) {
sqlString += " limit " + example.getLimit();
}
if (example != null && example.getOffset() != null) {
sqlString += " offset " + example.getOffset();
}
return sqlString;
*/
BufferedReader reader = new BufferedReader( new FileReader(sqlProviderFile));
List<String> lines = IOUtils.readLines(reader);
reader.close();
String limitString = " String sqlString = SQL();\n" +
" if (example != null && example.getLimit() != null) {\n" +
" sqlString += \" limit \" + example.getLimit();\n" +
" }\n" +
" if (example != null && example.getOffset() != null) {\n" +
" sqlString += \" offset \" + example.getOffset();\n" +
" }\n" +
" return sqlString;";
ArrayList<String> newLines = new ArrayList<String>();
for (int i=0; i< lines.size();++i) {
String line = lines.get(i);
newLines.add(line );
if(line.replaceAll(" ", "") .equalsIgnoreCase("ORDER_BY(example.getOrderByClause());")) {
// 添加下一行大括号和空白行
++i;
newLines.add(lines.get(i));
++i;
newLines.add(lines.get(i));
++i; // 跳过 return SQL();
newLines.addAll(Arrays.asList( limitString.split("\n")));
}
}
// for (String line : newLines) {
// System.out.println(line);
// }
FileOutputStream writer = new FileOutputStream(sqlProviderFile);
IOUtils.writeLines(newLines, "\n",writer,"UTF-8");
writer.close();
}
public static void main(String[] args) throws Exception {
new Generator().generate();
}
}