Mybatis-Plus --------学习笔记(详解)

目录

一、Mybatis-Plus简介

1.Mybatis-Plus概念

2.Mybatis-Plus的特性

3.支持的数据库

二、代码生成器

1.搭建一个SpringBoot框架

2.连接数据库(配置application.yml)

3.使用代码生成器

三、Mybatis-Plus主要的注解

1.@TableName

2.@TableId

3.@TableField

4.@Version

5.@EnumValue

6.@TableLogic

7.@KeySequence

四、条件构造器

常用条件连接

1.eq(等于=)

2.ne(不等于<>)

3.get(大于>)

4.lt(小于<)

6.like(like '%值%')

7.notLike(not like '%值%')

8.in

9.groupBy(分组)

五、执行SQL分析打印

1.在pom.xml文件中将p6spy依赖引入

2.application.yml配置

3.spy.properties配置

六、CRUD 接口

1.Service CRUD 接口及相关方法

1.1Save(插入)

1.2SaveOrUpdate(修改插入)

1.3Remove(删除)

1.4Update(更新)

1.5Get

1.6List

1.7Page

1.8Count

2.Mapper CRUD 接口

2.1Inser(插入)

2.2Delete

2.3Update

2.4Select

七、Mybatis-Plus——实现增删改查

1.插入数据

2.删除数据

3.更新数据

4.查询数据

5.分页查询

5.1添加分页插件(在com.egcxy.config下面)

5.2实现分页

6.多表关联查询和分页查询

6.1建立order实体和orderVo实体

6.2建立mapper文件

6.3mapper配置文件

6.4测试代码


一、Mybatis-Plus简介

1.Mybatis-Plus概念

官网:MyBatis-Plus (baomidou.com)icon-default.png?t=N7T8https://baomidou.com/

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

MyBatis-Plus提供了通用的mapper和service,可以在不编写任何SQL语句的情况下,快速的实现对单表的CRUD.批量、逻辑删除、分页等操作。

2.Mybatis-Plus的特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 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.支持的数据库

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

(下面演示的代码示例,涉及到的数据库采用的MySQL)

二、代码生成器

1.搭建一个SpringBoot框架

①创建一个新的项目

这里的依赖你可以选择加也可以不加,点击创建即可(我这里没有加)

②添加需要用到的依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.0.33</version>
            <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>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>p6spy</groupId>
            <artifactId>p6spy</artifactId>
            <version>3.9.1</version>
        </dependency>
<!--          阿里数据源  -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.2</version>
        </dependency>
        <!--  mybatis-plus代码生成器  -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--  模板引擎  -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>
    </dependencies>

2.连接数据库(配置application.yml)

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demol2?CharacterEncoding=UTF-8
    password: 423423
    username: root

3.使用代码生成器

在com.ecgxy.config包下创建一个CodeGenerato生成类

package com.egcxy.config;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;


import java.util.ArrayList;
import java.util.List;

