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. 记Oracle中regexp_substr的一次调优(速度提高95.5%)

    项目中需要做一个船舶代理费的功能,针对代理的船进行收费,那么该功能的第一步便是选择进行代理费用信息的录入,在进行船舶选择的时候,发现加载相关船舶信息十分的慢,其主要在sql语句的执行,因为测试的时候数 ...

  2. spring线程池的应用

    加载xml文件 在ApplicationContext.xml文件里面添加 xmlns:task="http://www.springframework.org/schema/task&qu ...

  3. 创建加载bean的实例

    一.创建实例 工程的结构如下图 1.创建接口 public interface Person { public void setName(String name); public String say ...

  4. Open with Sublime 右键打开

    Open with Sublime Sublime 的右键打开没有了,可以使用下面的bat命令添加.   @echo off SET st3Path=D:\Program Files\Sublime ...

  5. CMU Database Systems - Indexes

    这章主要描述索引,即通过什么样的数据结构可以更加快速的查询到数据 介绍Hash Tables,B+tree,SkipList 以及索引的并行访问 Hash Tables hash tables可以实现 ...

  6. 蓝牙BLE: GATT Profile 简介(GATT 与 GAP)

    一. 引言 现在低功耗蓝牙(BLE)连接都是建立在 GATT (Generic Attribute Profile) 协议之上.GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范,这些很 ...

  7. 阿里云 商标 SAAS

    商标注册-注册商标查询-商标交易平台-阿里云商标https://tm.aliyun.com/#/ 阿里云商标查询入口-云栖社区-阿里云https://yq.aliyun.com/articles/69 ...

  8. 使用TFA启动需要知道哪些概念?

    1. Boot stage BL1,BL2,BL31,BL32,BL33 2. Exception level EL3, EL1S, EL2 3. 那么放在表格里比较一下咯 Boot stage Ex ...

  9. C++ STL中常见容器的时间复杂度和比较和分析

    C++ STL中常见容器的时间复杂度 map, set, multimap, and multiset 上述四种容器采用红黑树实现,红黑树是平衡二叉树的一种.不同操作的时间复杂度近似为: 插入: O( ...

  10. 如何设置pycharm中使用的环境为本地的环境,而不用重新安装包

    Pycharm的两种环境配置 1.新建一个虚拟环境 一开始使用pycharm创建project的时候,点击创建 create new project: 然后就会弹出下面的窗口,如果我们选择的是上面的选 ...