1 逆向工程的简介
Mybatis 的逆向工程就是由代码生成器生成我们需要的代码和映射文件。
注意,逆向工程时最好新开一个项目,否则可能出现相同文件名覆盖的情况。
官方文档:MyBatis Generator Core – Introduction to MyBatis Generator
2 逆向工程代码
2.1 导入 Maven 依赖和插件
<dependencies>
<!-- MyBatis核心依赖包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<!-- 控制Maven在构建过程中相关配置 -->
<build>
<!-- 构建过程中用到的插件 -->
<plugins>
<!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.0</version>
<!-- 插件的依赖 -->
<dependencies>
<!-- 逆向工程的核心依赖 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.2</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>2.2 导入 log4j 配置
略。
2.3 创建 MyBatis 配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
" http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties"/>
<typeAliases>
<package name=""/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name=""/>
</mappers>
</configuration>2.4 创建 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>
<!--
targetRuntime: 执行生成的逆向工程的版本
MyBatis3Simple: 生成基本的 CRUD(清新简洁版)
MyBatis3: 生成带条件的 CRUD(奢华尊享版)
-->
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释。true:是;false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 数据库的连接信息 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8"
userId="root"
password="root">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL和NUMERIC类型解析为Integer,为true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- javaBean的生成策略-->
<javaModelGenerator targetPackage="com.thr.pojo"
targetProject="./src/main/java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- SQL映射文件的生成策略 -->
<sqlMapGenerator targetPackage="com.thr.mapper"
targetProject="./src/main/resources">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- Mapper接口的生成策略 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.thr.mapper"
targetProject="./src/main/java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 逆向分析的表 -->
<!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
<!-- domainObjectName属性指定生成出来的实体类的类名 -->
<table tableName="t_emp" domainObjectName="Emp"/>
<table tableName="t_dept" domainObjectName="Dept"/>
<!-- 指定生成哪些数据库表,要和数据库中对应,不能写错了,这里以t_user表为例,可以写多个;domainObjectName是要生成的实体类名称-->
<table schema="mybatis" tableName="t_user"/>
<!-- 有些表的字段需要指定java类型
<table schema="" tableName="">
<columnOverride column="" javaType="" />
</table> -->
</context>
</generatorConfiguration>还有就是不同的数据库中不能含有相同的表,例如数据库 A 有 t_user 表,数据库 B 也有 t_user 表,那么到时候代码不知道生成哪个。
2.5 执行逆向——编码形式
逆向工程核心生成代码 GeneratorSql.java
package com.thr.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.io.File;
import java.util.ArrayList;
import java.util.List;
public class GeneratorSql {
public void generator() throws Exception {
List<String> warnings = new ArrayList<>();
boolean overwrite = true;
// 指定逆向工程配置文件
String file = GeneratorSql.class.getResource("/generatorConfig.xml").getFile();
File configFile = new File(file);
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
// 执行main方法以生成代码
public static void main(String[] args) {
try {
GeneratorSql generatorSql = new GeneratorSql();
generatorSql.generator();
} catch (Exception e) {
e.printStackTrace();
}
}
}运行上面的程序,如果控制台打印了如下日志,说明生成代码成功了。

2.6 执行逆向——插件

执行结果
3 逆向工程举例
首先我们将上面生成的文件复制到目标项目中。在使用逆向工程举例之前,先来介绍生成的文件有哪些东西:
3.1 TUserMapper 接口生成的方法介绍
long countByExample(TUserExample example):按条件计数int deleteByExample(TUserExample example):按条件删除int deleteByPrimaryKey(Integer id):按主键删除int insert(TUser record):插入数据(返回值为 ID),包含值为 null 的字段int insertSelective(TUser record):插入数据,只插入值不为 null 的字段,内部动态 sql 判断List<TUser> selectByExample(TUserExample example):按条件查询,传入 null 表示查询所有TUser selectByPrimaryKey(Integer id):按主键查询int updateByExampleSelective(@Param("record") TUser record, @Param("example") TUserExample example):按条件更新值不为 null 的字段int updateByExample(@Param("record") TUser record, @Param("example") TUserExample example):按条件更新int updateByPrimaryKeySelective(TUser record):按主键更新值不为 null 的字段,主键对应实体类属性不能为 null。int updateByPrimaryKey(TUser record):按主键更新
代码示例
List<TUser> tUsers = mapper.selectByExample(null);//传入null表示查询所有3.2 TUserExample 条件扩展类介绍
上面的测试方法是不带条件的操作,那么接下来学习一下按条件如何进行增删改查操作,我们在逆向工程中已经生成了这个类 TUserExample,这个类就是一个条件扩展类,里面定义了一系列方法用来做条件,比如:排序、去重、大于、小于、等于、模糊查询、数据在某某之间等等。
我们在 TUserExample 类中可以看到定义了一个内部类 GeneratedCriteria,这个内部类就定义了一系列条件的方法,这些条件最后都会拼接在 SQL 中,但是我们一般不用它,都用它的子类 Criteria 来进行操作,Criteria 继承了内部类 GeneratedCriteria。

需要学习的内容:
- criteria 是可以链式添加条件的
criteria.andUsernameLike("%三%").andAgeBetween(18,30); - or 操作的使用
example.or(criteria1)
example.or(criteria2)
example.or(criteria3)
其中 criteria1、criteria2、criteria3 分别代表一个链式的判断条件
代码示例
//模糊查询用户信息
@Test
public void selectUserLike(){
TUserExample example = new TUserExample();
TUserExample.Criteria criteria = example.createCriteria();
//模糊条件
criteria.andUsernameLike("%三%");
/*sql语句相当于:select id, username, age, birthday, sex, address from t_user WHERE ( username like ? )*/
List<TUser> tUsers = mapper.selectByExample(example);
}
//查询年龄在18-30岁之间的用户信息
@Test
public void selectUserBetween(){
TUserExample example = new TUserExample();
TUserExample.Criteria criteria = example.createCriteria();
//Between条件
criteria.andAgeBetween(18,30);
example.or(criteria);
example.setDistinct(true);
/*sql语句相当于:select distinct id, username, age, birthday, sex, address
from t_user WHERE ( age between ? and ? ) or( age between ? and ? )*/
List<TUser> tUsers = mapper.selectByExample(example);
for (TUser tUser : tUsers) {
System.out.println(tUser);
}
}
//查询用户名A或B
@Test
public void selectUserOr(){
TUserExample example = new TUserExample();
TUserExample.Criteria criteria1 = example.createCriteria();
criteria1.andUsernameEqualTo("黄飞鸿");
TUserExample.Criteria criteria2 = example.createCriteria();
criteria2.andUsernameEqualTo("马保国");
//将criteria2条件拼接在 or 关键字字后面
example.or(criteria2);
/*sql语句相当于:select id, username, age, birthday, sex, address
from t_user WHERE ( username = ? ) or( username = ? )*/
List<TUser> tUsers = mapper.selectByExample(example);
for (TUser tUser : tUsers) {
System.out.println(tUser);
}
}
//根据用户名删除用户
@Test
public void deleteUserExample(){
TUserExample example = new TUserExample();
TUserExample.Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo("凡尔赛");
//sql语句相当于:delete from t_user WHERE ( username = ? )
int i = mapper.deleteByExample(example);
System.out.println(i>0?"删除成功":"删除失败");
}4 树
- java. Lang.Object
- tk. Mybatis. Mapper. Entity.Example
- tk. Mybatis. Mapper. Entity.Condition
- tk. Mybatis. Mapper. Entity.Example. Criterion
- tk. Mybatis. Mapper. Entity.Example. GeneratedCriteria
- tk. Mybatis. Mapper. Entity.Example. Criteria
- tk. Mybatis. Mapper. Entity.Example