MyBatis逆向工程生成

mybatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对单表自动生成mybatis执行所需要的代码(mapper.java、mapper.xml、pojo…),可以让程序员将更多的精力放在繁杂的业务逻辑上。

企业实际开发中,常用的逆向工程方式:由数据库的表生成java代码。

​ 之所以强调单表两个字,是因为Mybatis逆向工程生成的Mapper所进行的操作都是针对单表的,也许你可能会觉得那这就有点鸡肋了,但是在大型项目中,很少有复杂的多表关联查询,所以作用还是很大的。

介绍

MyBatis生成器(MBG)是MyBatis MyBatisiBATIS的代码生成器。它将为MyBatis的所有版本以及版本2.2.0之后的iBATIS生成代码。它将内省一个数据库表(或多个表),并将生成可用于访问表的工件。这减轻了设置对象和配置文件以与数据库表进行交互的麻烦。MBG试图对简单CRUD(创建,检索,更新,删除)的大部分数据库操作产生重大影响。您仍将需要手工编写SQL和对象代码以进行联接查询或存储过程。

官方仓库 官方文档

开始上代码

目录总体结构:

主要文件

pom依赖

 		<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency> <!--逆向工程生成-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
</dependency> <dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>

分页配置类

MySQLLimitPlugin.java

