一、Mybatis plus

意义:

为简化而生

官网
https://baomidou.com/

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

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)
);支持数据库
任何能使用 MyBatis 进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下,如果不在下列表查看分页部分教程 PR 您的支持。

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库

    1、快速入门

    构建一个SpringBoot工程
  1. 导入依赖

注意!!!mybatis和plus版本只能引入其中一个版本,不然会失效

  1. <dependency>
  2. <groupId>mysql</groupId>
  3. <artifactId>mysql-connector-java</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.baomidou</groupId>
  7. <artifactId>mybatis-plus-boot-starter</artifactId>
  8. <version>3.0.5</version>
  9. </dependency>
  1. 创建表 ```sql 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’);

  1. 3. 编写实体类以及实体类Mapper接口
  2. ```java
  3. //继承BaseMapper plus中的接口
  4. // 处理哪一个实体类就所使用该实体类的泛型
  5. @Repository//代表持久层
  6. @Mapper
  7. public interface UserMapper extends BaseMapper<User> {
  8. //此时所有的CRUD全部完成
  9. }

此时
image.png

这些方法都来自于父类BaseMapper,当然我们自己也可以编写方法查询

  1. 编写测试方法
    1. @Slf4j
    2. @SpringBootTest
    3. class MybatisPlusApplicationTests {
    4. @Autowired
    5. private UserMapper userMapper;
    6. @Test
    7. void contextLoads() {
    8. //Wrapper<T> 是一个条件构造器 查询所有没有条件,填写null
    9. List<User> users = userMapper.selectList(null);
    10. log.info("所有用户是{}",users);
    11. }
    12. }
    1. # 打印日志
    2. mybatis-plus:
    3. configuration:
    4. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    image.png

2、CRUD

主键生成策略

插入一条ID为空的数据

snowflake雪花算法 (推特)

https://www.cnblogs.com/haoxinyue/p/5208136.html

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。雪花算法支持的TPS可以达到419万左右(2^22*1000)。

@TableId

标注在实体类作为主键的属性上
相应的type配置

  • @TableId(type=IdType.NONE) 自增
    • 数据库主键字段必须是自增的

其余的

  1. public enum IdType {
  2. AUTO(0),//数据库ID自增
  3. NONE(1),//未设置主键自增
  4. INPUT(2),//手动输入
  5. ASSIGN_ID(3),//
  6. ASSIGN_UUID(4);//全局唯一ID

更新操作

  1. @Test
  2. void Update(){
  3. User user = new User(1471747870506700801L,"23232柱",23,"101001");
  4. int insert = userMapper.updateById(user);
  5. System.out.println(insert);
  6. }

内置动态SQL

自动填充

创建时间、修改时间!这些操作都是一遍自动化完成的,不希望手动更新 阿里巴巴开发手册: 所有数据库表: gmt_create,gmt_modified几乎所有的表都要配置上!而且自动化

方式一(不建议)
数据库级别

  1. create table user
  2. (
  3. id bigint not null comment '主键ID'
  4. primary key,
  5. name varchar(30) null comment '姓名',
  6. age int null comment '年龄',
  7. email varchar(50) null comment '邮箱',
  8. # 时间单位 默认为当前时间戳
  9. gmt_create datetime default current_timestamp,
  10. gmt_modified datetime default current_timestamp
  11. );

更改实体类

  1. public class User {
  2. @TableId(type = IdType.NONE)
  3. private Long id;
  4. private String name;
  5. private Integer age;
  6. private String email;
  7. private Date gmtCreate;
  8. private Date gmtModified;
  9. }

方式二
代码级别

  1. 删除默认值(个人)
  2. @TbaleFeild 默认是不填充 ```java

    开启驼峰命名

    map-underscore-to-camel-case: true

//插入时间更新 @TableField(fill = FieldFill.INSERT) private Date gmtCreate; //更改时间更新 @TableField(fill = FieldFill.UPDATE) private Date gmtModified;

  1. 3. 获取填充
  2. ```java
  3. @Component//注册到SpringBoot中
  4. public class MyMetaObjectHandler implements MetaObjectHandler {
  5. @Override//插入数据时填充字段
  6. public void insertFill(MetaObject metaObject) {
  7. log.info("start insert fill ....");
  8. // 参数一 字段名 二、字段值 三、要给哪个数据处理
  9. this.setFieldValByName("gmtCreate",new Date(),metaObject);
  10. this.setFieldValByName("gmtModified",new Date(),metaObject);
  11. }
  12. @Override//更改数据时填充字段
  13. public void updateFill(MetaObject metaObject) {
  14. log.info("start update fill ....");
  15. this.setFieldValByName("gmtModified",new Date(),metaObject);
  16. }
  17. }

image.png

乐观锁

对乐观锁和悲观锁的文章https://www.jianshu.com/p/d2ac26ca6525

乐观锁: 不会认为出什么问题,干什么都不会先上锁!出了问题就更新值测试 悲观锁:悲观,认为干什么都会出问题,无论干什么,都会先上锁再操作

  1. alter table user add version int default 1;

线程A和线程B并发 同时更改一条数据,线程A访问之后将version数值+1,之后线程B发现version数值匹配不上,就放弃更改以此保障线程的安全

同时实体类同步

  1. //这个注解代表乐观锁
  2. @Version
  3. private Integer version;

添加拦截器

  1. // Spring Boot 方式
  2. @Configuration
  3. @MapperScan("按需修改")
  4. public class MybatisPlusConfig {
  5. /**
  6. * 旧版
  7. */
  8. @Bean
  9. public OptimisticLockerInterceptor optimisticLockerInterceptor() {
  10. return new OptimisticLockerInterceptor();
  11. }
  12. /**
  13. * 新版
  14. */
  15. @Bean
  16. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  17. MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
  18. mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
  19. return mybatisPlusInterceptor;
  20. }
  21. }

