总结源自: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学习相关推荐

  1. MybatisPlus学习(四)条件构造器Wrapper方法详解

    https://www.cnblogs.com/xianz666/p/13857733.html MybatisPlus学习(四)条件构造器Wrapper方法详解 文章目录 1.条件构造器 2.Que ...

  2. MyBatis-Plus 学习笔记

    MyBatis-Plus 学习笔记 学习官网: https://mp.baomidou.com/guide/ 一.快速入门 1.简介 MyBatis的增强工具,在Mybatis的基础上只做增强功能,兼 ...

  3. MybatisPlus学习〖三〗crud接口实现

    MybatisPlus学习[三] 我们继续学习mp的增删改查接口 代码具体的实现 条件构造器实现 1. 查询user表中user_name字段模糊查询'张',或者user_age年龄大于20岁,按照u ...

  4. MyBatisPlus 学习笔记_MP的AR模式

    狂神说 MyBatisPlus 学习笔记 一.快速入门 文档:https://mp.baomidou.com/ 使用第三方组件: 导入对应依赖 研究依赖如何配置 代码如何编写 提高扩展技术能力 步骤: ...

  5. MyBatis-Plus学习总结

    MyBatis-Plus学习总结 什么是MyBatis-Plus? MyBatis-Plus的优点有哪些? 快速开始(在SpringBoot中使用MP) MyBatis-Plus常用注解 MyBati ...

  6. MyBatisPlus学习笔记【part2】

    MyBatisPlus学习笔记[part2] 一.查询操作 1.通过多个id批量查询 调用selectBatchIds方法. @Test public void testSelect1(){List& ...

  7. mybatis-plus学习记录(详细)

    文章目录 mybatis-plus MyBatis Plus 快速上手 常用注解 查询 自定义 SQL(多表关联查询) 添加 删除 修改 MyBatisPlus自动生成 Spring Boot +My ...

  8. Mybatis-plus学习-最全细致讲解

    Mybatis的升级版 首先说一下这个Mybatis-plus他自己集成了所有的CRUD方法,所以我们先简单的写一个小测试: 启动类: package com.example.Demo; import ...

  9. mybatis-plus学习(一)——入门看这一篇就够了

    文章目录 前言 准备工作 1.需要准备的SQL 2.一个简单的maven项目 3.配置文件如下 4.建立一个简单的实体和mapper 5.简单的helloworld测试程序 基本使用 通用mapper ...

  10. Mybatis-Plus学习(一):实现增删改查CRUD

    首先贴一个官网网址:MyBatis-Plus,学习mybatis一定要跟着官方文档来. mybatis-plus的作用:基友搭配,效率翻倍 说下实现简单增删改查的步骤: 1.创建一个springboo ...

最新文章

  1. iOS中的两种主要架构及其优缺点
  2. 一步一步SharePoint 2007系列文章目录
  3. .ini文件的读写操作
  4. 关于windows内存泄露思考
  5. java中注解的使用与实例(一)
  6. 研究生第一篇学术论文常犯问题总结
  7. 一套存储承载全场景,XSKY星辰天合发布企业级SDS V5系列
  8. 使用SQL语句添加和删除约束
  9. python是什么 自学-初学 Python 者自学 Anaconda 的正确姿势是什么?
  10. Windows server 2003 伪静态配置方法
  11. 滤波器基础06——滤波器设计软件
  12. Spring Boot工程结构推荐
  13. 图文介绍 Presto + Velox 整合
  14. 2020-08-31 ubuntu18.04下安装gitlab,以及使用邮箱注册
  15. python 显著性检验_Python SciPy 统计显著性检验(Statistical Significance Tests)
  16. 关于csv文件最大行数和最大列数
  17. Python学习之查询IP地址
  18. 自动化测试的三种测试报告模板
  19. Verilog TestBench 高级教程
  20. 用AHK读写Excel表格数据

热门文章

  1. 多变量微积分笔记19——直角坐标系和柱坐标系下的三重积分
  2. Bootstrap学习之三:使用排版
  3. 图片处理应用:固定容器缩略图实现
  4. 各类4G手机进入工参模式查看手机信息
  5. sql2008 表名为全数字时查询报错
  6. 拓端tecdat|数据视域下图书馆话题情感分析
  7. 拓端tecdat|共享单车大数据报告
  8. ctimespan 获取毫秒_VC++ 获取系统时间的方法汇总
  9. LeetCode6 Z字形变换
  10. 评分卡模型之数据预处理