一、MyBatisPlus(以下简称MP)
快速入门
- 创建数据库:mybatis_plus
- 创建 user 表
DROP TABLE IF EXISTS user;
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)
);
-- 真实开发中会有字段 version(乐观锁)、deleted(逻辑删除)、gmt_create、gmt_modified(创建、修改时间)
- 插入数据
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
- 编写项目,初始化项目,用Spring Initializer,勾选 spring web
- 添加必需的依赖
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mybatis-plus,是自己开发的不是官方的-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
说明:不要同时导入 mybatis 和 mybatis-plus,依赖的版本有差异会导致一些问题
- 连接数据库,修改配置文件 application.yaml
# mysql 5 驱动 com.mysql.jdbc.Driver
# mysql 8 驱动 com.mysql.cj.jdbc.Driver 高版本兼容低版本,url还比5需要多添加时区设置:serverTimezone=GMT%2B8
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
username: root
password: 123456
6. 传统操作数据库方式:pojo-dao(连接 mybatis, 配置 mapper.xml 文件)-service-controller
-
使用 mybatis-plus:
- pojo
@Data @AllArgsConstructor @NoArgsConstructor public class User { private Long id; private String name; private Integer age; private String email; }
- mapper 接口
@Repository public interface UserMapper extends BaseMapper<User> { //@Repository 注册进容器并标识为持久层 //此时所有的 CRUD 操作都已编写完成,无需再配置一堆文件,因为继承了 BaseMapper,它有许多操作的方法 //我们也可以编写自己的扩展方法 }
-
别忘了主启动类上加 Mapper 扫描注解
-
@MapperScan("com.sky.mapper")
- 使用
@SpringBootTest class MybatisPlusApplicationTests { @Autowired private UserMapper userMapper; @Test void contextLoads() { //参数是一个 Wrapper(条件构造器),这里先不用 List<User> users = userMapper.selectList(null); users.forEach(System.out::println); } }
配置日志
我们所有的 sql 现在不可见,但我们希望知道它如何执行,所以必须配置日志
-
只需要在 application.yaml 加一个配置即可:
-
#日志配置 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-
输入 mylog 首选就是这个属性,再输入 std 就出来属性值了
二、CRUD扩展
插入操作
-
依旧不用任何配置,直接测试类测试
-
@Test public void testInsert(){ User user = new User(); user.setName("sky"); user.setAge(18); user.setEmail("123@qq.com"); int result = userMapper.insert(user); System.out.println(result); System.out.println(user); }
-
测试后我们发现我们并未设置 id,但是 id 却自动生成了
-
我们知道数据库插入的 id 的默认值为:全局的唯一 id,那么这是如何实现的?
主键生成策略
- 例如常见的 uuid、自增 id、雪花算法、redis、zookeeper
默认使用 ID_WORKER 全局唯一 id 策略
雪花算法
- snowflake 是 Twitter 开源的分布式 ID 生成算法,结果是一个 long 型的 ID。其核心思想是:使用 41bit 作为毫秒数,10bit 作为机器的 ID(5 个 bit 是数据中心,5 个 bit 的机器 ID),12bit 作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。可以保证几乎全球唯一
主键自增
我们需要的配置:
- 实体类字段上 @tableId(type=IdType.Auto)
- 数据库字段需要设置为自增
- 修改后再次测试发现就是上一个生成的 id + 1
其他
public enum IdType {
AUTO(0), //数据库 id 自增
NONE(1), //未设置主键
INPUT(2), //手动输入
ID_WORKER(3), //默认的全局唯一 id
UUID(4), //全局唯一id uuid
ID_WORKER_STR(5); //ID_WORKER 的字符串表示法
}
- 一旦改为INPUT 就需要自己输入 id 了
更新操作
-
直接测试类
-
@Test public void testUpdate(){ User user = new User(); user.setId(1L); user.setAge(19); userMapper.updateById(user); }
-
注意传参是一个 user 对象,而不是真的是传个 id 进去,测试后发现 Jone 的 age 变成了 19
-
你多修改几个属性观察打印的 sql 会发现 MyBaitsPlus 会自动帮你动态拼接 sql
自动填充
- 我们知道创建时间,修改时间这些数据都是自动化完成的,我们不希望手动更新
阿里巴巴开发手册:所有的数据库表 gmt_create、gmt_modified 几乎所有的表都要配置这两个字段,并且需要自动化(gmt:格林尼治时间)
数据库级别(工作中不允许修改数据库)
-
创建时间别勾选根据当前时间戳更新,不然更新操作连创建时间一起更新
-
对应的,实体类也添加字段
-
private Date createTime; private Date updateTime;
-
再次更新测试发现确实更新时间
代码级别
-
先删除数据库中刚才为时间添加的配置
-
//字段添加填充内容 @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
-
编写处理器来处理注解即可!
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert");
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
乐观锁
- 面试过程经常会被问到乐观锁、悲观锁
乐观锁:顾名思义,总是认为不会出现问题,无论干什么都不去上锁,如果出现问题就再次更新值测试
悲观锁:顾名思义,十分悲观,认为干什么都会出现问题,无论干什么都会上锁再去操作
- 我们看一下官方文档怎么说
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
-
举个例子:
-
线程A:update user set name = "Jack",version = version + 1 where id = 2 and version = 1 线程B:update user set name = "Jack",version = version + 1 where id = 2 and version = 1
-
如果线程 A 在查询到 version 为 1 时,线程 B 不仅查询到 version 为 1,都进行完了修改操作,那么此时线程 A 继续工作,在执行更新操作时要把 1 更新为 2,但是 此时发现 version 都已经变成 2 了,那么就不更新
测试乐观锁插件:
- 数据库表先增加 int 类型字段 version,长度 10,默认为 1
- 根据规范肯定要对应修改实体类
@Version
private Integer version;
- 注册组件:handler 同级目录创建 config 包,新建 MyBatisPlusConfig.java
@EnableTransactionManagement
/**
* 这是 MyBatisPlus 应该做的,所以把包扫描注解从主启动类移了过来
*/
@MapperScan("com.sky.mapper")
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
- 测试一下
@Test
public void testOptimisticLocker2(){
//线程1
User user = userMapper.selectById(1L);
user.setAge(111);
//模拟另一个线程执行插队操作
User user2 = userMapper.selectById(1L);
user2.setAge(222);
userMapper.updateById(user2);
//如果没有乐观锁,那么 age 本来更新成了 222 会被覆盖成 111,但是有乐观锁,所以还是 222
userMapper.updateById(user);
}
查询操作
-
根据 id 查询一个用户就不说了
-
根据一堆 id 查询一堆用户:
-
@Test public void testSelectBatchId(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); users.forEach(System.out::println); }
-
使用 map 条件查询
-
@Test public void testSelectByMap(){ HashMap<String,Object> map = new HashMap<>(); map.put("name","Jack"); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); }
分页查询
- 原始的 limit 进行分页
- pageHelper 第三方插件
- MP 内置分页插件
使用方式
-
MP 配置类中加一行,添加组件
-
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
测试分页查询
@Test
public void testPage(){
//参数1:当前页,参数2:页面大小
Page<User> page = new Page<>(1,5);
userMapper.selectPage(page, null);
page.getRecords().forEach(System.out::println);
}
删除操作
- deleteById、deleteByMap、deleteBatchId 就不用说了,和 select 一样
逻辑删除
物理删除:从数据库中直接移除
逻辑删除:在数据库中未被移除,而是通过变量来让他失效,也就是软删除
- 例如实现管理员可以查看被删除的记录,防止数据丢失,类似回收站。其实就是为每条记录添加一个字段,如果是某个约定的值,普通用户无法查询到,管理员则可以直接访问数据库看到
测试
-
新增 int 类型 deleted 字段,长度 1,默认值 0,代表未被删除;1 代表被删除
-
实体类增加字段
-
@TableLogic private Integer deleted;
-
同样的 MP 配置类中添加组件
-
@Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); }
-
其实不配置好像也没关系,但是字段上的注解以及 application 配置一定要有,不然人家怎么知道什么值代表删除
-
#日志配置 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #逻辑删除 global-config: db-config: logic-delete-value: 1 logic-not-delete-value: 0
-
配置完以后测试删除操作时,不再删除记录,而是将 deleted 字段的值置为你设置的 1,此时进行查询测试,观察 sql 语句会发现自动拼接了 and deleted=0
性能分析插件
我用了直接原地爆炸,官网也已经移除这个
-
还是一样我们先把组件注册进来,在 MP 配置类中
-
@Bean @Profile({"dev","test"}) public PerformanceInterceptor performanceInterceptor(){ //性能分析插件 PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); //设置执行sql的最大时间,如果超过了则不执行 performanceInterceptor.setMaxTime(1); //设置是否开启格式化 performanceInterceptor.setFormat(true); return performanceInterceptor; }
-
这里注意这个配置只在 dev 和 test 环境下生效,所以我们需要在 application.yaml 中设置当前环境
条件构造器
之前的都是简单的条件查询,而使用条件构造器,几乎可以满足所有 sql 语句的实现
查询名字、邮箱不为空且年龄大于 20 的用户
-
@Test public void contextLoads() { //查询名字、邮箱不为空且年龄大于 20 的用户 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.isNotNull("name").isNotNull("email").ge("age",20); userMapper.selectList(wrapper).forEach(System.out::println); }
-
我的测试类用的是
import org.junit.Test;
,然后我就发现我得在类上加@RunWith(SpringRunner.class)
不然测试跑不起来 -
如果用
import org.junit.jupiter.api.Test;
则不需要上面那个注解,并且方法不能加 public -
ge 竟然是 GreaterEqual 也就是大于等于的意思,这名字起的真不咋的,你用 greatEq 都比这个见名知意
查询名字等于 Jone 的用户
-
@Test void test2(){ //查询名字等于 Jone 的用户 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("name","Jone"); User user = userMapper.selectOne(wrapper); System.out.println(user); }
-
查询一个的时候用 selectOne 否则别用,不然一个对象变量怎么接受两个对象的值
查询年龄在 20 - 25 之间的用户
-
@Test void test3(){ //查询年龄在 20 - 25 之间的用户 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.between("age",20,25); Integer count = userMapper.selectCount(wrapper); System.out.println(count); }
-
selectCount 可以得到查询结果有几条,用 selectList 还是一样获得查询到的用户
查询名字不带 e 并且 邮箱最左边是 t 的用户
-
@Test void test4(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.notLike("name","e").likeRight("email","t"); List<Map<String, Object>> maps = userMapper.selectMaps(wrapper); maps.forEach(System.out::println); }
-
likeLeft 就是比如 %t,t 开头所以用 rightLike 就是 t%,直接 like 就是 %t%
子查询测试
-
用子查询查询 id 小于 3 的
-
@Test void test5(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.inSql("id","select id from user where id<3"); List<Object> objects = userMapper.selectObjs(wrapper); objects.forEach(System.out::println); }
-
如果是 in,那么你能理解这个条件,比如
select * from user where id in (1,2,3)
-
那么这里的 inSql 其实就是
select * from user where id in (sql)
-
最终结果就是
select * from user where id in (select id from user where id<3)
查询所有用户根据 id 倒序
-
@Test void test6(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.orderByDesc("id"); userMapper.selectList(wrapper).forEach(System.out::println); }
三、代码生成器
-
万物皆对象,所以先创建一个自动生成器,然后执行代码生成操作,当然此时执行是等于啥也没干
-
public class CodeGenerator { public static void main(String[] args) { //构建代码生成器对象 AutoGenerator autoGenerator = new AutoGenerator(); //执行生成代码操作 autoGenerator.execute(); } }
-
-
生成肯定是根据你配置的生成策略来生成,所以来先全局配置一下
-
//配置策略 //1.全局配置 GlobalConfig config = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); //文件输出目录 config.setOutputDir(projectPath + "/src/main/java"); //设置作者 config.setAuthor("sky"); //生成完了是否打开资源管理器中生成的目录 config.setOpen(false); //是否覆盖原来生成的 config.setFileOverride(true); //去掉生成的 service 的 I 前缀 config.setServiceName("%sService"); //主键生成策略为雪花算法 config.setIdType(IdType.ASSIGN_ID); //设置日期格式 config.setDateType(DateType.ONLY_DATE); //自动配置swagger文档 config.setSwagger2(true); //为代码生成器设置为该全局配置 generator.setGlobalConfig(config);
-
别导错包,我一开始就导成核心类的了
-
import com.baomidou.mybatisplus.generator.AutoGenerator;
-
-
然后设置数据源
-
//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); generator.setDataSource(dsc);
-
-
然后包配置
-
//3.包配置 PackageConfig pc = new PackageConfig(); //生成的模块名 pc.setModuleName("test"); //此时最后生成的文件都会在 com.sky.test 下 pc.setParent("com.sky"); pc.setEntity("model"); pc.setMapper("mapper"); pc.setService("service"); pc.setController("controller"); generator.setPackageInfo(pc);
-
-
最后是策略配置
-
//4.策略配置 StrategyConfig strategyConfig = new StrategyConfig(); //包名下换线转驼峰 strategyConfig.setNaming(NamingStrategy.underline_to_camel); //列名下划线转驼峰 strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); //要生成的表名 strategyConfig.setInclude("user"); //自动为实体类增加 lombok 注解 strategyConfig.setEntityLombokModel(true); //逻辑删除字段 strategyConfig.setLogicDeleteFieldName("deleted"); //自动填充配置 TableFill createTime = new TableFill("create_time", FieldFill.INSERT); TableFill updateTime = new TableFill("update_time", FieldFill.UPDATE); strategyConfig.setTableFillList(Arrays.asList(createTime,updateTime)); //乐观锁 strategyConfig.setVersionFieldName("version"); //controller 使用 restful 风格 strategyConfig.setRestControllerStyle(true); //controller层请求配置驼峰转连字符 strategyConfig.setControllerMappingHyphenStyle(true); generator.setStrategy(strategyConfig);
-
-
老实说最后代码生成器代码不多,关键就是解决依赖是真的麻烦中的麻烦,首先是下面这个报错,说是什么什么版本不兼容,我就按照网上的把 MP 依赖版本都改成 3.4.0
-
com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty
-
然后又是报错,不过这个是模板引擎的问题,添加依赖就好
-
org/apache/velocity/context/Context
-
最后附上 pom.xml 中的全部依赖
-
<?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.6.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</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> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--mybatis-plus,是自己开发的不是官方的--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> <scope>test</scope> </dependency> <!-- 模板引擎 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <version>2.2.2.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.2.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.3.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> <version>1.5.13</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> <version>3.7.1</version> </plugin> </plugins> </build> </project>
附上代码生成器全部代码
package com.sky.mybatis_plus;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.Arrays;
/**
* @author sky
* @date 2022/4/1 17:06
*/
public class CodeGenerator {
public static void main(String[] args) {
//构建代码生成器对象
AutoGenerator generator = new AutoGenerator();
//配置策略
//1.全局配置
GlobalConfig config = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
//文件输出目录
config.setOutputDir(projectPath + "/src/main/java");
//设置作者
config.setAuthor("sky");
//生成完了是否打开资源管理器中生成的目录
config.setOpen(false);
//是否覆盖原来生成的
config.setFileOverride(true);
//去掉生成的 service 的 I 前缀
config.setServiceName("%sService");
//主键生成策略为雪花算法
config.setIdType(IdType.ASSIGN_ID);
//设置日期格式
config.setDateType(DateType.ONLY_DATE);
//自动配置swagger文档
config.setSwagger2(true);
//为代码生成器设置为该全局配置
generator.setGlobalConfig(config);
//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);
generator.setDataSource(dsc);
//3.包配置
PackageConfig pc = new PackageConfig();
//生成的模块名
pc.setModuleName("test");
//此时最后生成的文件都会在 com.sky.test 下
pc.setParent("com.sky");
pc.setEntity("model");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
generator.setPackageInfo(pc);
//4.策略配置
StrategyConfig strategyConfig = new StrategyConfig();
//包名下换线转驼峰
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
//列名下划线转驼峰
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
//要生成的表名
strategyConfig.setInclude("user");
//自动为实体类增加 lombok 注解
strategyConfig.setEntityLombokModel(true);
//逻辑删除字段
strategyConfig.setLogicDeleteFieldName("deleted");
//自动填充配置
TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
TableFill updateTime = new TableFill("update_time", FieldFill.UPDATE);
strategyConfig.setTableFillList(Arrays.asList(createTime,updateTime));
//乐观锁
strategyConfig.setVersionFieldName("version");
//controller 使用 restful 风格
strategyConfig.setRestControllerStyle(true);
//controller层请求配置驼峰转连字符
strategyConfig.setControllerMappingHyphenStyle(true);
generator.setStrategy(strategyConfig);
//执行生成代码操作
generator.execute();
}
}
- 学习代码在我资源