2022/5/30 Mybatis-Plus详解

目录

1.Mybatis-Plus简介

2.特性 

3.支持数据库

4.框架结构

5.快速开始 

        5.1 创建数据库mybatis_plus

        5.2 搭建项目

                5.2.1 创建Spring Boot工程

                5.2.2 导入依赖

                5.2.3 配置yml 

                5.2.4 entity实体类

                5.2.5 mapper 

                5.2.6 service 

                5.2.7  service实现类

6.使用Mybatis-Plus简化CURD 

        6.1编写测试类

        6.1 增加

        6.2 删除

        6.3 修改

        6.4 查询

                6.4.1模糊查询 

                6.4.2  区间查询

7. 自定义ID生成器

8. 自动填充  

         8.1 数据库新增两个字段(create_time,update_time)

         8.2 实体类新增两个字段(createTime,updateTime)

         8.3 编写Mybatis-Plus自动填充配置类

         8.4 结果

 9.乐观锁

        9.1 数据库新增字段(version)

        9.2  实体类新增字段(version)

        9.3 编写MyBatisPlus的配置类

        9.4 测试 

10.逻辑删除 

        10.1 数据库新增字段(deleted)

        10.2 实体类新增字段(deleted)

        10.3 yml配置 

        10.4 测试 

11. 代码生成器

12.高级条件查询(条件构造器)

        12.1 条件构造器关系介绍

        12.2 介绍 

        12.3 wapper介绍

        12.3 API

        12.4 示例

13.分页插件 

        13.1 编写MyBatisPlus的配置类

        13.2 Page<>对象API

        13.3 示例


写在前面:

  • 下面文章大部分是手敲和官网复制
  • 不喜勿喷

1.Mybatis-Plus简介

官网:MyBatis-Plus

代码托管:Gitee | Github

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

愿景:

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

2.特性 

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

3.支持数据库

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

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb

  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库

4.框架结构

5.快速开始 

        5.1 创建数据库mybatis_plus

现有一张 User 表,其表结构如下:

idnameageemail
1Jone18test1@baomidou.com
2Jack20test2@baomidou.com
3Tom28test3@baomidou.com
4Sandy21test4@baomidou.com
5Billie24test5@baomidou.com

其对应的数据库 Schema 脚本如下: 

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)
);
-- 真实开发中,version(乐观锁),deleted(逻辑删除)、gmt_create、gem_mo

        5.2 搭建项目

                5.2.1 创建Spring Boot工程

                5.2.2 导入依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--引入MybatisPlus核心配置文件-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--代码生成器-->
        <!--当前包未传递依赖 MP 包,需要自己引入!-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!-- 模板生成器引擎配合代码生成器一起使用 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
    </dependencies>

                5.2.3 配置yml 

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl   #开启日志打印
    map-underscore-to-camel-case: true    #开启驼峰命名法 数据库中的字段为create_time单词之间用_隔开
  mapper-locations: classpath*:/mapper/*Mapper.xml  #扫描接口
  type-aliases-package: com.example.mybatisplusday1.entity  #别名
  global-config:
    db-config:
      logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

                5.2.4 entity实体类

package com.example.mybatisplusday1.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.AUTO)    //设置id为自增长,跟随数据库表中列,默认为UUid需要手动改
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

                5.2.5 mapper 

package com.example.mybatisplusday1.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplusday1.entity.User;
import org.apache.ibatis.annotations.Mapper;


@Mapper
// 在对应的Mapper上面继承基本的类 BaseMapper
public interface UserMapper extends BaseMapper<User> {
    // 所有的CRUD操作都已经编写完成了
    // 你不需要像以前的配置一大堆文件了!
}

                5.2.6 service 

package com.example.mybatisplusday1.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mybatisplusday1.entity.User;

public interface UserService extends IService<User> {

}

                5.2.7  service实现类

package com.example.mybatisplusday1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mybatisplusday1.entity.User;
import com.example.mybatisplusday1.mapper.UserMapper;
import com.example.mybatisplusday1.service.UserService;
import org.springframework.stereotype.Service;


/**
 * UserServiceImpl的实现类
 * @ClassName UserServiceImpl
 * @Description TODO
 * @Author ACER
 * @Date 2022/5/17 17:05
 * @Version 1.0
 **/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

