文章目录
一、概述
①、简介
MyBatis-Plus (简称 MP
)是一个 MyBatis 的增强工具,在 MyBatis
的基础上只做增强不做改变,为简化开发、提高效率而生
②、特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本
CURD
,性能基本无损耗,直接面向对象操作 - 强大的 CRUD 操作:内置通用
Mapper
、通用Service
,仅仅通过少量配置即可实现单表大部分CRUD
操作,更有强大的条件构造器,满足各类使用需求 - 支持 Lambda 形式调用:通过
Lambda
表达式,方便的编写各类查询条件,无需再担心字段写错 - 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一
ID
生成器 -Sequence
),可自由配置,完美解决主键问题 - 支持 ActiveRecord 模式:支持
ActiveRecord
形式调用,实体类只需继承Model
类即可进行强大的CRUD
操作 - 支持自定义全局通用操作:支持全局通用方法注入(
Write once
,use anywhere
) - 内置代码生成器:采用代码或者
Maven
插件可快速生成Mapper
、Model
、Service
、Controller
层代码,支持模板引擎,更有超多自定义配置等您来使用 - 内置分页插件:基于
MyBatis
物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List
查询 - 分页插件支持多种数据库:支持
MySQL
、MariaDB
、Oracle
、DB2
、H2
、HSQL
、SQLite
、Postgre
、SQLServer
等多种数据库 - 内置性能分析插件:可输出
SQL
语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询 - 内置全局拦截插件:提供全表
delete
、update
操作智能分析阻断,也可自定义拦截规则,预防误操作
③、支持的数据库
任何能使用
mybatis
进行CRUD
, 并且支持标准SQL
的数据库,具体支持情况如下
mysql
,oracle
,db2
,h2
,hsql
,sqlite
,postgresql
,sqlserver
,Phoenix
,Gauss
,clickhouse
,Sybase
,OceanBase
,Firebird
,cubrid
,goldilocks
,csiidb
- 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
二、快速开始
开始之前,先创建案例数据库
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'Jone@pwrd.com'),
(2, 'Jack', 20, 'Jack@pwrd.com'),
(3, 'Tom', 28, 'Tom@pwrd.com'),
(4, 'Sandy', 21, 'Sandy@pwrd.com'),
(5, 'Billie', 24, 'Billie@pwrd.com');
①、创建SpringBoot项目
创建完毕后删除多余文件
②、导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.phz</groupId>
<artifactId>mybatis_plus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis_plus</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidao</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
③、配置文件
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
④、POJO
/**
* @Author 两米以下皆凡人
* @create 2021/9/25 16:29
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
⑤、Mapper
区别于
Mybatis
,我们写好了Mapper
类以后,不用再去写对应的xml
文件,而是继承BaseMapper
类,且泛型指定为当前POJO
/**
* @Author 两米以下皆凡人
* @create 2021/9/25 16:32
*/
@Repository
public interface UserMapper extends BaseMapper<User> {
}
进入
BaseMapper
源码,可以看到基本的增删改查方法,正如你所想的那样,至此,增删改查方法我们同样也已经实现完了,是不是很像JPA
?没错,我们Mapper
实现类同样也是在程序运行过程中动态的帮我们创建出来的
我们虽然创建了一个
Mapper
接口,但是我们现在程序还不认识它,还不能在程序运行过程中去创建对应的实现类,那么我们需要让程序认识它,识别出他是一个Mapper
接口,有以下两种方式
- 直接在
Mapper
上方添加一个@Mapper
注解 - 在
Mapper
接口上方添加一个@Repository
注解,表示是一个Dao
,然后在SpringBoot
主启动类上面添加一个@MapperScan("com.xxx")
注解,多个包用逗号隔开
⑥、测试
测试类简单查询,首先注入
Mapper
,由于Mapper
继承了BaseMapper
,所以基础的CRUD
操作可以直接使用,如果基础的CRUD
不满足需求,也可以自定义自己的操作,后面会提到
@SpringBootTest
class MybatisPlusApplicationTests {
@Resource
UserMapper userMapper;
@Test
void contextLoads() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
}
有注意到
selectList
方法传入了一个null
,其实这个参数是一个Wrapper
对象,这个对象是用来构造查询条件的,这里先忽略,后面也会提到
三、日志配置
现在我们所有的日志都是不可见的,作为开发人员我们希望看到它是怎么执行的,方便调试,所以我们可以打开日志功能,在
YML
配置文件中配置即可
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///mybatis-plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
四、CRUD扩展
①、增
在测试类中新增一个插入测试
@Test
void testInsert() {
User user = new User();
user.setName("彭焕智");
user.setAge(22);
user.setEmail("penghuanzhi@pwrd.com");
int result = userMapper.insert(user);
System.out.println(result);//受影响的行数
System.out.println(user);
}
可以看到我们没有给
User
设置id
,在插入后,自动帮我们回填了一个id
值,不难判断这个id
是一个全局唯一的id
,其实这是一个通过雪花算法生成的
- 雪花算法
snowflake
是ID
生成算法,结果是一个long
型的ID
。其核心思想是:使用41bit
作为 毫秒数,10bit
作为机器的ID
(5
个bit
是数据中心,5
个bit
的机器ID
),12bit
作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096
个ID
),最后还有一个符号位,永远是0
。可以保证几乎全球唯一
Ⅰ、主键生成策略
@TableId(type = IdType.ID_WORKER)//默认全局唯一ID
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ID_WORKER(3),
UUID(4),
ID_WORKER_STR(5);
private int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
-
AUTO
主键自增,实体类添加此注解后,还需要设置数据库的主键自增,否则会报错
-
NONE
未设置主键
-
ID_WORKER
默认全局唯一
ID
-
INPUT
手动输入
-
UUID
全局唯一
id
-uuid
-
ID_WORKER_STR
ID_WORKER
字符串表示法
②、改
@Test
void testUpdate() {
User user = new User();
user.setId(6L);
user.setName("焕智");
int i = userMapper.updateById(user);
System.out.println(i);
}
给
User
再重新设置一个年龄观察
user.setAge(21);
- 对比两次执行的
SQL
语句,可以发现MabatisPlus
是根据条件动态拼接SQL
的,而不是我们想象中的直接在生成的Mapper实现类中直接写死SQL
语句
思考一个问题,对于创建时间修改时间,这些操作每一遍都应该是自动化完成的,不应该手动更新,有了解阿里巴巴开发手册的同学可能知道,有两个字段是几乎所有表都应该具备的,那就是
gmt_create
,gmt_modified
,也就是创建时间和修改时间,且要配置自动化
Ⅰ、问题处理
- 方法一,直接修改数据库表结构(工作中不推荐使用)
新增两个字段,暂且用
create_time
和update_time
表示,注意修改时间需要勾选根据当前时间戳更新,两者默认为current_timestamp
在
POJO
新增两个属性
private Date createTime;
private Date modifiedTime;
观察此时数据库中值,目前时间还是空的
我们执行一次修改操作
user.setName("彭焕智");
user.setAge(22);
再次观察数据库,可以看到修改时间也加上了
- 方法二,代码层面
表那两个字段还是需要加上的,不过,我们把那个默认值给去掉
然后在实体类的两个字段上面新增注解
@TableField(fill = FieldFill.XXX)
,默认FieldFill.DEFAULT
,称之为自动填充策略
public enum FieldFill {
DEFAULT,
INSERT,
UPDATE,
INSERT_UPDATE;
private FieldFill() {
}
}
显而易见,
createTime
只需要在插入的时候自动填充,而updateTime
需要在插入和修改都填充
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date modifiedTime;
- 自动填充策略还没有完,我们需要去处理填充什么内容,此时我们需要创建一个我们的填充策略处理器,它实现了
MetaObjectHandler
接口,分别重写增加和删除时候执行的两个填充策略方法,且这个处理器类还需要被SpringBoot程序扫描到,所以还需要新增一个@Component
注解
/**
* @Author 两米以下皆凡人
* @create 2021/9/25 17:57
*/
@Component
@Slf4j
public class TimeMetaHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("插入填充开始...");
//setFieldValByName(String fieldName,Object fieldVal,MetaObject metaObject
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("modifiedTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("更新填充开始...");
this.setFieldValByName("modifiedTime", new Date(), metaObject);
}
}
再次测试增加
修改:
③、MyBatis Plus的乐观锁插件
- 取出记录时,获取当前
version
- 更新时,带上这个
version
- 执行更新时,
set version = newVersion where version = oldVersion
- 如果
version
不对,就更新失败
Ⅰ、增加字段
给表结构增加一个
version
字段,默认为1
Ⅱ、增加属性
同样的实体类增加一个字段,并加上一个
version
注解
@Version//乐观锁version注解
private Integer version;
Ⅲ、注册组件
这个时候就需要定义一个配置类了,需要在这个配置类上方加上一个
@Configuration
注解,之前全局扫描包的注解也可以转移到这个配置类上面了(随着不停的增加字段,修改配置,我们的Demo
慢慢走向完善了,目前还不够),然后注入一个名为OptimisticLockerInterceptor
的一个==拦截器Bean
==即可
/**
* @Author 两米以下皆凡人
* @create 2021/9/25 18:28
*/
@Configuration
@MapperScan("com.phz.mybatis_plus.mapper")
public class MyBatisPlusConfigure {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
Ⅳ、测试
正常情况
@Test
public void testSuccessOptimisticLocker() {
// 1、查询用户信息
User user = userMapper.selectById(7L);
// 2、修改用户信息
user.setName("彭彭");
user.setEmail("1551402789@qq.com");
// 3、执行更新操作
userMapper.updateById(user);
}
异常情况
@Test
public void testFailedOptimisticLocker2() {
// 线程 1
User user = userMapper.selectById(7L);
user.setName("焕智");
user.setEmail("1551402789@qq.com");
// 模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(7L);
user2.setName("智智");
user2.setEmail("penghuanzhi@pwrd.com");
userMapper.updateById(user2);
// 自旋锁来多次尝试提交!
userMapper.updateById(user); // 如果没有乐观锁就会覆盖插队线程的值!
}
显而易见,先更新的
user2
成功了,user
并没有成功
④、查
Ⅰ、简单查询
话不多说,上三个查询
// 测试查询
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println(user);
}
// 测试批量查询
@Test
public void testSelectByBatchId() {
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
// 按条件查询之一使用map操作
@Test
public void testSelectByBatchIds() {
HashMap<String, Object> map = new HashMap<>();
// 自定义要查询
map.put("name", "彭焕智");
map.put("age", 22);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
Ⅱ、分页查询
想想我们以前分页怎么做的?
- 原始的
limit
进行分页 pageHelper
第三方插件MyBatis Plus
其实也内置了分页插件
其实也不难,只需要注入一个分页拦截器即可
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
⑤、删除
话不多说,上三个删除
// 测试删除
@Test
public void testDeleteById() {
userMapper.deleteById(7L);
}
// 通过id批量删除
@Test
public void testDeleteBatchId() {
userMapper.deleteBatchIds(Arrays.asList(2L, 3L));
}
// 通过map删除
@Test
public void testDeleteMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "彭焕智");
userMapper.deleteByMap(map);
}
Ⅰ、逻辑删除
- 对于工作中的大部分场景,我们是不会直接物理删除的,都是需要逻辑删除,因为当今是一个大数据的时代,数据就是金钱(^_^)
新增一个字段用于标识是否删除
增加属性
@TableLogic //逻辑删除
private Integer deleted;
新增逻辑删除组件(不是拦截器哈)
@Bean public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
最后就需要在
YML
配置文件中指定1,0分别表示什么啦
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///mybatis-plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-value: 1
logic-not-delete-value: 0
最后执行代码删除4,5,结果显而易见哈
观察日志可以发现,删除走的就是修改方法啦,查询呢,就自动过滤了
deleted
字段为1的数据
五、性能分析插件
我们在平时的开发中,会遇到一些慢
SQL
,对于性能分析拦截器,用于输出每条SQL
语句及其执行时间,如果超过这个时间就停止运行,使用性能分析插件,可以帮助我们提高效率
①、注入性能分析拦截器类
/**
* SQL执行效率插件
* 设置 dev test 环境开启,保证我们的效率
*/
@Bean
@Profile({"dev", "test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
// ms设置sql执行的最大时间,如果超过了则不执行
performanceInterceptor.setMaxTime(100);
// 是否格式化代码
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
如使用了性能分析拦截器,并配置了Profile
属性,需要在配置环境中激活当前是dev
环境还是test
环境
spring:
profiles:
active: dev
当
MaxTime
设置为1(很小很小),可以看到最基本的一个查询也会报错
重新修改为100的时候,可以看到,程序不再报错了
六、条件构造器
在快速开始的时候我们埋下的伏笔还记得吧,在
selectList
的时候,参数传递了一个null
,当时我们说了,这是一个条件构造器,如果传递null
,就是没有条件,现在我们来介绍一下这个条件构造器Wrapper
,且十分重要,可以用来替代很多的复杂SQL
- 下面列出部分
Wrapper
的若干构造条件,详情请戳这里
查询方式 | 说明 |
---|---|
setSqlSelect | 设置SELECT查询字段 |
where | WHERE语句,拼接 - WHERE条件 |
and | AND语句,拼接 - AND 字段=值 |
andNew | AND语句,拼接 - AND (字段=值) |
or | OR语句,拼接 - OR 字段=值 |
orNew | OR语句,拼接 - OR(字段=值) |
eq | 等于= |
allEq | 基于map内容等于= |
ne | 不等于<> |
gt | 大于> |
ge | 大于等于>= |
lt | 小于< |
le | 小于等于<= |
like | 模糊查询LIKE |
notLike | 模糊查询NOT LIKE |
in | IN查询 |
notin | NOT IN查询 |
isNull | NULL值查询 |
isNotNull | IS NOT NULL |
groupBy | 分组GROUP BY |
having | HAVING关键词 |
orderBy | 排序ORDER BY |
orderAsc | ASC排序ORDER BY |
orderDesc | DESC排序ORDER BY |
exists | EXISTS条件语句 |
notExists | NOT EXISTS条件语句 |
between | BETWEEN条件语句 |
notBetween | NOT BETWEEN条件语句 |
addFilter | 自由拼接SQL |
last | 拼接在最后,例如last(“LIMIT 1”) |
①、简单举例使用
Ⅰ、测试1
@Test
void test1() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
.isNotNull("email")
.ge("age", 12);
//和map对比
userMapper.selectList(wrapper).forEach(System.out::println);
}
查看日志可以看到查询条件拼接如下
WHERE
deleted=0
AND name IS NOT NULL
AND email IS NOT NULL
AND age >= 12
Ⅱ、测试2
@Test
void test2() {
// 查询年龄在 20 ~ 30 岁之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 区间
wrapper.between("age", 20, 30);
// 查询结果数
Integer count = userMapper.selectCount(wrapper);
System.out.println(count);
}
sql
WHERE
deleted=0
AND age BETWEEN 20 AND 30
Ⅲ、测试3
// 模糊查询
@Test
void test3() {
// 查询年龄在 20 ~ 30 岁之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 左和右 t%
wrapper.notLike("name", "e")
.likeRight("email", "t");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
sql
WHERE
deleted=0
AND name NOT LIKE '%e%'
AND email LIKE 't%'
Ⅳ、测试4
@Test
void test4() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 通过id进行排序
wrapper.orderByAsc("id");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
sql
WHERE
deleted=0
ORDER BY
id ASC
其余的测试,只要知道在哪里查怎么用就可以
七、代码自动生成器
AutoGenerator
是MyBatis-Plus
的代码生成器,通过AutoGenerator
可以快速生成Entity
、Mapper
、Mapper XML
、Service
、Controller
等各个模块的代码,极大的提升了开发效率。
①、添加依赖
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
②、建表
CREATE TABLE emp
(
id bigint NOT NULL,
empno INT,
ename VARCHAR(50),
job VARCHAR(50),
mgr INT,
hiredate DATE,
sal DECIMAL(7, 2),
comm DECIMAL(7, 2),
deptno INT,
version int NULL DEFAULT 1,
create_time datetime(0) NULL DEFAULT NULL,
modified_time datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP (0),
deleted int NULL DEFAULT 0,
PRIMARY KEY (id) USING BTREE
);
CREATE TABLE dept
(
id bigint NOT NULL,
deptno INT,
dname VARCHAR(14),
loc VARCHAR(13),
version int NULL DEFAULT 1,
create_time datetime(0) NULL DEFAULT NULL,
modified_time datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP (0),
deleted int NULL DEFAULT 0,
PRIMARY KEY (id) USING BTREE
);
③、创建代码自动生成器
/**
* @Author 两米以下皆凡人
* @create 2021/9/25 20:30
*/
public class AutoGeneratorTest {
public static void main(String[] args) {
// 需要构建一个 代码自动生成器 对象
AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("PengHuAnZhi");
gc.setOpen(false);
// 是否覆盖
gc.setFileOverride(false);
// 去Service的I前缀
gc.setServiceName("%sService");
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
//模块名
pc.setModuleName("MybatisPlusDemo");
//包名
pc.setParent("com.phz.mybatis_plus_auto_generator_test");
//实体类包名
pc.setEntity("entity");
//mapper包名
pc.setMapper("mapper");
//service包名
pc.setService("service");
//控制器包名
pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
// 设置要映射的表名
strategy.setInclude("blog_tags", "course", "links", "sys_settings", "user_record", "user_say");
//实体类名下划线转驼峰命名
strategy.setNaming(NamingStrategy.underline_to_camel);
//字段名下划线转驼峰命名
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// 自动lombok;
strategy.setEntityLombokModel(true);
//逻辑删除
strategy.setLogicDeleteFieldName("deleted");
// 自动填充配置
TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
TableFill modifiedTime = new TableFill("modified_time", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(createTime);
tableFills.add(modifiedTime);
strategy.setTableFillList(tableFills);
// 乐观锁
strategy.setVersionFieldName("version");
//设置Restful风格的驼峰命名
strategy.setRestControllerStyle(true);
//Controller允许访问的时候参数用下划线传入,比如localhost:8080/hello_id_2
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
//执行
mpg.execute();
}
}
④、执行测试
成功执行