package com.meng.device.util;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.GeneratedXmlFile;
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.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.XmlConstants;
import org.mybatis.generator.config.PropertyRegistry; import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer; /**
* Created by meng
*/
public class MySQLLimitPlugin extends PluginAdapter { private static String XMLFILE_POSTFIX = "Ext"; private static String JAVAFILE_POTFIX = "Ext"; private static String ANNOTATION_RESOURCE = "javax.annotation.Resource"; @Override
public boolean validate(List<String> list) {
return true;
} /**
* 为每个Example类添加limit和offset属性已经set、get方法
*/
@Override
public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType.getIntInstance().getPrimitiveTypeWrapper(); Field limit = new Field();
limit.setName("limit");
limit.setVisibility(JavaVisibility.PRIVATE);
limit.setType(integerWrapper);
topLevelClass.addField(limit); Method setLimit = new Method();
setLimit.setVisibility(JavaVisibility.PUBLIC);
setLimit.setName("setLimit");
setLimit.addParameter(new Parameter(integerWrapper, "limit"));
setLimit.addBodyLine("this.limit = limit;");
topLevelClass.addMethod(setLimit); Method getLimit = new Method();
getLimit.setVisibility(JavaVisibility.PUBLIC);
getLimit.setReturnType(integerWrapper);
getLimit.setName("getLimit");
getLimit.addBodyLine("return limit;");
topLevelClass.addMethod(getLimit); Field offset = new Field();
offset.setName("offset");
offset.setVisibility(JavaVisibility.PRIVATE);
offset.setType(integerWrapper);
topLevelClass.addField(offset); Method setOffset = new Method();
setOffset.setVisibility(JavaVisibility.PUBLIC);
setOffset.setName("setOffset");
setOffset.addParameter(new Parameter(integerWrapper, "offset"));
setOffset.addBodyLine("this.offset = offset;");
topLevelClass.addMethod(setOffset); Method getOffset = new Method();
getOffset.setVisibility(JavaVisibility.PUBLIC);
getOffset.setReturnType(integerWrapper);
getOffset.setName("getOffset");
getOffset.addBodyLine("return offset;");
topLevelClass.addMethod(getOffset); return true;
} // 添删改Document的sql语句及属性
@Override
public boolean sqlMapDocumentGenerated(Document document,
IntrospectedTable introspectedTable) { XmlElement parentElement = document.getRootElement(); // updateDocumentNameSpace(introspectedTable, parentElement); // moveDocumentInsertSql(parentElement);
//
// updateDocumentInsertSelective(parentElement);
//
// moveDocumentUpdateByPrimaryKeySql(parentElement);
//
// generateMysqlPageSql(parentElement, introspectedTable);
//
// generateDataAccessSql(parentElement); return super.sqlMapDocumentGenerated(document, introspectedTable);
} private void updateDocumentNameSpace(IntrospectedTable introspectedTable,
XmlElement parentElement) {
Attribute namespaceAttribute = null;
for (Attribute attribute : parentElement.getAttributes()) {
if (attribute.getName().equals("namespace")) {
namespaceAttribute = attribute;
}
}
parentElement.getAttributes().remove(namespaceAttribute);
parentElement.getAttributes().add(
new Attribute("namespace", introspectedTable
.getMyBatis3JavaMapperType() + JAVAFILE_POTFIX));
} /**
* 为Mapper.xml的selectByExample添加limit
*/
@Override
public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element,
IntrospectedTable introspectedTable) { XmlElement ifLimitNotNullElement = new XmlElement("if");
ifLimitNotNullElement.addAttribute(new Attribute("test", "limit != null")); XmlElement ifOffsetNotNullElement = new XmlElement("if");
ifOffsetNotNullElement.addAttribute(new Attribute("test", "offset != null"));
ifOffsetNotNullElement.addElement(new TextElement("limit ${offset}, ${limit}"));
ifLimitNotNullElement.addElement(ifOffsetNotNullElement); XmlElement ifOffsetNullElement = new XmlElement("if");
ifOffsetNullElement.addAttribute(new Attribute("test", "offset == null"));
ifOffsetNullElement.addElement(new TextElement("limit ${limit}"));
ifLimitNotNullElement.addElement(ifOffsetNullElement); element.addElement(ifLimitNotNullElement); return true;
} // 生成XXExt.xml
@Override
public List<GeneratedXmlFile> contextGenerateAdditionalXmlFiles(
IntrospectedTable introspectedTable) { String[] splitFile = introspectedTable.getMyBatis3XmlMapperFileName()
.split("\\.");
String fileNameExt = null;
if (splitFile[0] != null) {
fileNameExt = splitFile[0] + XMLFILE_POSTFIX + ".xml";
} if (isExistExtFile(context.getSqlMapGeneratorConfiguration()
.getTargetProject(),
introspectedTable.getMyBatis3XmlMapperPackage(), fileNameExt)) {
return super.contextGenerateAdditionalXmlFiles(introspectedTable);
} Document document = new Document(
XmlConstants.MYBATIS3_MAPPER_PUBLIC_ID,
XmlConstants.MYBATIS3_MAPPER_SYSTEM_ID); XmlElement root = new XmlElement("mapper");
document.setRootElement(root);
String namespace = introspectedTable.getMyBatis3SqlMapNamespace()
+ XMLFILE_POSTFIX;
root.addAttribute(new Attribute("namespace", namespace)); GeneratedXmlFile gxf = new GeneratedXmlFile(document, fileNameExt,
introspectedTable.getMyBatis3XmlMapperPackage(), context
.getSqlMapGeneratorConfiguration().getTargetProject(),
false, context.getXmlFormatter()); List<GeneratedXmlFile> answer = new ArrayList<GeneratedXmlFile>(1);
answer.add(gxf); return answer;
} // 生成XXExt.java
@Override
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(
IntrospectedTable introspectedTable) { FullyQualifiedJavaType type = new FullyQualifiedJavaType(
introspectedTable.getMyBatis3JavaMapperType() + JAVAFILE_POTFIX);
Interface interfaze = new Interface(type);
interfaze.setVisibility(JavaVisibility.PUBLIC);
context.getCommentGenerator().addJavaFileComment(interfaze); FullyQualifiedJavaType baseInterfaze = new FullyQualifiedJavaType(
introspectedTable.getMyBatis3JavaMapperType());
interfaze.addSuperInterface(baseInterfaze); FullyQualifiedJavaType annotation = new FullyQualifiedJavaType(
ANNOTATION_RESOURCE);
interfaze.addAnnotation("@Resource");
interfaze.addImportedType(annotation); CompilationUnit compilationUnits = interfaze;
GeneratedJavaFile generatedJavaFile = new GeneratedJavaFile(
compilationUnits,
context.getJavaModelGeneratorConfiguration().getTargetProject(),
context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
context.getJavaFormatter()); if (isExistExtFile(generatedJavaFile.getTargetProject(),
generatedJavaFile.getTargetPackage(),
generatedJavaFile.getFileName())) {
return super.contextGenerateAdditionalJavaFiles(introspectedTable);
}
List<GeneratedJavaFile> generatedJavaFiles = new ArrayList<GeneratedJavaFile>(
1);
generatedJavaFile.getFileName();
generatedJavaFiles.add(generatedJavaFile);
return generatedJavaFiles;
} private boolean isExistExtFile(String targetProject, String targetPackage,
String fileName) { File project = new File(targetProject);
if (!project.isDirectory()) {
return true;
} StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(targetPackage, ".");
while (st.hasMoreTokens()) {
sb.append(st.nextToken());
sb.append(File.separatorChar);
} File directory = new File(project, sb.toString());
if (!directory.isDirectory()) {
boolean rc = directory.mkdirs();
if (!rc) {
return true;
}
} File testFile = new File(directory, fileName);
if (testFile.exists()) {
return true;
} else {
return false;
}
}
}