6.使用Mybatis-Plus简化CURD 

        6.1编写测试类

package com.example.mybatisplusday1;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.mybatisplusday1.entity.User;
import com.example.mybatisplusday1.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.sql.Wrapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
class MybatisPlusday1ApplicationTests {
    @Autowired
    private UserMapper usermapper;

}

        6.1 增加

 @Test
    /*
    * 添加用户信息
    * */
    void contextLoads() {
        User user = new User();
        user.setName("方哥");
        user.setAge(19);
        user.setEmail("1149876322@qq.com");
        int result = usermapper.insert(user); // 雪花算法帮我们自动生成id
        System.out.println(result); // 受影响的行数
        System.out.println(user); // 发现,id会自动回填
    }

        6.2 删除

   /**
     * 功能描述:
     * MybatisPlus的一些删除方式
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/17 15:57
     */
    @Test
    void delete(){
        //1.按id删除,既可以按id删除,也可以按对象删除
        int result=usermapper.deleteById(1L);
        //int result usermapper.deleteById(User);
        //2.批量删除
        int delete = usermapper.deleteBatchIds(Arrays.asList(1l, 2l, 3l));
        //3.通过map删除
        Map<String,Object>map=new HashMap<>();
        map.put("name","方哥");
        int result2=usermapper.deleteByMap(map);
        //条件构造,高级操作
        //usermapper.delete(Wrapper);
    }

        6.3 修改

    /**
     * 功能描述:
     * MybatisPlus的一些修改方式
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/17 15:25
     */
    @Test
    void update(){
        //通过id修改,可以实现动态修改
        User user=new User();
        user.setId(7L);
        user.setName("fang");
        usermapper.updateById(user);
        //通过条件进行修改,高级部分
        //usermapper.update(User,wrapper);
    }

        6.4 查询

    /**
     * 功能描述:
     * MybatisPlus的一些查询方式
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/17 15:27
     */
    @Test
    void select(){
        //1.根据id获取一个User对象
        User user1 = usermapper.selectById(6L);

        //2.按map条件查询
        Map<String,Object>map=new HashMap<>();
        map.put("name","fang");
        map.put("age",19);
        List<User> users = usermapper.selectByMap(map);
        //jdk8的lambda表达式 ::方法引用
        users.forEach(System.out::println);
        //3.查询全部
        List<User> users1 = usermapper.selectList(null);
        users1.forEach(System.out::println);
    }

                6.4.1模糊查询 

   /**
     * 功能描述:
     * MybatisPlus(条件构造器)模糊查询
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/18 9:29
     **/
    @Test
    void selectBylike(){
        String name="";
        //wrapper.likeRight();      %在右边
        //wrapper.likeLeft();       %在左边
        //wrapper.like();           %%左右两边都有
        //   wrapper.like(true,"name",name);
        //第一个参数为判断name是否为空为空查全部不为空则按要求查
        QueryWrapper<User>wrapper=new QueryWrapper<>();
        wrapper.like(true,"name",name);
        List<User> users = usermapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

                6.4.2  区间查询

 /**
     * 功能描述:
     * MybatisPlus(条件构造器)区间查询
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/30 10:09
     **/
    @Test
    void selectByBetween(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.between("age",15,24);
        //所有的条件拼接默认都是and,只有当自己拼接了or才会以or的方式拼接
        wrapper.or().eq("name","方哥");
        wrapper.orderByDesc("age");
        List<User> users = usermapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

7. 自定义ID生成器

设置实体类中主键自增长类型(默认自动生成类型为UUID)

    @TableId(type = IdType.AUTO)    //设置id为自增长,跟随数据库表中列,默认为UUid需要手动改
    private Long id;

api: 

package com.baomidou.mybatisplus.annotation;

import lombok.Getter;

/**
 * 生成ID类型枚举类
 *
 * @author hubin
 * @since 2015-11-10
 */
@Getter
public enum IdType {
    /**
     * 数据库ID自增
     * <p>该类型请确保数据库设置了 ID自增 否则无效</p>
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
     */
    NONE(1),
    /**
     * 用户输入ID
     * <p>该类型可以通过自己注册自动填充插件进行填充</p>
     */
    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);

    private final int key;

    IdType(int key) {
        this.key = key;
    }
}

8. 自动填充  

创建时间、修改时间!这些操作一般自动化完成的,我们不希望手动更新!

阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified几乎所有表都要配置上!而且需要自动化!

         8.1 数据库新增两个字段(create_time,update_time)

         8.2 实体类新增两个字段(createTime,updateTime)

    // 注意!这里需要标记为填充字段
    //fill = FieldFill.INSERT代表新增是填充
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    // 注意!这里需要标记为填充字段
    //fill = FieldFill.INSERT_UPDATE代表新增修改时填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

         8.3 编写Mybatis-Plus自动填充配置类

package com.example.mybatisplusday1.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 功能描述:
 * MyBatisPlus的自动填充配置类
 * @Author: Mr.Huang
 * @Date: 2022/5/17 15:45
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {


    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //增加的时候实现填充,需要添加两个值
        this.strictInsertFill(metaObject, "createTime", Date.class,new Date()); // 起始版本 3.3.0(推荐使用)
        this.strictInsertFill(metaObject, "updateTime", Date.class,new Date()); // 起始版本 3.3.0(推荐使用)
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        //增加的时候实现填充
        this.strictInsertFill(metaObject, "updateTime", Date.class,new Date()); // 起始版本 3.3.0(推荐使用)
    }
}

         8.4 结果