public class CodeGenerator {
    public static void main(String[] args) {
        //数据库连接
        String url = "jdbc:mysql://localhost:3306/demol2?CharacterEncoding=UTF-8";//数据库url
        String username = "root";//账号
        String password = "423423";//密码
        String module = "";//项目模块名,如果是有父项目的话,需要配置。
        //全局配置参数
        String author = "huangwei";//作者
        String outputDir = System.getProperty("user.dir")+ "/" + module +"/src/main/java";//指定输出目录
        //包配置参数
        String parent = "com.egcxy";//父包名
        String moduleName = "";//父包模块名
        String entity = "entity";//Entity 实体类包名
        String mapper = "mapper";//Mapper 包名
        String mapperXml = "mapper.xml";//Mapper XML 包名
        String service = "service";//Service 包名
        String serviceImpl = "service.Impl";//Service Impl 包名
        String controller = "controller";//Controller 包名*/
        //要生成的数据库表
        List<String> tables = new ArrayList<>();
        tables.add("account");
        tables.add("dep");
        tables.add("phone");
        tables.add("stu");
        tables.add("user");
        tables.add("brand");

        //开始生成
        FastAutoGenerator.create(url,username,password)
                //全局配置
                .globalConfig(builder -> {
                    builder.author(author)
                            .outputDir(outputDir)
                            .disableOpenDir() //生成之后不打开目录
                            /*.enableSwagger()//开启swagger*/
                            .fileOverride() // 覆盖已生成文件
                            .dateType(DateType.ONLY_DATE) //定义生成的实体类中日期类型 DateType.ONLY_DATE 默认值: DateType.TIME_PACK
                            .commentDate("yyyy-MM-dd");//注释日期

                })
                //包配置
                .packageConfig(builder -> {
                    builder.parent(parent)
                            .moduleName(moduleName)
                            .entity(entity)
                            .mapper(mapper)
                            .xml(mapperXml)
                            .service(service)
                            .serviceImpl(serviceImpl)
                            .controller(controller);
                })
                //策略配置
                .strategyConfig(builder -> {
                    builder.addInclude(tables)
//                            .addTablePrefix("sys_") // 设置过滤表前缀
                            //开启生成实体类
                            .entityBuilder()
                            .enableLombok()//开启 lombok 模型
                            .enableTableFieldAnnotation()//开启生成实体时生成字段注解
                            //开启生成mapper
                            .mapperBuilder()
                            //.enableBaseResultMap()//启用 BaseResultMap 生成
                            .superClass(BaseMapper.class)//设置父类
                            .enableMapperAnnotation()//开启 @Mapper 注解
                            .formatMapperFileName("%sMapper")//格式化 mapper 文件名称
                            .formatXmlFileName("%sMapper")//格式化 xml 实现类文件名称
                            //开启生成service及impl
                            .serviceBuilder()
                            .formatServiceFileName("%sService")//格式化 service 接口文件名称
                            .formatServiceImplFileName("%sServiceImpl")//格式化 service 实现类文件名称
                            //开启生成controller
                            .controllerBuilder()
                            // 映射路径使用连字符格式,而不是驼峰
                            //.enableHyphenStyle()
                            .formatFileName("%sController")//格式化文件名称
                            .enableRestStyle();
                })
                .templateEngine(new VelocityTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                //.templateConfig(builder -> builder.controller(""))//关闭生成controller
                .execute();
    }
}

生成的代码结构如下:

三、Mybatis-Plus主要的注解

1.@TableName

  • 描述:表名注解,标识实体类对应的表
  • 使用位置:实体类
  • 使用案例:
package com.egcxy.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
@Getter
@Setter
@TableName("user")
public class User1 {
    private Long id;
    private String name;
    private Integer age;
    private Integer gender;
}
  • 相关属性:
属性类型必须指定默认值描述
valueString""表名
schemaString""schema
keepGlobalPrefixbooleanfalse是否保持使用全局的 tablePrefix 的值(当全局 tablePrefix 生效时)
resultMapString""xml 中 resultMap 的 id(用于满足特定类型的实体类对象绑定)
autoResultMapbooleanfalse是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建与注入)
excludePropertyString[]{}需要排除的属性名

2.@TableId

  • 描述:主键注解
  • 使用位置:实体类主键字段
  • 使用案例:
package com.egcxy.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
@Getter
@Setter
@TableName("user")
public class User1 {
    //这个注解是用来申明主键,里面的type是用来声明这是一个什么样的主键
    @TableId(type = IdType.AUTO)//自增的主键id
    private Long id;
    private String name;
    private Integer age;
    private Integer gender;
}
  • 相关属性:
    属性类型必须指定默认值描述
    valueString""主键字段名
    typeEnumIdType.NONE指定主键类
  • IdType常使用的值:

描述
AUTO数据库 ID 自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert 前自行 set 主键值
ASSIGN_ID分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)

3.@TableField

  • 描述:字段注解(非主键)
  • 使用案例:
