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>
随后配置好数据源
接着写好domain(get,set,tostring)
接着就可以完成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/,这是国人写的而且教程适合新手,建议看完
标准数据层开发
在以上快速入门的基础上来测试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最常用相当于以上全部注解
标准分页功能制作
首先我们要开启mp这个功能就要到拦截器中添加分页的拦截器
接着就可以测试其自带的分页接口了
// 测试分页功能接口 @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()); }
这里要看底层实现可以到方法中去看也可以开启mp的日志
开启方式如下
到我们的yml配置文件中配置
# 开启mp的日志(输出到控制台的日志) mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
要开启其他方式的日志需要其他的配置(一般做测试将日志关了,遇到问题才打开)
条件查询
条件查询三种格式
首先日志文件较多导致我们不容易直接看到结果,我们现在配置文件中简化下日志的显示
方式一:
@Test void testGetAll() { //按条件查询 QueryWrapper qw=new QueryWrapper();//wrapper接口实现查询的实现类 //添加条件 qw.lt("id",3);//id小于3的所有数据 List<User> userList = userDao.selectList(qw); System.out.println(userList); }
方式二: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语句)
推荐使用条件控制参数的方式
只有前面的条件判断为true,后面的语句才有效
查询投影
设置查询结果的样式
就是设置要显示的列
查询条件
主要就是一些方法的使用
其余的方法去看官文
条件构造器 | MyBatis-Plus (baomidou.com)
映射匹配兼容性
当表列名和我们实体类的列名不一致的时候
编码中添加了数据库中没有定义的属性
采用默认查询开放了所有字段的查看权限(包括密码这种不能显示的数据,只用返回的json里面有就能被想办法获取)
表名和实体类名字不对应(这样mp不知道我们到底要查哪张表,这就是之前我们说的只能查单表的数据库)
在实体类上用@TableName绑定对应的表名
一个数据库中所有的表中都有相同的前缀,我们也可以直接配置全局配置,将所有的实体类前缀都加上,这里假设所有表的前缀都是tb_
db-config: table-prefix: tb_
这样就不用在实体类上使用@TableName注解了
id生成策略(主键生成)
全部策略请看官文
主键策略 | MyBatis-Plus (baomidou.com)
默认策略auto
我们一般到配置文件中直接更改默认的策略
db-config: id-type: assign_id
多数据操作(删除&查询)
逻辑删除
建议使用全局配置逻辑字段
一代配置了逻辑查询,则用mp的删除操作就变成了update操作,只是将对应的逻辑字段变成已删除标记
mp的查询所有也变成只查询逻辑字段是未删除的数据
要想查全部只有自己写sql语句进行查询
乐观锁
之前jdbc,和web开发也讲过,遇到并发现象带来的资源同时抢占问题,我们就要给资源上锁,免得同一个资源被多线程抢占
MP中通过拦截器可以实现乐观锁(只能解决中小型线程出现的问题)
一个乐观锁开发如下
version让同一个资源只能让一个线程操作,操作时拿到数据对应version,使其加1,其他线程也相对这个数据进行操作的时候发现version和数据提供的version对不上,则不能完成操作
代码生成器(了解)
首先创建好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>
运行你发现弹出了生成好的目录
里面的文件是根据数据库实现的,但是生成位置是默认位置,我们可以创建个管理类去更改其配置
一般配置所需代码如下
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(); } }
根据需求配置好了就运行就好了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!