新增:

修改:

 9.乐观锁

分布式场景下可能会出现脏读  幻读

乐观锁:顾名思义乐观,它总是认为不会出现问题,无论干什么都不去上锁!如果出现问题,再次更新值测试,效率低,容错率高

悲观锁:顾名思义悲观,它总是认为会出现问题,无论干什么都会加上锁!再去操作,效率低,容错率高 

乐观锁实现方式: 

  • 取出记录是,获取当前version
  • 更新事,带上这个version
  • 执行更新事,set version=newVersion where version =oldVersion
  • 如果version不对,就更新失败

        9.1 数据库新增字段(version)

        9.2  实体类新增字段(version)

    /*
     * 乐观锁
     * 数据库需要给此字段设置默认值为1
     * 功能描述:
     * 任何操作都应该是乐观的,都觉得它不会出问题,
     * 从而不会对行,表进行锁定,一旦出现问题将无法解决
     * 与其相反的为悲观锁:效率低,容错高
     * @Author: Mr.Huang
     * @Date: 2022/5/17 16:08
     **/
    @Version
    private Integer version;

        9.3 编写MyBatisPlus的配置类

package com.example.mybatisplusday1.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * MyBatisPlus的配置类
 * @ClassName MyBatisPlusConfiguration
 * @Description TODO
 * @Author ACER
 * @Date 2022/5/17 16:11
 * @Version 1.0
 **/
@Configuration
public class MyBatisPlusConfiguration {
    /**
     * MyBatisPlus配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //乐观锁配置
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //分页插件配置
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return mybatisPlusInterceptor;
    }
}

        9.4 测试 

   /**
     * 功能描述:
     * MybatisPlus乐观锁
     * 测试乐观锁是否能够使用
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/17 16:01
     **/
    @Test
    void testversion(){
        //修改一个用户信息,根据id获取用户信息
        //模拟a用户去修改6L这个数据
        User user1 = usermapper.selectById(6L);
        user1.setName("张三");

        //模拟b用户去修改6L这个数据
        User user2 = usermapper.selectById(6L);
        user2.setName("李四");

        //a先修改用户
        usermapper.updateById(user1);
        //b后修改用户(李四修改失败)
        usermapper.updateById(user2);
    }

10.逻辑删除 

物理删除:从数据库中直接移除

逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效!delete=0 => delete=1 

管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!订单,不能直接删除的!

