mybatis-plus.学习和分析

01、Mybatis-plus的学习

01、官网

https://mp.baomidou.com/guide/

02、简介

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 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库

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

  • mysql,oracle,db2,h2,hsql,sqlite,postgresql,sqlserver,Phoenix,Gauss ,clickhouse,Sybase,OceanBase,Firebird,cubrid,goldilocks,csiidb
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库

03、官方视频

作者地址:https://www.imooc.com/u/7459484/courses?sort=publish

入门:https://www.imooc.com/learn/1130

进阶:https://www.imooc.com/learn/1171

权限管理系统:https://www.imooc.com/learn/1294

04、主流的ORM持久层框架

  • Mybatis

    • SQL语句可以自由控制,更加灵活,性能较高
    • SQL代码分离,阅读和维护。
    • 提供XML标签,之前编写动态SQL语句。
  • JPA

    • JPA移植性好
    • 提供很多CURD的方法,提高开发效率
    • 对象化程度较高
  • mybatis缺点

    • 简单CURD操作可能还需要我们自己去的编写SQL语句
    • XML有大量的SQL要维护
    • Mybatis自身的功能有限,但支持插件Plugin

这些mybatis问题如何解决呢?Mybatis-plus

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

05、Mybatis-plus的整体架构

在这里插入图片描述

06、在使用Mybatis-plus你必须要依赖Lombok

在这里插入图片描述

02、创建项目springboot +maven

01、依赖配置

  <!--lombok依赖,可以辅助项目的开发比如生成setter.getter和日志-->
  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
  </dependency>
  <!--mybatis依赖-->
  <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.4.2</version>
  </dependency>
  <!--mysql驱动依赖-->
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.26</version>
  </dependency>

02、在application.yml中配置数据源

# 配置数据库连接
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/kss-web-db?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: mkxiaoer

03、创建实体

package com.listudy.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.Date;

