MybatisPlus

MyBatisPlus

MP是基于mybatis基础上开发的增强型工具,维勒简化mybatis开发,提高效率

因为企业中最常用的是SpringBoot所以我们主要研究基于SpringBoot使用Mybatis

快速入门

首先创建boot项目,你发现没有MP对应的启动依赖,于是我们要自己配,选好mysql的,点击完成(注意第一件事是更改Maven路径)

手动导入必要依赖

<!-- 添加MyBatisPlus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>

随后配置好数据源

image-20220515202409544

接着写好domain(get,set,tostring)

image-20220515202557590

接着就可以完成dao接口层了

之前springboot项目我们写dao接口是要自己去写里面的抽象方法再在接口上用@Mapper声明,现在用了MP之后我们只用继承BaseMapper并且传入对应实体类,再用@Mapper声明就可以进行测试了

@Mapper
public interface UserDao extends BaseMapper<User> {
}
@SpringBootTest
class MyBatisPlusQuickstarApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetAll() {
List<User> userList = userDao.selectList(null);
System.out.println(userList);
}
}

这直接可以返回所有数据(注意这里只有单表才可以多表要进行配置)

MyBatisPlus介绍

详细接受和教程直接看官网https://baomidou.com/,这是国人写的而且教程适合新手,建议看完

标准数据层开发

image-20220515215618059

在以上快速入门的基础上来测试MP自带的接口(注意在不配置具体表的情况下单表的数据库才能直接测)

@SpringBootTest
class MyBatisPlusQuickstarApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testSave(){
User user=new User();
user.setUsername("zhangsan");
user.setEmail("sb123@163.com");
user.setPassword("sbsbsb");
int insert = userDao.insert(user);
System.out.println(insert);
}
@Test
void testDelete(){
userDao.deleteById(4);
}
@Test
void testUpdate(){
User user=new User();
user.setId(6);
user.setUsername("老六");
int i = userDao.updateById(user);
System.out.println(i);
}
@Test
void testGeiById(){
User user = userDao.selectById(6);
System.out.println(user);
}
}

补充个简化实体类开发的依赖lombok(小辣椒)