主要配置 映射哪些表也是在这个里面配置(每次只需要修改这个)

generatorConfig_local.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>
<!--<classPathEntry location="C:/Project/DB/mysql-connector-java-5.1.40-bin.jar"/>-->
<context id="base_resource" targetRuntime="MyBatis3"> <property name="useActualColumnNames" value="false"/> <plugin type="com.meng.device.util.MySQLLimitPlugin"/> <commentGenerator>
<property name="suppressDate" value="true"/>
</commentGenerator> <jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/springboot?useUnicode=true&amp;characterEncoding=UTF-8"
userId="root"
password="root">
</jdbcConnection> <!-- targetProject:生成PO类的位置 根据自己项目位置更改 -->
<javaModelGenerator targetPackage="com.meng.device.dao"
targetProject="E:\project\IdeaProjects\device\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="true"/>
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 根据自己项目位置更改-->
<sqlMapGenerator targetPackage="com.meng.device.mapper"
targetProject="E:\project\IdeaProjects\device\src\main\resources">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator> <!-- targetPackage:mapper接口生成的位置 根据自己项目位置更改-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.meng.device.mapper"
targetProject="E:\project\IdeaProjects\device\src\main\java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="true"/>
</javaClientGenerator> <!-- 指定数据库表 -->
<!--映射表名 多个表可以写多个-->
<!--<table tableName="表名" domainObjectName="实体名">
<property name="useActualColumnNames" value="false"/>
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>--> <!-- 有些表的字段需要指定java类型 <table schema=""tableName=""> <columnOverridecolumn="" javaType="" /> </table> --> </context>
</generatorConfiguration>

启动类

Generator.java

package com.meng.device.generator;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback; import java.util.ArrayList;
import java.util.List; /**
* @description: mybatis逆向工程 自动生成mybatis-Mapper工具
* @author: meng
* @create: 2019-09-11 08:58
**/
public class Generator { /**
* 目前在系统中本地环境使用local来配置mapper生成规则
*/
//指定逆向工程配置文件
private static final String config_url = "generatorConfig_local.xml"; public void generator() throws Exception {
List<String> warnings = new ArrayList<String>();
ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(Generator.class.getClassLoader().getResourceAsStream(config_url)); DefaultShellCallback callback = new DefaultShellCallback(true);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
} /**
* 主函数
*/
public static void main(String[] args) throws Exception {
try {
Generator generatorSqlmap = new Generator();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("generator 执行成功!");
} }

配置完成后执行Generator类中主函数

MyBatis逆向工程生成配置 generator (生成pojo、mapper.xml、mapper.java)的更多相关文章

  1. spring mybatis 整合问题Error parsing Mapper XML. Cause: java.lang.NullPointerException

    14:30:40,872 DEBUG SqlSessionFactoryBean:431 - Parsed configuration file: 'class path resource [myba ...

  2. Spring 与 mybatis整合 Error parsing Mapper XML. Cause: java.lang.NullPointerException

    mapper配置文件中的namespace没有填:而且namespase的值应该填为:mapper的权限定名:否则还是会抛出异常 org.springframework.beans.factory.B ...

  3. nested exception is java.lang.RuntimeException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Result Maps collection already contains value for

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'daoSupport': ...