/**
  * @author li
 * @date 2021/11/10 21:03
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName("kss_user") // 指定实体和数据库表kss-user做映射
public class User extends Model<User> implements java.io.Serializable {
    // 用户id
    @TableId(type = IdType.AUTO)
    private Integer id;
    // 用户昵称
    private String nickname;
    // 用户密码
    private String password;
    // 用户收集
    private String telephone;
    // 用户的邮箱
    private String email;
    // 用户的头像
    private String avatar;
    // 用户的签名
    private String sign;
    // 创建时间
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    // 更新时间
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    // 用户的激活状态 1激活 0 未激活
    private Integer active;
    // 角色 admin 管理员 normal正常用户
    private String role;
}

04、新建一个Mapper

package com.listudy.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.listudy.entity.User;
import org.springframework.stereotype.Repository;


@Repository
public interface UserMapper extends BaseMapper<User> {

}

05、扫包

package com.listudy.config.mybatis;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//Spring boot方式
@Configuration
@MapperScan("com.listudy.mapper")
public class MybatisPlusConfig {

    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        //设置最大单页限制数量,默认 500 条,-1 不受限制
        paginationInnerInterceptor.setMaxLimit(500L);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }


}

03、为什么要继承BaseMapper

在这里插入图片描述

查询说明:BaseMapper -----T就是我们操作的具体的实体。比如:

package com.listudy.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.listudy.entity.User;
import org.springframework.stereotype.Repository;


@Repository
public interface UserMapper extends BaseMapper<User> {

}

BaseMapper 代表的是:只要有UserMapper继承了BaseMapper那么就自动拥有父类提供的能力。

一个类继承另外一个类作用:职责分担。

04、Mybatis-plus的常用注解

通过测试用例

package com.listudy;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.listudy.entity.Blog;
import com.listudy.enums.StatusEnum;
import com.listudy.entity.User;
import com.listudy.mapper.BlogMapper;
import com.listudy.mapper.UserMapper;
import com.listudy.service.user.IUserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
class KssWebProjectApplicationTests {

    @Autowired
    private UserMapper userMapper;
    @Test
    public void testSelect() {
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

}

执行打印的sql语句如下:

SELECT id,nickname,password,telephone,email,avatar,sign,create_time,update_time,active,role FROM kss_user

实体如下

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class KssUser extends Model<KssUser> implements java.io.Serializable {
	// 省略代码
}

从这里分析得出:mybatis-plus底层会根据实体的名字,自动变成小写,然后通过反射找到实体中所有的属性,然后拼接成SQL语句:

 SELECT id,nickname,password,telephone,email,avatar,sign,create_time,update_time,active,role FROM user

如果表名和实体不一致:统一指定,省去不必要的麻烦

@TableName(“数据表”)

如果属性和数据库的字段不一致:

@TableField(“数据字段”)

05、排除非表字段的三种方式)(重点

在开发中往往有时候,在开发的时候,在实体bean中增加一些额外的字段,但是这些字段只是去存储一些数据,但是不是数据库表的列。那么就告诉MP进行排除。

如果不排除你觉得会怎么样?

它就会把它当做SQL的一部分去自动拼接上,肯定是不对的。

排除方式1:transient

// 临时字段
private transient String remark;

排除方式2:static

// 临时字段
private static String remark;

排除方式3:@TableField(exist = false)(推荐

@TableField(exist = false)
private String remark;
  • static有一个问题,转换json的时候或者你要远程传递的属性的属性会排除在外
  • transient 被这个关键字修饰的字段,代表不会序列化到流中进行传递。比如:微服务RPC或者resttemplate传输的时候,被transient修饰的属性会自动忽略。

06、查询Wrapper

抽象父类:AbstractWrapper

查询Wrapper

  • QueryWrapper(如果多表关联查询用:QueryWrapper 为什么因为有别名的问题.)
  • LambdaQueryWrapper(推荐) 但是不万能?

更新Wrapper

  • UpdateWrapper

为什么没有InsertWrapper , 因为insert没有where条件

在开发中,除了根据id返回实体,还有多条件查询,关联查询,子查询等等。

一句话:AbstractWrapper是引来指定查询条件的类。

方法架构

在这里插入图片描述

得出结论:其实就给查询语句设置查询条件,的处理器。它把开发中所以的查询条件的规则都进行了封装

   /**
     * 查询(根据 columnMap 条件)
     *
     * @param columnMap 表字段 map 对象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根据 entity 条件,查询一条记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录
     * <p>注意: 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 Wrapper 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

01、传统的写法

定义一个接口:

package com.listudy.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.listudy.entity.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;


@Repository
public interface UserMapper {


    /**
     * 根据 entity 条件,查询一条记录
     */
    List<User> selectList(@Param("nickname") String username,
                          @Param("password")String password);

}

在UserMapper.xml定义如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.listudy.mapper.UserMapper">


    <select id="selectList" resultType="com.listudy.entity.User">
           select * from kss_user where nickname = #{nickname} and password = #{password}
    </select>

</mapper>

使用Mybatis-plus写法

  public List<User> findUserList(String username,String password){
        //QueryWrapper负责查询条件的和排序的类
        //where nickname = #{nickname} and password = #{password}
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("nickname",username);
        queryWrapper.eq("password",password);
        // 2:执行sql拼接条件
        // userMapper.selectList是来自己与BaseMapper<User>
        // 反射实体转换成User.class通过反射拿到它里面所有的属性拼接sql语句, select id,nickname,password where nickname='yykk' and password='12121545'
        List<User> list = userMapper.selectList(queryWrapper);
        return list;
    }

执行的SQL如下:

==>  Preparing: SELECT id,nickname,password,telephone,email,avatar,sign,create_time,update_time,active,role FROM kss_user WHERE (nickname = ? AND password = ?)
==> Parameters: yykk(String), 8c953f1d3dcb49afd4f3d365627149fd(String)

上面存在的问题

queryWrapper.eq("nickname",username);
queryWrapper.eq("password",password);

1、“nickname” 到底是数据库的列呢?还是实体的属性呢?

2、"nickname"很多时候会写错,但是开发者就不会往这里思考?

如何解决问题呢?

没有LambdaQueryWrapper来解决这个问题

public List<User> findUserList2(String username,String password){
        //QueryWrapper负责查询条件的和排序的类
        //where nickname = #{nickname} and password = #{password}
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
        lambdaQueryWrapper.eq(User::getNickname,username);
        lambdaQueryWrapper.eq(User::getPassword,password);
        // 2:执行sql拼接条件
        // userMapper.selectList是来自己与BaseMapper<User>
        // 反射实体转换成User.class通过反射拿到它里面所有的属性拼接sql语句, select id,nickname,password where nickname='yykk' and password='12121545'
        List<User> list = userMapper.selectList(lambdaQueryWrapper);
        return list;
    }