package com.egcxy.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
@Getter
@Setter
@TableName("user")
public class User1 {
    //这个注解是用来申明主键,里面的type是用来声明这是一个什么样的主键
    @TableId(type = IdType.AUTO)//自增的主键id
    private Long id;
    @TableField("nickname")
    private String name;
    private Integer age;
    private Integer gender;
}
  • 主要相关属性
    属性类型必须指定默认值描述
    valueString""数据库字段名
    existbooleantrue是否为数据库表字段
    conditionString""字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s}参考(opens new window)
    updateString""字段 update set 部分注入,例如:当在version字段上注解update="%s+1" 表示更新时会 set version=version+1 (该属性优先级高于 el 属性)
    nsertStrategyEnumFieldStrategy.DEFAULT举例:NOT_NULL
    insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
    updateStrategyEnumFieldStrategy.DEFAULT举例:IGNORED
    update table_a set column=#{columnProperty}
    whereStrategyEnumFieldStrategy.DEFAULT举例:NOT_EMPTY
    where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
    fillEnumFieldFill.DEFAULT字段自动填充策略
    selectbooleantrue是否进行 select 查询

4.@Version

  • 描述:乐观锁注解、标记 @Version 在字段上

5.@EnumValue

  • 描述:普通枚举类注解(注解在枚举字段上)

6.@TableLogic

  • 描述:表字段逻辑处理注解(逻辑删除)
  • 相关属性
属性类型必须指定默认值描述
valueString""逻辑未删除值
delvalString""逻辑删除值

7.@KeySequence

  • 描述:序列主键策略 oracle
  • 属性:value、dbType
  • 相关属性:
属性类型必须指定默认值描述
valueString""序列名
dbTypeEnumDbType.OTHER数据库类型,未配置默认使用注入 IKeyGenerator 实现,多个实现必须指定

四、条件构造器

Wrapper:条件构造器,最顶端的一个类

AbstractWrapper:用于sql语句条件的封装,主要是封装where条件

QueryWrapper:查询条件封装,继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件及 LambdaQueryWrapper, 可以通过 new QueryWrapper().lambda() 方法获取

UpdateWrapper:更新条件封装,继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件及 LambdaUpdateWrapper, 可以通过 new UpdateWrapper().lambda() 方法获取!

AbstractLambdaWrapper:具有Lambda语法的条件封装

LambdaQueryWrapper:具有Lambda语法查询条件封装

LambdaUpdateWrapper:具有Lambda语法更新条件封装

常用条件连接

1.eq(等于=)

eq(R column, Object val)
eq(boolean condition, R column, Object val)

使用例如:eq("name"."xiaoming")=======>name='xiaoming'

QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("name","xiaoming1");

2.ne(不等于<>)

ne(R column, Object val)
ne(boolean condition, R column, Object val)

例如:ne("name"."xiaoming")=======>name<>'xiaoming'

     QueryWrapper wrapper = new QueryWrapper<>();
     wrapper.ne("name","xiaoming1");

3.get(大于>)

gt(R column, Object val)
gt(boolean condition, R column, Object val)

例如:gt("age"."18") =======> ge>18

        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.gt("age",18);

4.lt(小于<)

lt(R column, Object val)
lt(boolean condition, R column, Object val)

例如:lt("age"."18") =======> ge<18

        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.lt("age",18);

5.between

between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)

例如:between("age",18,30) ====> age between 18 and 30

    QueryWrapper<Tests> testsQueryWrapper = new QueryWrapper<>();
    testsQueryWrapper.between("age",18,35);

6.like(like '%值%')

like(R column, Object val)
like(boolean condition, R column, Object val)

例如:like("name","美") ====> name like '%美%'

7.notLike(not like '%值%')

notLike(R column, Object val)
notLike(boolean condition, R column, Object val)

例如:notLike("name","美") ====> name not  like '%美%'

8.in

in(R column, Collection<?> value)
in(boolean condition, R column, Collection<?> value)
  • 字段 IN (value.get(0), value.get(1), ...)
  • 例如:in("age",{1,2,3}) ====> age in (1,2,3)
in(R column, Object... values)
in(boolean condition, R column, Object... values)
  • 字段 IN (v0, v1, ...)
  • 例如:in("age",10,20,30) ===> age in (10,20,30)

9.groupBy(分组)