        10.1 数据库新增字段(deleted)

        10.2 实体类新增字段(deleted)

    /*
     * 功能描述:
     * 逻辑删除,并不是真的删除
     * @Param:
     * @Return:
     * @Author: Mr.Huang
     * @Date: 2022/5/17 16:37
     **/
    @TableLogic
    private Integer deleted;

        10.3 yml配置 

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl   #开启日志打印
    map-underscore-to-camel-case: true    #开启驼峰命名法 数据库中的字段为create_time单词之间用_隔开
  mapper-locations: classpath*:/mapper/*Mapper.xml  #扫描接口
  type-aliases-package: com.example.mybatisplusday1.entity  #别名
  global-config:
    db-config:
      logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

        10.4 测试 

    @Test
    void delete(){
        //1.按id删除,既可以按id删除,也可以按对象删除
        int result=usermapper.deleteById(14L);
    }

11. 代码生成器

实现代码的自动生成   mapper  service  mapper.xml   controller都是一次性全部生成

请查看:2022/5/25 Mybatis-Plus代码生成器(mybatis-plus-generat)配置模板_Abcdzzr的博客-CSDN博客

12.高级条件查询(条件构造器)

        12.1 条件构造器关系介绍

在这里插入图片描述

        12.2 介绍 

  1. 上图绿色框为抽象类abstract
  2. 蓝色框为正常class类,可new对象
  3. 黄色箭头指向为父子类关系,箭头指向为父类

        12.3 wapper介绍

  1. Wrapper : 条件构造抽象类,最顶端父类,抽象类中提供4个方法西面贴源码展示
  2. AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
  3. AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
  4. LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
  5. LambdaUpdateWrapper : Lambda 更新封装Wrapper
  6. QueryWrapper : Entity 对象封装操作类,不是用lambda语法
  7. UpdateWrapper : Update 条件封装,用于Entity对象更新操作

        12.3 API

官网:条件构造器 | MyBatis-Plus

在这里插入图片描述

        12.4 示例

    /**
     * 功能描述:
     * MybatisPlus(条件构造器)模糊查询
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/18 9:29
     **/
    @Test
    void selectBylike(){
        String name="";
        //wrapper.likeRight();      %在右边
        //wrapper.likeLeft();       %在左边
        //wrapper.like();           %%左右两边都有
        //   wrapper.like(true,"name",name);
        //第一个参数为判断name是否为空为空查全部不为空则按要求查
        QueryWrapper<User>wrapper=new QueryWrapper<>();
        wrapper.like(true,"name",name);
        List<User> users = usermapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
    /**
     * 功能描述:
     * MybatisPlus(条件构造器)区间查询
     * @Param: []
     * @Return: void
     * @Author: Mr.Huang
     * @Date: 2022/5/30 10:09
     **/
    @Test
    void selectByBetween(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.between("age",15,24);
        //所有的条件拼接默认都是and,只有当自己拼接了or才会以or的方式拼接
        wrapper.or().eq("name","方哥");
        wrapper.orderByDesc("age");
        List<User> users = usermapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
}

13.分页插件 

        13.1 编写MyBatisPlus的配置类

package com.example.mybatisplusday1.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * MyBatisPlus的配置类
 * @ClassName MyBatisPlusConfiguration
 * @Description TODO
 * @Author ACER
 * @Date 2022/5/17 16:11
 * @Version 1.0
 **/
@Configuration
public class MyBatisPlusConfiguration {
    /**
     * MyBatisPlus配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //乐观锁配置
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //分页插件配置
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return mybatisPlusInterceptor;
    }
}

        13.2 Page<>对象API

package com.baomidou.mybatisplus.extension.plugins.pagination;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import lombok.Setter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

/**
 * 简单分页模型
 *
 * @author hubin
 * @since 2018-06-09
 */
public class Page<T> implements IPage<T> {

    private static final long serialVersionUID = 8545996863226528798L;

    /**
     * 查询数据列表
     */
    protected List<T> records = Collections.emptyList();

    /**
     * 总数
     */
    protected long total = 0;
    /**
     * 每页显示条数,默认 10
     */
    protected long size = 10;

    /**
     * 当前页
     */
    protected long current = 1;

    /**
     * 排序字段信息
     */
    @Setter
    protected List<OrderItem> orders = new ArrayList<>();

    /**
     * 自动优化 COUNT SQL
     */
    protected boolean optimizeCountSql = true;
    /**
     * 是否进行 count 查询
     */
    protected boolean searchCount = true;
    /**
     * {@link #optimizeJoinOfCountSql()}
     */
    @Setter
    protected boolean optimizeJoinOfCountSql = true;
    /**
     * countId
     */
    @Setter
    protected String countId;
    /**
     * countId
     */
    @Setter
    protected Long maxLimit;

    public Page() {
    }

    /**
     * 分页构造函数
     *
     * @param current 当前页
     * @param size    每页显示条数
     */
    public Page(long current, long size) {
        this(current, size, 0);
    }

    public Page(long current, long size, long total) {
        this(current, size, total, true);
    }

    public Page(long current, long size, boolean searchCount) {
        this(current, size, 0, searchCount);
    }

    public Page(long current, long size, long total, boolean searchCount) {
        if (current > 1) {
            this.current = current;
        }
        this.size = size;
        this.total = total;
        this.searchCount = searchCount;
    }

    /**
     * 是否存在上一页
     *
     * @return true / false
     */
    public boolean hasPrevious() {
        return this.current > 1;
    }

    /**
     * 是否存在下一页
     *
     * @return true / false
     */
    public boolean hasNext() {
        return this.current < this.getPages();
    }

    @Override
    public List<T> getRecords() {
        return this.records;
    }

    @Override
    public Page<T> setRecords(List<T> records) {
        this.records = records;
        return this;
    }

    @Override
    public long getTotal() {
        return this.total;
    }

    @Override
    public Page<T> setTotal(long total) {
        this.total = total;
        return this;
    }

    @Override
    public long getSize() {
        return this.size;
    }

    @Override
    public Page<T> setSize(long size) {
        this.size = size;
        return this;
    }

    @Override
    public long getCurrent() {
        return this.current;
    }

    @Override
    public Page<T> setCurrent(long current) {
        this.current = current;
        return this;
    }

    @Override
    public String countId() {
        return this.countId;
    }

    @Override
    public Long maxLimit() {
        return this.maxLimit;
    }

    /**
     * 查找 order 中正序排序的字段数组
     *
     * @param filter 过滤器
     * @return 返回正序排列的字段数组
     */
    private String[] mapOrderToArray(Predicate<OrderItem> filter) {
        List<String> columns = new ArrayList<>(orders.size());
        orders.forEach(i -> {
            if (filter.test(i)) {
                columns.add(i.getColumn());
            }
        });
        return columns.toArray(new String[0]);
    }

    /**
     * 移除符合条件的条件
     *
     * @param filter 条件判断
     */
    private void removeOrder(Predicate<OrderItem> filter) {
        for (int i = orders.size() - 1; i >= 0; i--) {
            if (filter.test(orders.get(i))) {
                orders.remove(i);
            }
        }
    }

    /**
     * 添加新的排序条件,构造条件可以使用工厂:{@link OrderItem#build(String, boolean)}
     *
     * @param items 条件
     * @return 返回分页参数本身
     */
    public Page<T> addOrder(OrderItem... items) {
        orders.addAll(Arrays.asList(items));
        return this;
    }

    /**
     * 添加新的排序条件,构造条件可以使用工厂:{@link OrderItem#build(String, boolean)}
     *
     * @param items 条件
     * @return 返回分页参数本身
     */
    public Page<T> addOrder(List<OrderItem> items) {
        orders.addAll(items);
        return this;
    }

    @Override
    public List<OrderItem> orders() {
        return this.orders;
    }

    @Override
    public boolean optimizeCountSql() {
        return optimizeCountSql;
    }

    public static <T> Page<T> of(long current, long size, long total, boolean searchCount) {
        return new Page<>(current, size, total, searchCount);
    }

    @Override
    public boolean optimizeJoinOfCountSql() {
        return optimizeJoinOfCountSql;
    }

    public Page<T> setSearchCount(boolean searchCount) {
        this.searchCount = searchCount;
        return this;
    }

    public Page<T> setOptimizeCountSql(boolean optimizeCountSql) {
        this.optimizeCountSql = optimizeCountSql;
        return this;
    }

    @Override
    public long getPages() {
        // 解决 github issues/3208
        return IPage.super.getPages();
    }

    /* --------------- 以下为静态构造方式 --------------- */
    public static <T> Page<T> of(long current, long size) {
        return of(current, size, 0);
    }

    public static <T> Page<T> of(long current, long size, long total) {
        return of(current, size, total, true);
    }

    public static <T> Page<T> of(long current, long size, boolean searchCount) {
        return of(current, size, 0, searchCount);
    }

    @Override
    public boolean searchCount() {
        if (total < 0) {
            return false;
        }
        return searchCount;
    }

    /**
     * --begin------------- 未来抛弃移除的方法 -------------begin--
     * 该部分属性转移至 {@link PageDTO}
     */
    @Deprecated
    public String getCountId() {
        return this.countId;
    }

    @Deprecated
    public Long getMaxLimit() {
        return this.maxLimit;
    }

    @Deprecated
    public List<OrderItem> getOrders() {
        return this.orders;
    }

    @Deprecated
    public boolean isOptimizeCountSql() {
        return this.optimizeCountSql;
    }

    @Deprecated
    public boolean isSearchCount() {
        return this.searchCount;
    }
    /** --end------------- 未来抛弃移除的方法 -------------end-- */

}

        13.3 示例

package com.example.mybatisplusday1.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mybatisplusday1.entity.User;
import com.example.mybatisplusday1.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * User控制器
 * @ClassName UserController
 * @Description TODO
 * @Author ACER
 * @Date 2022/5/17 17:08
 * @Version 1.0
 **/
@RestController
@CrossOrigin        //解决接口跨域问题
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 功能描述:
     * 条件查询并分页
     * @Param: [page, size, name]
     * @Return: com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.example.mybatisplusday1.entity.User>
     * @Author: Mr.Huang
     * @Date: 2022/5/30 11:14
     **/
    @GetMapping("/getUserList")
    public Page<User> getUsers(@RequestParam(value = "page",required = true,defaultValue = "1") Integer page,
                               @RequestParam(value = "size",required = true,defaultValue = "3")Integer size,
                               @RequestParam(value = "name",required = false)String name){
       // BaseMapper<User> baseMapper = userService.getBaseMapper();
        Page<User> pageinfo = new Page<>(page,size);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //判断条件值是否为空,如果不为空拼接条件
        if (!StringUtils.isEmpty(name)){
            //构建条件 模糊查询
            queryWrapper.like("name",name);
        }
        Page<User> page1 = userService.page(pageinfo, queryWrapper);
        //baseMapper.selectPage(pageinfo,queryWrapper);

        return page1;
    }
    //增加
    @PostMapping("/addUser")
    public String addbanana(@RequestBody User user){
        return userService.save(user)+"";
    }
    //删除
    @DeleteMapping("/deleteUser")
    public String deleteUser(@RequestBody User user){
        return userService.removeById(user)+"";
    }
    //修改
    @PutMapping("/updateUser")
    public String updateUser(@RequestBody User user){
        return userService.updateById(user)+"";
    }


}

码字不易,谢谢点赞关注。 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abcdzzr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值