Welcome to 发呆鱼.|

发呆鱼

园龄:3年4个月粉丝:1关注:0

MyBatisPlus 入门学习笔记

1 简介

官网

MyBatis-Plus (baomidou.com)

简述

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

2 快速入门

数据库中创建表

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');

创建项目,引入依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>
spring:
  #数据源配置
  datasource:
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/myemployees?useUnicode=utf-8&characterEncoding=utf-8

#配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

使用

一个实体类
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

一个接口
public interface UserMapper extends BaseMapper<User> {

}



即可使用

@Autowired
private UserMapper userMapper;

@Test
public void testSelect() {
    System.out.println(("----- selectAll method test ------"));
    //参数是一个wrapper,条件构造器
    //查询全部的用户
    List<User> userList = userMapper.selectList(null);

    userList.forEach(System.out::println);
}

3 CRUD

3.1 插入

@Test
public void insertTest(){
    User user=new User();
    user.setAge(12);
    user.setEmail("aaaa@test.com");
    user.setName("fadaiyu");

    int insert = userMapper.insert(user);//自动生成id
}

image-20220221223614262

主键生成策略

    //数据库ID自增该类型请确保数据库设置了 ID自增 否则无效
    AUTO(0),
    /**
     * 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
     */
    NONE(1),
    /**
     * 用户输入ID
     * 该类型可以通过自己注册自动填充插件进行填充
     */
    INPUT(2),

    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 分配ID (主键类型为number或string),
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
     * @since 3.3.0
     */
    ASSIGN_ID(3),
    /**
     * 分配UUID (主键类型为 string)
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
     */
    ASSIGN_UUID(4);

雪花算法

Twitter使用scala语言开源了一种分布式 id 生成算法——SnowFlake算法,被翻译成了雪花算法。因为自然界中并不存在两片完全一样的雪花的,每一片雪花都拥有自己漂亮独特的形状、独一无二。雪花算法也表示生成的ID如雪花般独一无二。

雪花算法生成的ID是一个64 bitlong型的数字且按时间趋势递增。大致由首位无效符、时间戳差值、机器编码,序列号四部分组成。

img

如图:

  • 首位无效符:第一个 bit 作为符号位,因为我们生成的都是正数,所以第一个 bit 统一都是 0。
  • 时间戳:占用 41 bit ,精确到毫秒。41位最好可以表示2^41-1毫秒,转化成单位年为 69 年。
  • 机器编码:占用10bit,其中高位 5 bit 是数据中心 ID,低位 5 bit 是工作节点 ID,最多可以容纳 1024 个节点。
  • 序列号:占用12bit,每个节点每毫秒0开始不断累加,最多可以累加到4095,一共可以产生 4096 个ID。

3.2 更新

@Test
public void updateTest(){
    User user=new User();
     //通过条件自动拼接动态sql
    user.setId(6L);
    user.setName("fadaiyu");

    userMapper.updateById(user);

}

自动填充——数据库级别

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 '邮箱',
	 	`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP comment  '创建时间',
    `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '修改时间',
    PRIMARY KEY (id)
);

自动填充——代码级别

添加注释

@TableField(fill = FieldFill.INSERT)
private Date createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
#自动填充
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    //插入时填充数据
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
       
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

3.3 乐观锁

乐观锁:它总是认为不会出现问题,无论干什么都不去上锁。如果出现问题,再次更新测试。

悲观锁:它认为总是会出现问题,无论干什么都会上锁。

乐观锁实现方式:

  • 取出记录时,获取当前 version

  • 更新时,带上这个 version

  • 执行更新时, set version = newVersion where version = oldVersion

  • 如果 version 不对,就更新失败

mybatisplus 实现

数据库中添加字段

image-20220221233730992

添加字段

@Version //乐观锁主键
private int version;

注册组件

@Configuration
public class MybatisPlusconfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

}

3.4 查询操作

 @Test
public void queryTest(){


    System.out.println(userMapper.selectById(1L));  //通过id查询

    //通过多个用户id查询
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    for (User user : users) {
        System.out.println(user);
    }

    //使用map 按条件查询
    HashMap<String, Object> map=new HashMap<>();
    map.put("name","2");
    List<User> users2 = userMapper.selectByMap(map);
    for (User user : users2) {
        System.out.println(user);
    }


}

分页查询

/**分页查询
1. 使用原始的limit 进行分页
2. pageHelper 第三方插件
3. mybatisplus 内置了分页插件
*/

//引入插件
@Configuration
@MapperScan("com.fadaiyu.mapper")
public class MybatisPlusconfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //加入乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //加入分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}


 @Test
public void pageTest(){

    //current:当前页  size: 页面大小
    Page<User> page=new Page<>(2,5);
    userMapper.selectPage(page, null);

    page.getRecords().forEach(System.out::println);

}

3.5 删除

@Test
public void deleteTest(){
    //通过id 删除
    userMapper.deleteById(2L);

    //通过
    userMapper.deleteBatchIds(Arrays.asList(18,19));

    //通过map删除
    Map<String, Object> map=new HashMap<>();
    map.put("name","17");
    userMapper.deleteByMap(map);


}

逻辑删除

删除的时候没有从数据库中直接删除,而是通过一个变量来让他逻辑删除

  @TableLogic  //逻辑删除主键
  private int deleted;

//添加配置
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      logic-delete-field: false
      logic-delete-value: 1
      logic-not-delete-value: 0

image-20220223102457067

执行的是delete 操作,但是本质走的是delete 操作

image-20220223102634937

此时再执行查询操作,就自动添加了deletetd=0 条件。

4 条件构造器

 @Test
public void test1(){

    QueryWrapper<User> wrapper=new QueryWrapper<>();
    wrapper
        .isNotNull("email") //邮箱不为空
        .ge("age",10); //年龄大于10

    userMapper.selectList(wrapper).forEach(System.out::println);
}


wrapper.eq("name","8"); //查询名字为8的


wrapper.between("age",1,18);  //查询年龄在1--18 之间的个数
System.out.println(userMapper.selectCount(wrapper));


wrapper.notLike("name","1");  //(name NOT LIKE %1%)

 wrapper.likeLeft("name","1");  //(name  LIKE %1)

.....

https://baomidou.com/pages/10c804/#abstractwrapper

5 代码生成器

package com.fadaiyu;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;

public class CodeGenerator {

    public static void main(String[] args) {
        String projectPath=System.getProperty("user.dir");



        FastAutoGenerator.create("jdbc:mysql://localhost:3306/myemployees?useUnicode=utf-8&characterEncoding=utf-8",
                        "root", "123456")
                .globalConfig(builder -> {
                    builder.author("fadaiyu") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir(projectPath+"/src/main/java/")// 指定输出目录
                            .dateType(DateType.ONLY_DATE);//日期类型

                })
                .packageConfig(builder -> {
                    builder.parent("com.fadaiyu") //设置父包名
                            .moduleName("blog") //设置模块名
                            .entity("entity") //设置实体类
                            .mapper("mapper")
                            .service("service")
                            .controller("controller");
                })
                .execute();

    }
}

代码生成器(新) | MyBatis-Plus (baomidou.com)

代码生成器配置新 | MyBatis-Plus (baomidou.com)

跟随《遇见狂神说》学习

本文作者:发呆鱼

本文链接:https://www.cnblogs.com/dyiblog/articles/15927824.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   发呆鱼  阅读(36)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起