groupBy(R... columns)
groupBy(boolean condition, R... columns)
  • 分组:GROUP BY 字段, ...
  • 例如: groupBy("id","name") ====> group by id,name

五、执行SQL分析打印

1.在pom.xml文件中将p6spy依赖引入

<dependency>
     <groupId>p6spy</groupId>
     <artifactId>p6spy</artifactId>
     <version>3.9.1</version>
</dependency>

2.application.yml配置

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource

    #driver-class-name: com.mysql.cj.jdbc.Driver
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost:3306/demol2?CharacterEncoding=UTF-8
#    url: jdbc:mysql://localhost:3306/demol2?CharacterEncoding=UTF-8
    password: 423423
    username: root
  main:
    banner-mode: off #关闭springboot启动图标
mybatis-plus:
  config-location:
    log-impl: org.apache.ibatis.logging.stdout.Std0utImpl #打印SQL到控制台
  global-config:
    banner: off #关闭mybatisplus启动图标

3.spy.properties配置

#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

六、CRUD 接口

这里主要讲解经常使用到的接口

1.Service CRUD 接口及相关方法

  • 通用 Service CRUD 封装IService (opens new window)接口,进一步封装 CRUD 采用 get查询单行 、remove删除 、list查询集合、 page分页 前缀命名方式区分 Mapper 层避免混淆,
  • 泛型 T 为任意实体对象
  • 建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类
  • 对象 Wrapper 为 条件构造器

1.1Save(插入)

// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

参数说明:

类型参数名描述
Tentity实体对象
Collection<T>entityList实体对象集合
intbatchSize插入批次数量

1.2SaveOrUpdate(修改插入)

// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

参数说明:

类型参数名描述
Tentity实体对象
Wrapper<T>updateWrapper实体对象封装操作类 UpdateWrapper
Collection<T>entityList实体对象集合
intbatchSize插入批次数量

1.3Remove(删除)

// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

参数说明:

类型参数名描述
Wrapper<T>queryWrapper实体包装类 QueryWrapper
Serializableid主键 ID
Map<String, Object>columnMap表字段 map 对象
Collection<? extends Serializable>idList主键 ID 列表

1.4Update(更新)

// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

参数说明:

类型参数名描述
Wrapper<T>updateWrapper实体对象封装操作类 UpdateWrapper
Tentity实体对象
Collection<T>entityList实体对象集合
intbatchSize更新批次数量

1.5Get

// 根据 id 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

参数说明:

类型参数名描述
Serializableid主键 ID
Wrapper<T>queryWrapper实体对象封装操作类 QueryWrapper
booleanthrowEx有多个 result 是否抛出异常
Tentity实体对象
Function<? super Object, V>mapper转换函数

1.6List

// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

参数说明:

类型参数名描述
Wrapper<T>queryWrapper实体对象封装操作类 QueryWrapper
Collection<? extends Serializable>idList主键 ID 列表
Map<String, Object>columnMap表字段 map 对象
Function<? super Object, V>mapper转换函数

1.7Page

// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

参数说明:

类型参数名描述
IPage<T>page翻页对象
Wrapper<T>queryWrapper实体对象封装操作类 QueryWrapper

1.8Count

// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);

参数说明:

类型参数名描述
Wrapper<T>queryWrapper实体对象封装操作类 QueryWrapper

2.Mapper CRUD 接口

  • 通用 CRUD 封装BaseMapper (opens new window)接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器
  • 泛型 T 为任意实体对象
  • 参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键
  • 对象 Wrapper 为 条件构造器

2.1Inser(插入)

// 插入一条记录
int insert(T entity);

参数说明:

类型参数名描述
Tentity实体对象

2.2Delete

// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

参数说明:

类型参数名描述
Wrapper<T>wrapper实体对象封装操作类(可以为 null)
Collection<? extends Serializable>idList主键 ID 列表(不能为 null 以及 empty)
Serializableid主键 ID
Map<String, Object>columnMap表字段 map 对象

2.3Update

// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

参数说明:

类型参数名描述
Tentity实体对象 (set 条件值,可为 null)
Wrapper<T>updateWrapper实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)

2.4Select

// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)

参数说明:

类型参数名描述
Serializableid主键 ID
Wrapper<T>queryWrapper实体对象封装操作类(可以为 null)
Collection<? extends Serializable>idList主键 ID 列表(不能为 null 以及 empty)
Map<String, Object>columnMap表字段 map 对象
IPage<T>page分页查询条件(可以为 RowBounds.DEFAULT)

七、Mybatis-Plus——实现增删改查

1.插入数据


@SpringBootTest
class Mybatispuls001ApplicationTests {
    @Autowired
    User1Service user1Service;
    @Autowired
    User1Mapper user1Mapper;
//    @Autowired
//    UsersMapper usersMapper;

    @Test
    void contextLoads() {
        //插入数据
        User1 user = new User1();
        user.setAge(10);
        user.setName("花花");
        user.setGender(1);
        // mapper层插入
        user1Mapper.insert(user);
        Long id = user.getId();
        System.out.println("id" + id);

        //这里是service中封装的插入方法
//        boolean isSuccess = user1Service.save(user);
//        Long id = user.getId();
//        System.out.println("返回结果" + isSuccess + "id" + id);

        //伪批量插入
        List<User1> user1List = new ArrayList<>();
        for (int i = 10; i < 20; i++) {
            User1 user1 = new User1();
            user1.setAge(10 + i);
            user1.setGender(1 + i);
            user1.setName("xiaoming" + i);
            user1List.add(user1);
        }
        boolean isSuccess = user1Service.saveBatch(user1List);
        System.out.println("返回结果" + isSuccess);


        //批量保存或者更新
        List<User1> user1List1 = new ArrayList<>();
        for (int i = 3; i < 10; i++) {
            User1 user1 = new User1();
            user1.setAge(10 + i);
            user1.setGender(1 + i);
            user1.setName("xiaoming" + i);
            user1List.add(user1);
        }
        boolean isSuccess1 = user1Service.saveOrUpdateBatch(user1List1);
        System.out.println("返回结果" + isSuccess);
//        user1Service.saveOrUpdateBatch();//可以指定批量的大小
    }

}

2.删除数据

    @Test
    void deleteTest() {
        //Mapper层删除功能
        //1.1根据主键id删除数据(直接传id)
        int count = user1Mapper.deleteById(9L);
        System.out.println("删除了:" + count + "条数据");

        //1.2根据主键id删除数据(传实体类)
        User1 user = new User1();
        user.setId(8L);
        int count1 = user1Mapper.deleteById(user);
        System.out.println("删除了:" + count1 + "条数据");

        //1.3根据主键id批量删除数据
        List<Long> ids = new ArrayList<>();
        ids.add(1L);
        ids.add(2L);
        //delete from t_user where id in ids
        user1Mapper.deleteBatchIds(ids);

        //通过构造器
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.ne("name","xiaoming1");
        wrapper.gt("age",11);
        //delete from t_user where (name="xiaoming1" and age=11)
        user1Mapper.delete(wrapper);

        //使用lambda表达式删除数据
        user1Mapper.delete(new QueryWrapper<User1>()
                .lambda()
                .eq(User1::getName,"xiaoming1")
                .eq(User1::getAge,11)
        );

        //使用map设置条件删除
        Map<String,Object> col = new HashMap<>();
        col.put("name","xiaoming2");
        col.put("age",12);
        int count2 = user1Mapper.deleteByMap(col);
        System.out.println("删除了:" + count2 + "条数据");
    }

3.更新数据

    @Test
    void updateTest() {
        //更新数据
        //Mapper层更新
       User1 user = User1.builder()
               .name("小小")
               .id(5L)
               .gender(0)
               .build();
       int count = user1Mapper.updateById(user);
        System.out.println("更新了:" + count + "条数据");

        //通过wrapper进行跟新
        User1 user1 = User1.builder()
                .name("花花")
                .gender(0)
                .build();
        UpdateWrapper<User1> wrapper = new UpdateWrapper<>();
        wrapper.eq("age",13);
        int count1 = user1Mapper.update(user1,wrapper);
        System.out.println("更新了:" + count1 + "条数据");

        //service层更新数据
        UpdateWrapper<User1> user1UpdateWrapper = new UpdateWrapper<>();
        user1UpdateWrapper.set("name","xixi");
        user1UpdateWrapper.eq("id",5L).eq("age",13);
        boolean isSuccess = user1Service.update(user1UpdateWrapper);
        System.out.println(isSuccess);
    }