首先导入依赖(因为是springboot项目版本号就不写了)

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
//用lombok创建实体类,就只用自己声明属性就可以了
@Setter
@Getter
@ToString
public class User {
private int id;
private String username;
private String email;
private String password;

还有的相关注解

@Setter
@Getter
@ToString
@NoArgsConstructor//无参构造方法
@AllArgsConstructor//有参构造方法
@EqualsAndHashCode//equals方法

@Date最常用相当于以上全部注解

image-20220516143918825

标准分页功能制作

首先我们要开启mp这个功能就要到拦截器中添加分页的拦截器

image-20220516150133986

接着就可以测试其自带的分页接口了

// 测试分页功能接口
@Test
void testGetByPage(){
IPage page=new Page(1,2);
userDao.selectPage(page,null);
System.out.println("当前页码值;"+page.getCurrent());
System.out.println("每页显示数;"+page.getSize());
System.out.println("总页数;"+page.getPages());
System.out.println("总条数;"+page.getTotal());
System.out.println("数据;"+page.getRecords());
}

image-20220516150231220

这里要看底层实现可以到方法中去看也可以开启mp的日志

开启方式如下

到我们的yml配置文件中配置

# 开启mp的日志(输出到控制台的日志)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

要开启其他方式的日志需要其他的配置(一般做测试将日志关了,遇到问题才打开)

条件查询

条件查询三种格式

首先日志文件较多导致我们不容易直接看到结果,我们现在配置文件中简化下日志的显示

image-20220516152155451

方式一:

@Test
void testGetAll() {
//按条件查询
QueryWrapper qw=new QueryWrapper();//wrapper接口实现查询的实现类
//添加条件
qw.lt("id",3);//id小于3的所有数据
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
}

image-20220516153039439

方式二:lambda格式的条件查询

// 方式二:lambda格式的条件查询(要在实现类中用泛型指定数据库对应的实体类)
QueryWrapper<User> qw=new QueryWrapper<User>();
qw.lambda().lt(User::getId,4);
List<User> userList = userDao.selectList(qw);
System.out.println(userList);

方式三:用LambdaQueryWrapper实现类简化方式二

// 方式三,简化方式二
LambdaQueryWrapper<User> lqw=new LambdaQueryWrapper<User>();
lqw.lt(User::getId,3);
List<User> userList = userDao.selectList(qw);
System.out.println(userList);

多条件查询直接加条件就好了

// 多条件查询id在1-3之间的数据
LambdaQueryWrapper<User> lqw=new LambdaQueryWrapper<User>();
//lqw.lt(User::getId,3);
//lqw.gt(User::getId,1);
lqw.lt(User::getId,3).gt(User::getId,1);
//and多条件直接写成这种链式语句
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
// 多条件查询id在2-3之外的数据
LambdaQueryWrapper<User> lqw=new LambdaQueryWrapper<User>();
lqw.lt(User::getId,2).or().gt(User::getId,3);
//or()
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

条件查询null值处理

原始方法用if判断条件是否为空(不推荐,会导致代码出现多个if语句)

image-20220516155405287

推荐使用条件控制参数的方式

只有前面的条件判断为true,后面的语句才有效

image-20220516155653981

查询投影

设置查询结果的样式

就是设置要显示的列

image-20220516160304436

查询条件

image-20220516160555351

主要就是一些方法的使用

image-20220516161127753

image-20220516161221804

其余的方法去看官文

条件构造器 | MyBatis-Plus (baomidou.com)

映射匹配兼容性

当表列名和我们实体类的列名不一致的时候

image-20220516162904214

编码中添加了数据库中没有定义的属性

image-20220516163101893

采用默认查询开放了所有字段的查看权限(包括密码这种不能显示的数据,只用返回的json里面有就能被想办法获取)

image-20220516163341111

表名和实体类名字不对应(这样mp不知道我们到底要查哪张表,这就是之前我们说的只能查单表的数据库)

在实体类上用@TableName绑定对应的表名

image-20220516163537586

一个数据库中所有的表中都有相同的前缀,我们也可以直接配置全局配置,将所有的实体类前缀都加上,这里假设所有表的前缀都是tb_

db-config:
table-prefix: tb_

这样就不用在实体类上使用@TableName注解了

id生成策略(主键生成)

全部策略请看官文

主键策略 | MyBatis-Plus (baomidou.com)

默认策略auto

image-20220516164306296

image-20220516164734706

我们一般到配置文件中直接更改默认的策略

db-config:
id-type: assign_id

多数据操作(删除&查询)

image-20220516165925340

逻辑删除

image-20220516170235048

image-20220516170935998

image-20220516171009227

建议使用全局配置逻辑字段

image-20220516171114114

一代配置了逻辑查询,则用mp的删除操作就变成了update操作,只是将对应的逻辑字段变成已删除标记

mp的查询所有也变成只查询逻辑字段是未删除的数据

要想查全部只有自己写sql语句进行查询

乐观锁

之前jdbc,和web开发也讲过,遇到并发现象带来的资源同时抢占问题,我们就要给资源上锁,免得同一个资源被多线程抢占

MP中通过拦截器可以实现乐观锁(只能解决中小型线程出现的问题)

一个乐观锁开发如下

version让同一个资源只能让一个线程操作,操作时拿到数据对应version,使其加1,其他线程也相对这个数据进行操作的时候发现version和数据提供的version对不上,则不能完成操作

image-20220516205017345

image-20220516205259026

image-20220516205318562

image-20220516205413515

代码生成器(了解)

image-20220516205949032

首先创建好boot项目,导入所需依赖,以下是需要手动导入的

<!-- 添加MyBatisPlus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- 代码生成器-->
<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>

image-20220516212425770

运行你发现弹出了生成好的目录

image-20220516212510685

里面的文件是根据数据库实现的,但是生成位置是默认位置,我们可以创建个管理类去更改其配置

image-20220516212633518

一般配置所需代码如下

package com.ember;
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;
public class CodeGenerator {
public static void main(String[] args) {
//1.获取代码生成器的对象
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")+"/mybatisplus_04_generator/src/main/java"); //设置代码生成位置
globalConfig.setOpen(false); //设置生成完毕后是否打开生成代码所在的目录
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);
//2.执行生成操作
autoGenerator.execute();
}
}

根据需求配置好了就运行就好了

posted @   Ember00  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示