前言
为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)
发现宝藏
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。
五、CRUD进阶开发I
1.mp日志简化(加快程序运行速度)
- 在application.yml中添加配置
# 开启mp日志 (输出到控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- 运行结果(多了很多查询结果的详细信息)
- 进一步简化控制台输出
- 编辑applicatiion.yml(输入banner就会有对应提示)
- 创建logback.xml并编写该配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
</configuration>
- 简化后的控制台输出(spring加载与mybatis-plus加载相关信息不再显示)
2.条件查询的三种方式
- 方式一:常规写法按条件查询
- 在测试类的查询全部方法 selectList() 方法上ctrl + 鼠标左键进入该方法的源代码,可知当 selectList() 方法的参数为null的时候代表查全部,当参数为Wrapper类的时候代表按该类的限制条件查询
- 在Wrapper上ctrl + 鼠标左键进入该类源码,然后crtl + H查看该类的继承体系,可知该类是个抽象类,无法直接使用,此处我们选用该类的实现类QueryWrapper类来实现限制条件的编写
- 在测试类的 testGetAll() 方法中编写按条件查询的代码
@Test
void testGetAll() {
//按条件查询
//创建QueryWrapper类对象
QueryWrapper qw = new QueryWrapper<>();
//编写限制条件(查询年龄小于18岁的用户信息)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
qw.lt("age", 18);
//将条件Wrapper<T>类型的参数qw传入selectList()方法中
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
}
- 运行结果
可以看到只查询了2条记录(原表有4条记录)
2. 方式二:lambda格式按条件查询I
- 常规写法中的列名是写在字符串里的,出错不容易发现,可以借助lambda表达式确保列名不会写错,注意QuerWrapper接口后面要注入实体类
@Test
void testGetAll() {
//方式二:lambda格式按条件查询I
//创建QueryWrapper类对象,并指定泛型
QueryWrapper<User> qw = new QueryWrapper<User>();
//编写限制条件(查询年龄大于18岁的用户)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
qw.lambda().gt(User::getAge, 18);
//将条件Wrapper<T>类型的参数qw传入selectList()方法中
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
}
- 运行结果
- 方式三:lambda格式按条件查询II(推荐)
@Test
void testGetAll() {
//方式三:lambda格式按条件查询II
//创建LambdaQueryWrapper类对象,并指定泛型
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//编写限制条件(查询年龄小于4岁的用户)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
lqw.lt(User::getAge, 4);
//将条件Wrapper<T>类型的参数lqw传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果
- 多条件查询(举例)
- and逻辑(比如 x > 3 并且 x < 10)
@Test
void testGetAll() {
//方式三:lambda格式多条件查询
//创建LambdaQueryWrapper类对象,并指定泛型
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//编写限制条件(查询大于3岁小于10岁的用户)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
//链式编程
lqw.lt(User::getAge, 10).lqw.gt(User::getAge, 3);
//将条件Wrapper<T>类型的参数传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果
- or逻辑 (比如 x < 3 或者 x > 10)
@Test
void testGetAll() {
//方式三:lambda格式按条件查询
//创建LambdaQueryWrapper类对象,并指定泛型
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//编写限制条件(查詢年齡大10岁或者小于4岁的用户)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
//链式编程
lqw.gt(User::getAge, 10). or().lt(User::getAge, 4);
//将条件Wrapper<T>类型的参数传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果
3.条件查询null判断
- 应用场景举例
当我们在网上购物的时候筛选商品价格区间一般只设置上限或者下限,不设置值的那个输入框需要进行控制判断
- 原本的User类作为下限类,新建一个Userquery类继承User类表示上限
package com.example.dl_mp.domain.query;
import com.example.dl_mp.domain.User;
import lombok.Data;
//@Data 注解的主要作用是提高代码的简洁,
// 使用这个注解可以省去代码中大量的get()、 set()、 toString()等方法(这些通用方法可以一键生成);
//要使用 @Data 注解要先引入lombok,它是一个工具类库,可以用简单的注解形式来简化代码,提高开发效率。
@Data
public class Userquery extends User {
//以年龄为例,设置上限属性age2
private Integer age2;
}
- 模拟网页传入测试数据
@Test
void testGetAll() {
//模拟页面传递过来的查询数据
Userquery uq = new Userquery();
uq.setAge(3);
uq.setAge2(10);
//创建LambdaQueryWrapper类对象,并指定泛型
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//编写限制条件(查詢年齡大于3岁或者小于10岁的用户)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
lqw.gt(User::getAge, uq.getAge());
lqw.lt(User::getAge, uq.getAge2());
//将条件Wrapper<T>类型的参数传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果(但是如果getAge ()或者getAge2()为空,则查询失败)
- 用if语句判断(太多的if语句程序冗余,能用但是不推荐)
@Test
void testGetAll() {
//模拟页面传递过来的查询数据
Userquery uq = new Userquery();
//此处不设置下限Age的值
//uq.setAge(3);
uq.setAge2(10);
//创建LambdaQueryWrapper类对象,并指定泛型
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//编写限制条件(查詢年齡小于10岁的用户)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
if(null != uq.getAge()){
lqw.gt(User::getAge, uq.getAge());
}
lqw.lt(User::getAge, uq.getAge2());
//将条件Wrapper<T>类型的参数传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果
- 用【mybatis-plus条件构造器】的语法格式
@Test
void testGetAll() {
//模拟页面传递过来的查询数据
Userquery uq = new Userquery();
uq.setAge(3);
//此处不设置上限限Age2的值
//uq.setAge2(10);
//创建LambdaQueryWrapper类对象,并指定泛型
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//编写限制条件(查詢年齡大于3岁的用户)
//lt代表 < gt代表 >,第一个参数是列名,第二个参数是限制条件的数值
lqw.lt(null != uq.getAge2(), User::getAge, uq.getAge2());
lqw.gt(null != uq.getAge(), User::getAge, uq.getAge());
//将条件Wrapper<T>类型的参数传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果
4. 查询投影
- 如果我们只希望返回某些列的数据,而不是所有列的数据,我们可以用SELECT 列1, 列2, 列3 FROM …,让结果集仅包含指定列。这种操作称为【投影查询】
2.lambda表达式查询指定字段
@Test
void testGetAll() {
//查询投影
//创建LambdaQueryWrapper类对象,并指定泛型
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//lambda表达式查询指定字段
lqw.select(User::getId, User::getAge);
//将条件Wrapper<T>类型的参数传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果
- 如果使用的不是lambda表达式,就需要手动指定字段
@Test
void testGetAll() {
//查询投影
//创建QueryWrapper类对象,并指定泛型
QueryWrapper<User> lqw = new QueryWrapper<User>();
//非lambda表达式查询指定字段
lqw.select("age", "id", "password");
//将条件Wrapper<T>类型的参数传入selectList()方法中
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 运行结果
- 聚合查询 selectMaps()(count、max、min、avg、sum)
@Test
void testGetAll() {
//查询投影
//创建QueryWrapper类对象,并指定泛型
QueryWrapper<User> lqw = new QueryWrapper<User>();
//聚合查询(count、max、min、avg、sum),lambda无法做聚合查询
//as 起别名
//查询表中有多少条记录
lqw.select("count(*) as count");
//将条件Wrapper<T>类型的参数传入selectMaps()方法中
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
}
- 运行结果(结果集 Map 中 count 是 key, 4 是value)
- 分组查询( gruopBy() )
@Test
void testGetAll() {
//查询投影
//创建QueryWrapper类对象,并指定泛型
QueryWrapper<User> lqw = new QueryWrapper<User>();
//分组查询(groupby)
//as 起别名
//按电话分组并分别计数
lqw.select("count(*) as count, tel");
lqw.groupBy("tel");
//将条件Wrapper<T>类型的参数传入selectMaps()方法中
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
}
- 运行结果
- 模糊查询(like)
@Test
void testGetAll() {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//模糊匹配 like, Left 和 Right指的是%在左边还是右边
lqw.likeRight(User::getName,"J");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 更多请见【官方条件构造器详解】【查询投影详解】
5.映射匹配兼容性(@TableField()和@TableName())
- 问题一 :表字段与编码属性设计不匹配
- 如图表字段为 ‘pwd’ ,而实体类为 ‘password’,查询会出现异常,可以在实体类中通过 @TableField(value = “pwd”) 注解将实体类属性与表名进行映射匹配
- 问题二 :编码中添加了数据库中未定义的属性
如图,实体类中有用于判断用户是否在线的online属性,而数据库中没有相应的字段,查询会出现异常,可以通过 @TableField(exist = false) 设置该属性在数据库中不存在
- 问题三 :采用默认查询开发了更多字段查看权限
如图,用户密码默认在查询字段中,而该字段并不随便对外开放,可以用**@TableField(select = false)**将该字段的查询权限关闭
- 问题四 :表名与编码开发设计不同步
可以通过 @TableName(“tbl_user”) 注解将实体类名与数据库表名关联起来
6.id生成策略(@TableId()或全局配置)
-
Mybatis-plus提供了多种主键生成策略, 可以在Pojo类中主键上加注解进行配置,例如数据库主键自增 @TableId(type=IdType.AUTO)
-
不同的表应用不同的id生成策略:
日志:自增(1,2,3,4,……) 购物订单:特殊规则(FQ23948AK3843) 外卖单:关联地区日期等信息(10 04 20200314 34 91) 关系表:可省略id ……
-
策略种类
- 全局配置id生成策略
假设我们希望默认全部都使用 AUTO 策略(数据库ID自增),那么可以在 application.yml 中添加如下配置进行修改:
mybatis-plus.global-config.db-config.id-type=auto
7.多数据操作(_BatchIds())
- 应用场景
购物车删除多条记录 - 在testSave()方法中添加两条新纪录,效果如图
- 删除多条记录( deleteBatchIds ( Collection<> ) )
- 代码
@Test
void testDelete(){
//删除指定多条数据
List<Long> list = new ArrayList<>();
list.add(12L);
list.add(13L);
userDao.deleteBatchIds(list);
}
- 运行结果
- 查询多条记录
- 代码
- 运行结果
六、CRUD进阶开发II
1.逻辑删除( @TableLogic() 或者 全局配置)
- 应用场景
- 假如编号为1的员工辞职了,他的姓名,工号等信息要删除,但是他工作的合同编号,成交日期,金额等信息需要保留,如果直接执行按id删除操作,会把所有相关的数据删除掉,逻辑删除可以解决这个问题。
- 逻辑删除指的是修改数据的某个字段,使其表示为已删除状态,而非删除数据,保留该数据在数据库中,但是查询时不显示该数据(查询时过滤掉该数据)。
- 在navicat中右键user表,点击设计表选项添加字段delete, 并设置默认值为0,代表未进行逻辑删除,然后点击保存
3.在对应的user实体类中添加逻辑删除字段 deleted , 并通过 @TableLogic() 注解设置未进行逻辑删除的值 value 和 逻辑删除的值 delval
//lombok
@Data
@TableName("user")
public class User {
//设置主键生成策略
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
//逻辑删除字段,标记当前记录是否被删除
@TableLogic(value = "0" ,delval = "1")
private Integer deleted;
}
- 在测试类中的 testDelete() 方法方法中删除id为1的记录
- 代码
@Test
void testDelete(){
//模拟逻辑删除
userDao.deleteById(1L);
}
- 运行结果
从控制台输出以及表更新后的情况来看,可以知道逻辑删除做的其实是更新操作,并且此时查询全部不设置条件会默认查询 逻辑删除字段 deleted = 0(自定义的值)的记录
- 在全局配置中配置逻辑删除相关信息
- 在注解中的字符串里配置容易出错,我们可以在全局配置文件中配置逻辑删除的相关参数
- MyBatisPlus全局配置示例
global-config:
db-config:
#全局配置逻辑删除字段名
logic-delete-field: deleted
#逻辑已删除值(默认1)
logic-delete-value: 1
#逻辑未删除值(默认0)
logic-not-delete-value: 0
2.乐观锁(@version)
- 应用场景举例
添加和删除的操作简单的介绍完了,接下来介绍一下修改相关的问题及其解决方在案:乐观锁。比如我们在网上购物进行秒杀活动的时候,大家都去抢一个商品,每抢一次商品数量减一,最后一个被抢完的时候需要一个限制条件防止异常,这个处理并发问题的解决方案叫做乐观锁。它通过一个字段来标识,每抢一次该标识+1,这样每个人拿到的标识都不一样,当标识到达设定值后程序开始拦截请求。
- 添加乐观锁字段version
在user表上右键设计表格,点击添加字段,编辑version字段,设置数据类型为int,默认值为1
效果如下
- 在实体类user中添加乐观锁字段version,并添加@version注解
- 在Mpconfig类中添加乐观锁拦截器
要实现每次访问version的效果需要在访问的sql语句里添加功能可以实现 version = version + 1 的字段,mp里乐观锁拦截器可以做这个事情
- 在测试类的 testUpdate()方法中编辑修改记录的代码看看效果
- 代码
void testUpdate(){
User user = new User();
user.setId(3L);
user.setName("Jock666");
//要传version,如果没有传version就没有锁机制
user.setVersion(1);
userDao.updateById(user);
}
- 运行结果
右边的version是传入的version,左边的version是更新后的version,可以看到实现了version = version + 1的效果
6. 开启锁机制的第二种方法,先查询,再进行更新操作
- 代码
@Test
void testUpdate(){
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L);
//2.将要修改的属性逐一设置进去
user.setName("Jock777");
userDao.updateById(user);
- 运行结果
- 模拟多用户秒杀场景
假设此时秒杀活动已经过去了2秒,数据库里id为3的商品乐观锁字段version已经累加到了3
假设用户1 user, 用户2 user2 再进行秒杀活动,用户2先访问秒杀界点击下单,然后数库更新代表该商品的 id 为 3 的乐观锁字段version, 当用户1再进行访问下单的时候,version == 3的条件不成立,该更新请求操作失效,即秒杀失败
- 代码
@Test
void testUpdate(){
//用户1查询时version=3
User user = userDao.selectById(3L);
//用户2查询时version=3
User user2 = userDao.selectById(3L);
user2.setName("Jock aaa");
//用户2更新后version==4
userDao.updateById(user2);
user.setName("Jock bbb");
//此时用户1更新时verion=3的条件不成立,该更新语句失效
userDao.updateById(user);
}
- 运行结果
3. mp快速开发-代码生成器
1.场景介绍
在我们开发mp项目的时候,创建编写实体类功能的时候,模板都差不多,区别就是模块名不一样,这就类似于造句,只要提供模板和参数,mp就能自动帮我们生成代码
- 模板 :MyBatisPlus提供
- 数据库相关配置 :读取数据库获取信息
- 开发者自定义配置 :手工配置
- 创建新的springboot空项目DL_mp_generator(不勾选任何依赖,一会手动加),创建好新项目后导入 代码生成器 以及 velocity模板引擎 等坐标(完整代码见资源mybatis-plus源码)
//pom.xml文件
<dependencies>
<!--代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!--velocity模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
- 核心代码
创建Generator类,编写核心代码
此时运行没有什么意义,因为什么信息都没有配置
public class Generator {
public static void main(String[] args) {
//创建生成器对象
AutoGenerator autoGenerator = new AutoGenerator();
//执行生成器
autoGenerator.execute();
}
}
4.配置数据源
public class Generator {
public static void main(String[] args) {
//创建生成器对象
AutoGenerator autoGenerator = new AutoGenerator();
//配置数据源信息
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("root");
autoGenerator.setDataSource(dataSource);
//执行生成器
autoGenerator.execute();
}
}
(默认生成文件路径在D盘根目录下)
2.配置文件生成路径
- 代码
public class Generator {
public static void main(String[] args) {
//创建生成器对象
AutoGenerator autoGenerator = new AutoGenerator();
//配置数据源
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("root");
autoGenerator.setDataSource(dataSource);
//设置全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java"); //设置代码生成位置
globalConfig.setOpen(true); //设置生成完毕后是否打开生成代码所在的目录
globalConfig.setAuthor("东离与糖宝"); //设置作者
globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件
globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称
globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略
autoGenerator.setGlobalConfig(globalConfig);
//执行生成器
autoGenerator.execute();
}
}
- 运行结果
(默认生成的包名叫baomidou)
- 配置包名相关信息
先把baomidou包删除,并将临时表名改为tbl_user并执行如下代码
- 代码
public class Generator {
public static void main(String[] args) {
//创建生成器对象
AutoGenerator autoGenerator = new AutoGenerator();
//配置数据源
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("root");
autoGenerator.setDataSource(dataSource);
//设置全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java"); //设置代码生成位置
globalConfig.setOpen(true); //设置生成完毕后是否打开生成代码所在的目录
globalConfig.setAuthor("东离与糖宝"); //设置作者
globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件
globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称
globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略
autoGenerator.setGlobalConfig(globalConfig);
//设置包名相关配置
PackageConfig packageInfo = new PackageConfig();
packageInfo.setParent("com.aaa"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
packageInfo.setEntity("domain"); //设置实体类包名
packageInfo.setMapper("dao"); //设置数据层包名
autoGenerator.setPackageInfo(packageInfo);
//执行生成器
autoGenerator.execute();
}
}
- 运行结果
解析举例; 可以看到根据表名称生成了tbl前缀,并且实体类中有getter和setter方法
- 策略配置
- 代码
public class Generator {
public static void main(String[] args) {
//创建生成器对象
AutoGenerator autoGenerator = new AutoGenerator();
//配置数据源
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("root");
autoGenerator.setDataSource(dataSource);
//设置全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java"); //设置代码生成位置
globalConfig.setOpen(true); //设置生成完毕后是否打开生成代码所在的目录
globalConfig.setAuthor("东离与糖宝"); //设置作者
globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件
globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称
globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略
autoGenerator.setGlobalConfig(globalConfig);
//设置包名相关配置
PackageConfig packageInfo = new PackageConfig();
packageInfo.setParent("com.aaa"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
packageInfo.setEntity("domain"); //设置实体类包名
packageInfo.setMapper("dao"); //设置数据层包名
autoGenerator.setPackageInfo(packageInfo);
//策略设置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setInclude("tbl_user"); //设置当前参与生成的表名,参数为可变参数
strategyConfig.setTablePrefix("tbl_"); //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名 例如: User = tbl_user - tbl_
strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格
strategyConfig.setVersionFieldName("version"); //设置乐观锁字段名
strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名
strategyConfig.setEntityLombokModel(true); //设置是否启用lombok
autoGenerator.setStrategy(strategyConfig);
//执行生成器
autoGenerator.execute();
}
}
- 运行结果
解析举例: 可以看到数据库表前缀名称 tbl_ 在生成实体类等文件的时候被成功剪切,并且生成了乐观锁和逻辑删除字段,并且启用lombok(自带getter 和 setter方法)文章来源:https://www.toymoban.com/news/detail-494792.html
总结
欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)文章来源地址https://www.toymoban.com/news/detail-494792.html
到了这里,关于Mybatis-Plus 进阶开发 -- Mybatis-Plus 入门教程(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!