07、动态SQL

就是开发中,如果条件满足就拼接条件,如果不满足不拼接。这种动态SQL其实一般应用在:后台的这种复杂的SQL查询。

需求:

1:根据用户名模糊查询用户信息 username like ‘%xxx%’

2:并且查询出激活的用户 active = 1

3:并且查询角色等于超级管理员 role=admin

4:查询出注册时间在某个时间段的:create_time betwwend starttime and endtime;

注意:默认情况下查询的所有的用户,只有用户操作了才开始拼接条件.

实现步骤

1、查询所有数据,摒弃所有的条件,先把业务做通。

2、建设一个查询条件的vo,不要传递整个实体。

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class UserParamVo implements java.io.Serializable {

    // null或者""代表拼接条件 模糊条件
    private String username;
    // 1 激活 0未激活  null代表拼接条件
    private Integer active;
    // admin 是管理员  normal普通用户  null或者""代表拼接条件
    private String role;
    // 注册时间 开始时间
    private String starttime;
    // 注册时间 结束时间
    private String endtime;
}

01、第一种实现方案 - 原生的实现方案Mybatis+Xml来实现

用这种方案就告诉你一个道理:MP支持原生的mybatis+xml的方式。

实现步骤如下:

1:定义mp配置支持mybatis原生的xml文件的机制

# mybatis-plus的配置
mybatis-plus:
  configuration:
    # 开启mybatis日志执行sql打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    call-setters-on-nulls: true
    default-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler
  # 重点:告诉mybatis你的mapper.xml文件在那个位置,我会启动的过程找到这个配置文件进行加载  
  mapper-locations: classpath*:/mapper/*.xml
  # 别名映射,不建议使用,简写的东西往往很多麻烦的事情,写错了你都知道。告诉你在xml文件中只要是这个包下面的实体,你都用类名小写,省去书写的工作。
  type-aliases-package: com.listudy.entity
  type-enums-package: com.listudy.enums

在这里插入图片描述

2:定义一个接口方法

package com.listudy.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.listudy.entity.User;
import com.listudy.vo.UserParamVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;


@Repository
public interface UserMapper extends  BaseMapper<User> {


    /**
     * 根据userParamVo查询对应的用户信息
     * @param userParamVo
     * @return
     */
    public List<User> findUsers(UserParamVo userParamVo);

}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.listudy.mapper.UserMapper">


    <select id="findUsers" resultType="com.listudy.entity.User" parameterType="com.listudy.vo.UserParamVo">
        SELECT
            id,
            nickname,
            PASSWORD,
            telephone,
            email,
            avatar,
            sign,
            create_time,
            update_time,
            active,
            role
        FROM
            kss_user
        <where>
            <if test="username!=null and username!=''">
                AND  nickname LIKE #{username}
            </if>
            <if test="active!=null">
                AND active = #{active}
            </if>
            <if test="role!=null and role!=''">
                AND role = #{role}
            </if>
        </where>

    </select>


</mapper>
 @Test
    public void testSelectMybatisSQL() throws JsonProcessingException {
        // 1: 设置条件
        UserParamVo userParamVo = new UserParamVo();
        userParamVo.setUsername("yykk1");
        userParamVo.setActive(1);
        userParamVo.setRole("admin");
        List<User> userList = userMapper.findUsers(userParamVo);
        userList.forEach(System.out::println);
    }

02、第二种实现方案 - 实现方案MP+LambdaQueryWrapper来实现