4.查询数据

    @Test
    void selectTest() {
        //查询数据
        //Mapper层查询
        //根据主键id查询
        User1 user = user1Mapper.selectById(5L);
        System.out.println(user.toString());

        //通过构造wrapper条件查询一条数据
        QueryWrapper<User1> queryWrapper = new QueryWrapper<>();
        //设置查询字段:仅查询name、id字段
        queryWrapper.select("id","name");
        //添加查询条件
        queryWrapper.eq("id",6L);
        User1 user1 = user1Mapper.selectOne(queryWrapper);
        System.out.println(user1.toString());

        //根据主键id进行批量查询
        List<User1> user1List = user1Mapper.selectBatchIds(Arrays.asList(5L,6L,7L));
        System.out.println(user1List.toString());

        //通过wrapper组装查询条件,查询全部数据
        QueryWrapper<User1> queryWrapper1 = new QueryWrapper<>();
        //设置查询字段:仅查询name、id字段
        queryWrapper1.select("id","name");
        //添加查询条件
        queryWrapper1.eq("age",30);
        List<User1> users = user1Mapper.selectList(queryWrapper1);

        //根据columnMap设置查询挑条件
        Map<String,Object> colMap = new HashMap<>();
        colMap.put("name","xixi");
        colMap.put("age",13);
        //select * from t_user where name="xixi" and age=13
        List<User1> user1List1 = user1Mapper.selectByMap(colMap);

        //根据wrapper条件,查询记录总数
        QueryWrapper<User1> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("name","xixi").eq("age",13);
        long count = user1Mapper.selectCount(queryWrapper2);//获取总量
        System.out.println(count);

        //service层查询数据

        User1 user2 = user1Service.getById(5L);//根据id获取数据
        //通过wrapper查询一条数据,当结果出现多条数据的时候是会抛出异常
        QueryWrapper<User1> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.eq("name","xixi").eq("id",5L);
        //执行的sql语句:select * from t_user where id=5 and name = "xixi"
        User1 user3 = user1Service.getOne(queryWrapper3);

        //通过list开头的方法来查询多条数据
        //条件查询
        QueryWrapper<User1> queryWrapper4 = new QueryWrapper<>();
        queryWrapper4.eq("name","xixi").eq("id",5L);
        //执行的sql语句:select * from t_user where id=5 and name = "xixi"
        List<User1> user1s = user1Service.list(queryWrapper4);

        //根据id列表查询数据
        //执行的sql语句:select * from t_user where id in(5,6)
        List<User1> user1List2 = user1Service.listByIds(Arrays.asList(5L,6L));

        //通过map构造查询条件
        Map<String,Object> cloMap = new HashMap<>();
        cloMap.put("name","xixi");
        cloMap.put("age",13);
        //执行的sql语句:select * from t_user where age=13 and name = "xixi"
        List<User1> user1List3 = user1Service.listByMap(cloMap);
//
//        //获取查询总数
        QueryWrapper<User1> queryWrapper5 = new QueryWrapper<>();
        queryWrapper5.eq("name","xixi").eq("id",5L);
        user1Service.count(queryWrapper5);//获取查询总数
    }

5.分页查询

5.1添加分页插件(在com.egcxy.config下面)

package com.egcxy.config;

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

@Configuration
@MapperScan("com.egcxy.mapper")
public class MybatisPlusConfig {