  4. MyBatis逆向工程:根据table生成Model、Mapper、Mapper.xml

    逆向工程工具 下载地址:https://download.csdn.net/download/zhutouaizhuwxd/10779140 1.工程导入Eclipse  2.运行MainUI.jav ...

  5. mybatis逆向工程之配置

    逆向工程1.什么是逆向工程mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml. ...

  6. Mybatis逆向工程的配置

    源码github下载地址:https://github.com/wcyong/mybatisGeneratorCustom.git 参考文章:https://www.cnblogs.com/whgk/ ...

  7. Spring Boot整合tk.mybatis及pageHelper分页插件及mybatis逆向工程

    Spring Boot整合druid数据源 1)引入依赖 <dependency> <groupId>com.alibaba</groupId> <artif ...

  8. mybatis逆向工程自动生成实体类、接口以及映射Mapper.xml配置文件

    Mybatis的逆向工程非常简单,只要一个配置文件和一个Main方法就可以实现,下面以maven工程为例: (1)在pom.xml中引入依赖包 <dependency> <group ...

  9. 回顾一下MyBatis逆向工程——自动生成代码

    前言 最近做的项目(SSM+Shiro)的数据库表已经创建完成,一共有15张表,如果我们一个个去写pojo/bean的代码以及各种sql语句的话未免太过麻烦而且很容易出错,这个时候我们就需要MyBat ...

随机推荐

  1. [WEB安全]SSRF中URL的伪协议

    当我们发现SSRF漏洞后,首先要做的事情就是测试所有可用的URL伪协议 0x01 类型 file:/// dict:// sftp:// ldap:// tftp:// gopher:// file: ...

  2. WAMP本地环境升级php版本操作步骤(详细)

    php版本下载地址:http://windows.php.net/download/ 步骤:下载php版本-解压文件-放到bin/php目录下-更改文件 图片教程: 更改文件内容: 1.从已存在的ph ...

  3. zabbix监控线

    echo mntr | nc 127.0.0.1 2181获取mntr的信息 换成conf将获得conf信息,从中找出需要监控项 conf: clientPort:客户端端口号 dataDir:数据文 ...

  4. LeetCode 第 154 场周赛

    一."气球" 的最大数量(LeetCode-5189) 1.1 题目描述 1.2 解题思路 统计各个字母的出现的次数,然后根据"木桶最短板"返回就好. 1.3 ...

  5. Spring boot MyBatis基本操作

    XML 配置方式 目录结构 数据库信息: 数据库student -> 表名 custom_user  -> 主键-> custom_id ,其他字段 cusotm_name,cust ...

  6. IDEA_2019.2的安装与个人配置(Windows)

    1. 下载 官方下载网站:https://www.jetbrains.com/idea/download/ IDEA是支持多平台的开发工具,分为Windows.Mac和Linux三个平台,这里就只拿W ...

  7. 深度学习面试题10:二维卷积(Full卷积、Same卷积、Valid卷积、带深度的二维卷积)

    目录 二维Full卷积 二维Same卷积 二维Valid卷积 三种卷积类型的关系 具备深度的二维卷积 具备深度的张量与多个卷积核的卷积 参考资料 二维卷积的原理和一维卷积类似,也有full卷积.sam ...

  8. 7年.NET面试Java的尴尬历程

    先简单介绍LZ 现如今的情况,LZ 1992年出生,2012年实习,大专学渣一枚,实习期直接被校企合作直招到公司做.NET开发,现如今在某三线城市做后端技术经理,7年开发经验(5年.Net,2年.NE ...

  9. EditText限制输入的几种方式及只显示中文汉字的做法

    最近项目要求限制密码输入的字符类型, 例如不能输入中文.   现在总结一下EditText的各种实现方式,  以比较各种方法的优劣. 第一种方式:  设置EditText的inputType属性,可以 ...

  10. Oracle insert大量数据经验之谈

    在很多时候,我们会需要对一个表进行插入大量的数据,并且希望在尽可能短的时间内完成该工作,这里,和大家分享下我平时在做大量数据insert的一些经验. 前提:在做insert数据之前,如果是非生产环境, ...