image.png

分页查询

1.配置组件

  1. @MapperScan("mybatisplus.mapper")
  2. @Configuration//配置组件
  3. @EnableTransactionManagement//开启事务,默认开启
  4. public class MybatisPlusVersion {
  5. //@Bean//返回乐观锁拦截器组件
  6. @Bean
  7. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  8. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  9. interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
  10. return interceptor;
  11. }
  12. /**
  13. * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
  14. */
  15. @Bean
  16. public MybatisPlusInterceptor mybatisPlusInterceptorPage() {
  17. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  18. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
  19. return interceptor;
  20. }
  21. }
  1. 查询
    1. @Test
    2. void pag(){
    3. //获取页
    4. Page<User> objectPage = new Page<>(2,3);
    5. Page<User> userPage = userMapper.selectPage(objectPage, null);
    6. userPage.getRecords().forEach(System.out::println);
    7. }
    image.png

逻辑删除

物理删除:从数据库中直接移除 逻辑删除:在数据库中没有移除,通过程序中的变量让他失效 delede=0=>delete=1

管理员可以查看被删除的记录,防止数据丢失,类似于回收站

  1. 添加一个字段delete

    1. alter table user add luo_ji int default 0;
  2. 配置文件

    1. mybatis-plus:
    2. global-config:
    3. db-config:
    4. logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
    5. logic-delete-value: 1 # 逻辑已删除值(默认为 1)
    6. logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  3. 注解:

    1. @TableLogic
    2. private Integer luoJi;

    执行删除语句
    image.png
    image.png

执行SQL分析插件

新版官方已经移除,参见官方文档

条件查询器 Warpper

支持混合SQL查询

  1. QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
  2. userQueryWrapper.inSql("id","select id from user where id < 3");
  3. userMapper.selectList(userQueryWrapper).forEach(System.out::println);

image.png

代码生成器

新版

  1. 导入依赖
    1. <dependency>
    2. <groupId>com.baomidou</groupId>
    3. <artifactId>mybatis-plus-generator</artifactId>
    4. <version>3.5.1</version>
    5. </dependency>
    全局配置方案
    https://baomidou.com/pages/981406/#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE-globalconfig