MyBatisPlus学习
总结源自:B站遇见狂神说 MyBatisPlus教程地址
Mybatis—plus特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求,BaseMapper
- 支持 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
快速入门
地址:https://baomidou.com/guide/quick-start.html
导入数据库脚本:
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)
);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');
创建一个SpringBoot工程
创建一个空的 Spring Boot 工程
可以使用 Spring Initializer (opens new window)快速初始化一个 Spring Boot 工程
添加依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>undefined</version><relativePath/>
</parent>
创建pojo、mapper(不需要mapper.xml文件)
User类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Long id;private String name;private Integer age;private String email;
}@Mapper
public interface UserMapper extends BaseMapper<User> {//只需要继承BaseMapper<T> 就可以使用BaseMapper中CRUD方法
}
测试
@SpringBootTest
class MybatisplusdemoApplicationTests {@Autowiredprivate UserMapper userMapper;@Testvoid contextLoads() {List<User> userList = userMapper.selectList(null);userList.forEach(System.out::println);}
}
输出结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zCZ6aHx4-1628931210293)(MyBatis—plus.assets/image-20210807162248764.png)]
测试Insert
@Test
public void testInsert() {User user = new User();user.setAge(4);user.setName("zyh");user.setEmail("1111111@qq.com");int insert = userMapper.insert(user);System.out.println(insert);
}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E4ofAEEN-1628931210296)(MyBatis—plus.assets/image-20210807162845523.png)]
思考:没有设置id,为什么会插入id呢?
主键生成策略:雪花算法
开源的分布式ID生成ID算法,类型为Long
核心思想:snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是∶使用41bit作为毫秒数,10bit作为机器的ID (5个bit是数据中心,9个bit的机器ID ),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID),最后还有一个符号位,永远是0。
主键自增:
@TableId(type = IdType.AUTO)//主键自增,需要数据库同步设置自增
private Long id;//其他属性
public enum IdType {AUTO(0),//自增NONE(1),//未设置主键INPUT(2),//手动输入ID_WORKER(3),//默认全局IdUUID(4),//全局唯一IDID_WORKER_STR(5);//截取字符串表示
}
测试update
@Test
public void testUpdate() {User user = new User();user.setName("test");user.setAge(18);user.setId(5L);userMapper.updateById(user);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7azc10GH-1628931210298)(MyBatis—plus.assets/image-20210807165415631.png)]
会自动帮我们完成Sql拼接
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5O88kM7-1628931210300)(MyBatis—plus.assets/image-20210807165620882.png)]
自动填充
方式一:数据库级别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ld4BIgg7-1628931210303)(MyBatis—plus.assets/image-20210807165946535.png)]
再次insert测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CRd470xF-1628931210304)(MyBatis—plus.assets/image-20210807170452623.png)]
发现会自动帮我们创建时间并更新时间
方式二:代码级别
1、删除数据库中属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TEKpq0AN-1628931210305)(MyBatis—plus.assets/image-20210807171918298.png)]
2、在实体类中的属性加注解
@TableField(fill = FieldFill.INSERT)//插入时填充属性
private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)//插入更新时填充属性
private Date updateTime;
3、编写处理器处理注解
@Component
@Slf4j
public class AutoFillHandler implements MetaObjectHandler {//插入时的处理策略@Overridepublic void insertFill(MetaObject metaObject) {log.info("开始填充属性");this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);}//更新时的处理策略@Overridepublic void updateFill(MetaObject metaObject) {log.info("开始填充属性");this.setFieldValByName("updateTime",new Date(),metaObject);}
}
乐观锁
乐观锁:总是认为所有操作不会出现问题,无论什么操作都不会加锁!如果出现了问题,就去更新值测试
悲观锁:总是认为所有操作都会出问题,无论什么操作都会加锁!再去操作!
乐观锁插件
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
1、给数据库加上version字段
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9zykG0Av-1628931210305)(MyBatis—plus.assets/image-20210807175437388.png)]
2、实体类添加属性,加上@Version注解
@Version//Mybatis_plus乐观锁注解
private Integer verison;
3、注册乐观锁拦截器插件
@Configuration
@MapperScan("com.zyh.mybatisplusdemo.mapper")
@EnableTransactionManagement//自动开始事务管理
public class MyBatisPlusConfig {/*** 注册乐观锁插件* @return OptimisticLockerInterceptor*/@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}
}
4、测试
乐观锁成功
@Test
public void testOptimisticLocker() {//1、查询用户信息User user = userMapper.selectById(1L);//2、修改用户先息user.setName("testOptimisticLock");user.setEmail("testOptimisticLock@qq.com");//3、更新用户信息userMapper.updateById(user);
}
乐观锁失败
@Test
public void testOptimiticLockerFail() {//模拟线程1修改属性User user1 = userMapper.selectById(1L);user1.setName("testOptimisticLock111");user1.setEmail("testOptimisticLock@qq11.com");//模拟线程2修改属性User user2 = userMapper.selectById(1L);user2.setName("testOptimisticLock222");user2.setEmail("testOptimisticLock@qq22.com");userMapper.updateById(user1);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e1ZYpYRM-1628931210306)(MyBatis—plus.assets/image-20210807183509696.png)]
查询操作
selectById:单个查询
@Test
public void testSelectById() {// User user = new User();// user.setEmail("test@test.com");// user.setName("testSelectById");// user.setAge(2);User user1 = userMapper.selectById(3L);System.out.println(user1);
}
selectByBatchIds:批量查询
public void testSelectByBatchIds() {List<User> userList = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));userList.forEach(System.out::println);
}
条件查询map:selectByMap
@Test
public void testSelectByMap() {HashMap<String, Object> map = new HashMap<>();//自定义查询//key是数据库对应字段,value是数据库字段的值//Mybatis_plus会去数据库匹配符合map中所有条件的数据并返回一个Listmap.put("name","Tom");map.put("id",3L);List<User> userList = userMapper.selectByMap(map);userList.forEach(System.out::println);
}
执行的sql及结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a6SDl9o7-1628931210307)(MyBatis—plus.assets/image-20210807194004190.png)]
分页查询
1、在MyBatisPlusConfig中加入分页插件
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();
}
2、使用Page对象即可
@Test
public void testPageSelect() {//Page<当前页,页面大小>Page<User> page = new Page<>(1,6);userMapper.selectPage(page,null);//拿到当前页的记录page.getRecords().forEach(System.out::println);
}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uRPvv53A-1628931210307)(MyBatis—plus.assets/image-20210807200356976.png)]
删除操作
根据id删除数据
// 根据id删除数据@Testpublic void testDeleteById() { userMapper.deleteById(1423923643572228098L);}
根据ids列表删除
//根据ids删除@Testpublic void testDeleteByIds() { userMapper.deleteBatchIds(Arrays.asList(1423923972787326978L,1423923972787326979L, 1423923972787326980L));
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rb2WeZre-1628931210311)(MyBatis—plus.assets/image-20210807201322187.png)]
根据map条件查询
//根据map条件查询@Testpublic void testDeleteMap() { HashMap<String, Object> map = new HashMap<>(); map.put("name","test"); map.put("age",23); userMapper.deleteByMap(map);}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KFuFkAQv-1628931210312)(MyBatis—plus.assets/image-20210807201727641.png)]
逻辑删除
物理删除:在数据库中直接移除数据
逻辑删除:在数据库中没有移除,而是通过一个变量使数据失效,类似于回收站的功能!
测试:
在数据库中加入deleted字段,在实体类加入属性
@TableLogicprivate Integer deleted;
在配置类中加入逻辑删除插件
/*** 逻辑删除插件*/@Beanpublic ISqlInjector sqlInjector() { return new LogicSqlInjector();}
yml中加入配置
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #配置日志 global-config: db-config: logic-delete-value: 1 logic-not-delete-value: 0
测试删除
//逻辑删除@Testpublic void logicDelete() { userMapper.deleteById(1L);}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1tQfmIyd-1628931210313)(MyBatis—plus.assets/image-20210808231214843.png)]
执行后可以看到并没有直接删除,而是将数据库中deleted字段值更改为1,执行的是update操作
再来测试一下select操作,看看数据是否还能被正常查询到
@Testpublic void testLogic() { User user = userMapper.selectById(1L); System.out.println(user);}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IhiHXD7G-1628931210314)(MyBatis—plus.assets/image-20210808231642215.png)]
查询不到这个用户,逻辑删除插件会帮我们过滤deleted字段值为1的数据,但是在数据库中这个数据仍然存在。
性能分析插件
在平时开发中,会遇到一些慢查询,MP提供了性能分析插件
1、导入插件
//sql性能分析工具@Bean@Profile({"dev", "test"})public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); //sql执行最大时间 performanceInterceptor.setMaxTime(100); performanceInterceptor.setFormat(true); return performanceInterceptor;}
2、在配置yml
spring: profiles: active: dev
条件构造器Wrapper
使用wrapper可以替代一些复杂的sql,使用wrapper中的方法来加入条件执行sql
测试1:查询name不为空、email不为空,年龄大于12的用户信息
@Testpublic void testWrapper() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.isNotNull("name") .isNotNull("email") .ge("age", 12);//g:大于 e:equals userMapper.selectList(wrapper).forEach(System.out::println);}
测试2:查询单个数据使用selectOne,多个数据可以使用map或list
@Testpublic void test1Wrapper() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("name","Tom"); System.out.println(userMapper.selectOne(wrapper));}
测试3:Between and ,年龄在20-30之间
@Testpublic void test1Wrapper() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.between("age",20,30); Integer count = userMapper.selectCount(wrapper);//查询的区间结果数 System.out.println(count);}
测试4:模糊查询
//模糊查询,名字中不包含y的@Testpublic void test2Wrapper() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.notLike("name","y"); List<Map<String, Object>> maps = userMapper.selectMaps(wrapper); maps.forEach(System.out::println);}
测试5:内查询
//内查询@Testpublic void test3Wrapper() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.inSql("id","select id from user where id > 1"); userMapper.selectList(wrapper).forEach(System.out::println);}
测试6:降序升序
@Testpublic void test6() { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.orderByAsc("id"); userMapper.selectObjs(wrapper).forEach(System.out::println);}
代码自动生成器
MyBatisPlus学习相关推荐
- MybatisPlus学习(四)条件构造器Wrapper方法详解
https://www.cnblogs.com/xianz666/p/13857733.html MybatisPlus学习(四)条件构造器Wrapper方法详解 文章目录 1.条件构造器 2.Que ...
- MyBatis-Plus 学习笔记
MyBatis-Plus 学习笔记 学习官网: https://mp.baomidou.com/guide/ 一.快速入门 1.简介 MyBatis的增强工具,在Mybatis的基础上只做增强功能,兼 ...
- MybatisPlus学习〖三〗crud接口实现
MybatisPlus学习[三] 我们继续学习mp的增删改查接口 代码具体的实现 条件构造器实现 1. 查询user表中user_name字段模糊查询'张',或者user_age年龄大于20岁,按照u ...
- MyBatisPlus 学习笔记_MP的AR模式
狂神说 MyBatisPlus 学习笔记 一.快速入门 文档:https://mp.baomidou.com/ 使用第三方组件: 导入对应依赖 研究依赖如何配置 代码如何编写 提高扩展技术能力 步骤: ...
- MyBatis-Plus学习总结
MyBatis-Plus学习总结 什么是MyBatis-Plus? MyBatis-Plus的优点有哪些? 快速开始(在SpringBoot中使用MP) MyBatis-Plus常用注解 MyBati ...
- MyBatisPlus学习笔记【part2】
MyBatisPlus学习笔记[part2] 一.查询操作 1.通过多个id批量查询 调用selectBatchIds方法. @Test public void testSelect1(){List& ...
- mybatis-plus学习记录(详细)
文章目录 mybatis-plus MyBatis Plus 快速上手 常用注解 查询 自定义 SQL(多表关联查询) 添加 删除 修改 MyBatisPlus自动生成 Spring Boot +My ...
- Mybatis-plus学习-最全细致讲解
Mybatis的升级版 首先说一下这个Mybatis-plus他自己集成了所有的CRUD方法,所以我们先简单的写一个小测试: 启动类: package com.example.Demo; import ...
- mybatis-plus学习(一)——入门看这一篇就够了
文章目录 前言 准备工作 1.需要准备的SQL 2.一个简单的maven项目 3.配置文件如下 4.建立一个简单的实体和mapper 5.简单的helloworld测试程序 基本使用 通用mapper ...
- Mybatis-Plus学习(一):实现增删改查CRUD
首先贴一个官网网址:MyBatis-Plus,学习mybatis一定要跟着官方文档来. mybatis-plus的作用:基友搭配,效率翻倍 说下实现简单增删改查的步骤: 1.创建一个springboo ...
最新文章
- iOS中的两种主要架构及其优缺点
- 一步一步SharePoint 2007系列文章目录
- .ini文件的读写操作
- 关于windows内存泄露思考
- java中注解的使用与实例(一)
- 研究生第一篇学术论文常犯问题总结
- 一套存储承载全场景,XSKY星辰天合发布企业级SDS V5系列
- 使用SQL语句添加和删除约束
- python是什么 自学-初学 Python 者自学 Anaconda 的正确姿势是什么?
- Windows server 2003 伪静态配置方法
- 滤波器基础06——滤波器设计软件
- Spring Boot工程结构推荐
- 图文介绍 Presto + Velox 整合
- 2020-08-31 ubuntu18.04下安装gitlab,以及使用邮箱注册
- python 显著性检验_Python SciPy 统计显著性检验(Statistical Significance Tests)
- 关于csv文件最大行数和最大列数
- Python学习之查询IP地址
- 自动化测试的三种测试报告模板
- Verilog TestBench 高级教程
- 用AHK读写Excel表格数据