    /**
     * 添加分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
        //interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
        return interceptor;
    }
}

5.2实现分页

 //mapper层的分页查询
        QueryWrapper<User1> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("age",30);
        Page<User1> page = new Page<>(2,10);//查询第二页,每页10条数据
        page = user1Mapper.selectPage(page,queryWrapper);
        System.out.println("总共记录数:" + page.getTotal());
        System.out.println("总共多少页:" + page.getPages());
        System.out.println("当前页码:" + page.getCurrent());
        //获取当前数据
        List<User1> user1s = page.getRecords();
        user1s.forEach(System.out::println);
        //service层分页查询
        QueryWrapper<User1> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("age",30);
        Page<User1> page = new Page<>(2,10);//查询第二页,每页10条数据
        page = user1Service.page(page,queryWrapper);
        System.out.println("总共记录数:" + page.getTotal());
        System.out.println("总共多少页:" + page.getPages());
        System.out.println("当前页码:" + page.getCurrent());
       //获取当前数据
        List<User1> user1s = page.getRecords();
        user1s.forEach(System.out::println);

6.多表关联查询和分页查询

6.1建立order实体和orderVo实体

@Data
@Getter
@Setter
@TableName("t_order")
public class Order {
    private Long id;
    private Long orderId;
    private Long userId;//用户id
    private String goodsName;//商品名称
    private BigDecimal goodsPrice;//商品价格
}
@Data
@Getter
@Setter
public class OrderVo {
    private Long orderId;
    private Long userId;//用户id
    private String goodsName;//商品名称
    private BigDecimal goodsPrice;//商品价格
    private String userName;
    private Integer userAge;
    private Integer userGender;
}

6.2建立mapper文件

@Mapper
public interface User1Mapper extends BaseMapper<User1> {
    //查询订单列表
    List<OrderVo> selectOrders();
    //关联分页查询
    IPage<OrderVo> selectOrderPage(IPage<OrderVo> page, @Param(Constants.WRAPPER) QueryWrapper<OrderVo> wrapper);// @Param绑定参数
}

6.3mapper配置文件

<?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.egcxy.mapper.User1Mapper">
    <resultMap id="orderMap" type="com.egcxy.entity.OrderVo">
        <result property="userName" column="name"></result>
        <result property="userAge" column="age"></result>
        <result property="userGender" column="gender"></result>
        <result property="orderId" column="order_id"></result>
        <result property="userId" column="user_id"></result>
        <result property="goodsName" column="goods_name"></result>
        <result property="goodsPrice" column="goods_price"></result>
    </resultMap>
<!--    <select id="selectOrders" resultMap="orderMap">-->
<!--        select o.order_id,o.user_id,o.goods_name,o.goods_price,u.name,u.age,u.gender-->
<!--        from t_order as o left join t_user as u on o.user_id=u.id;-->
<!--    </select>-->
    <!--分页查询,${ew.customSqlSement}这个可以实现分页-->
    <select id="selectOrderPage" resultMap="orderMap">
        select o.order_id,o.user_id,o.goods_name,o.goods_price,u.name,u.age,u.gender
        from t_order as o left join t_user as u on o.user_id=u.id
        ${ew.customSqlSegment}
    </select>
</mapper>

6.4测试代码

        //多表关联查询
        //需求:假设前端需要展示数据:订单号、商品名称、商品价格、下单用户名、下单用户年龄、性别
        //执行的sql语句:select o.order_id,o.user_id,o.goods_name,o.goods_price,u.name,u.age,u.gender from t_order as o left join t_user as u on o.user_id=u.id;
        List<OrderVo> orderVos =  user1Mapper.selectOrders();
        orderVos.forEach(System.out::println);

        //关联分页查询
        //查询第一页,每页数据显示10条
        Page<OrderVo> page = new Page<>(1,10);
        //需要手动关闭关闭qal优化(${ew.customSqlSegment}),如果不关闭就只会查询主表
        page.setOptimizeCountSql(false);
        //组装查询条件:age=30
        QueryWrapper<OrderVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("age",18);
        IPage<OrderVo> page1 = user1Mapper.selectOrderPage(page,queryWrapper);
        System.out.println("总共记录数:" + page1.getTotal());
        System.out.println("总共多少页:" + page1.getPages());
        System.out.println("当前页码:" + page1.getCurrent());
        //System.out.println("当前查询数据:" + page1.getRecords());
        List<OrderVo> orderVos1 = page.getRecords();
        orderVos1.forEach(System.out::println);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值