用这种方案就告诉你一个道理:MP它很优秀确实可以帮做到单表的动态SQL查询,用一种面向对象的方式。

    public List<User> findUserList2(UserParamVo userParamVo) {
        //QueryWrapper负责查询条件的和排序的类
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
        lambdaQueryWrapper.eq(Optional.ofNullable(userParamVo.getActive()).isPresent(), User::getActive, userParamVo.getActive());
        lambdaQueryWrapper.eq(Optional.ofNullable(userParamVo.getRole()).isPresent(), User::getRole, userParamVo.getRole());
        lambdaQueryWrapper.like(!StringUtils.isEmpty(userParamVo.getUsername()), User::getNickname, userParamVo.getUsername());
        // 2:执行sql拼接条件
        lambdaQueryWrapper.orderByDesc(User::getCreateTime);
        // userMapper.selectList是来自己与BaseMapper<User>
        // 反射实体转换成User.class通过反射拿到它里面所有的属性拼接sql语句, select id,nickname,password where nickname='yykk' and password='12121545'
        List<User> list = userMapper.selectList(lambdaQueryWrapper);
        return list;
    }

    @Test
    public void testSelectMybatisSQL2() throws JsonProcessingException {
        // 1: 设置条件
        UserParamVo userParamVo = new UserParamVo();
        userParamVo.setUsername("yykk1");
        userParamVo.setActive(1);
        userParamVo.setRole("admin");
        List<User> userList = findUserList2(userParamVo);
        userList.forEach(System.out::println);
    }

03、第三种实现方案 - 采用Mybatis的Mapper+XML+LambdaQueryWrapper/QueryMapper来实现

用这种方案就告诉你一个道理:MP它很优秀,但是它不是万能的,复杂的关联查询是无能无能力。因为默认的BaserMapper值提供了一些单表常用,多表关联查询就必须还是得自己去编写SQL语句,进行混合使用,。当然你也可以不用,全部原生的写法。

01、使用原生的XML来完成

Mapper接口

package com.listudy.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.listudy.entity.User;
import com.listudy.vo.UserParamVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;


@Repository
public interface UserMapper extends  BaseMapper<User> {

     List<Map<String,Object>> findBlogsUsers();

}

xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.listudy.mapper.UserMapper">


    <select id="findBlogsUsers" resultType="java.util.Map">
            SELECT
                ku.*,
                count( 1 ) AS num
            FROM
                kss_blog kb
                LEFT JOIN kss_user ku ON kb.user_id = ku.id
            GROUP BY kb.user_id
            ORDER BY num DESC
    </select>


</mapper>

测试

    //关联查询 + Mybatis+xml
    @Test
    public void testSelectMybatisSQL3() throws JsonProcessingException {
        List<Map<String,Object>> userList = userMapper.findBlogsUsers();
        userList.forEach(System.out::println);
    }


返回map一定要特别的小心取值问题,因为map的key是直接根据你表的列名进行设定的。

map.get("createTime")而是map.get("create_time");

如何解决用别名

<select id="findBlogsUsers" resultType="java.util.Map">
            SELECT
                ku.id,
                ku.nickname,
                ku.password,
                ku.telephone,
                ku.email,
                ku.avatar,
                ku.sign,
                ku.create_time as ctime,
                ku.update_time as uptime,
                ku.active,
                ku.role,
                count( 1 ) AS num
            FROM
                kss_blog kb
                LEFT JOIN kss_user ku ON kb.user_id = ku.id
            GROUP BY kb.user_id
            ORDER BY num DESC
    </select>

上面存在一个问题

分页必须自己去写,很繁琐,

02、使用MpQueryMapper来完成分页

导入分页插件

package com.listudy.config.mybatis;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//Spring boot方式
@Configuration
@MapperScan("com.listudy.mapper")
public class MybatisPlusConfig {

    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        //设置最大单页限制数量,默认 500 条,-1 不受限制
        paginationInnerInterceptor.setMaxLimit(500L);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }


}
03、使用关联查询 +QueryMapper来完成分页
分析
userMapper.selectPage(page,wrapper)

上面这个分页查询方法,只能针对当前自己的实体,它很好支持和处理,但是关联查询就不行。

  • 上面代码的底层:会通过拦截器PageIntercetor进行拦截处理会把执行sql和求count自动发起和执行
  • 同时根据返回的总数,字段换算出来pages,total,current,
  • 数据放在 records中
  • 用Page整个包裹返回
规律
  • sql (自动通过反射去生成)
  • 分页条件
  • page
04、如果关联查询呢?只不过sql语句自己去写
  • sql (自己通过mapper.xml)文件自己去写
  • 分页条件(用mp)
  • page(用mp)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值