欢迎光临
我们一直在努力

MyBatis-Plus基础使用

文章目录

  • 1. MyBatis-Plus 入门
    • 1.1 简介
    • 1.2 支持数据库
    • 1.3 核心优势
    • 1.4 架构
  • 2. 快速搭建工程(Spring Boot 整合)
    • 2.1 环境准备
    • 2.2 建库建表
    • 2.3 Maven 依赖
    • 2.4 application.yml 配置
    • 2.5 实体类 + 注解
    • 2.6 Mapper 接口
    • 2.7 启动类
  • 3. 常见配置
    • 3.1 configLocation
    • 3.2 mapperLocations
    • 3.3typeAliasesPackage
    • 3.4 mapUnderscoreToCamelCase
  • 4. 通用CRUD
    • 4.1 插入操作
      • 4.1.1 方法定义
      • 4.1.2 测试用例
      • 4.1.3 MP*主键生成策略
        • 1)自增主键:
        • 2)输入主键:
        • 3)使用UUID作为主键:
        • 4)采用雪花算法字符串作为主键:
        • 5)采用雪花算法数值作为主键:
    • 4.2 更新操作
      • 4.2.1 根据id更新
      • 4.2.2 根据条件更新
    • 4.3 删除操作
      • 4.3.1 根据id删除
      • 4.3.2 根据条件删除
      • 4.3.3 批量删除
    • 4.4 查询操作
      • 4.4.1 根据id查询
      • 4.4.2 批量查询
      • 4.4.3 查询一条记录
      • 4.4.4 查询记录条数
      • 4.4.5 查询多条记录
      • 4.4.6 分页查询
  • 5. 条件构造器
    • 5.1 基本比较操作
    • 5.2 模糊查询
    • 5.3 逻辑查询
    • 5.4 字段查询
    • 5.5 排序

在这里插入图片描述

1. MyBatis-Plus 入门

1.1 简介

MyBatis-Plus(简称 MP) 是 MyBatis 的增强工具,只增强、不修改,在原生 MyBatis 基础上提供:

  • 内置通用 CRUD,无需写 XML
  • Lambda 条件构造,防字段写错
  • 分页、逻辑删除、主键策略、性能分析
  • 代码生成器,一键生成全套代码

愿景:成为 MyBatis 最好的搭档,1+1>2。

1.2 支持数据库

MySQL、Oracle、PostgreSQL、SQL Server、达梦、人大金仓等主流数据库。

1.3 核心优势

无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝滑

损耗小:启动即会自动注入基本 CRUD,性能基本无损耗,直接面向对象操作

强大的 CRUD 操作:内置通用 Mapper 通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作, 更有强大的条件构造器,满足各类使用需求

支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错

支持多种数据库:支持 MySQL MariaDB Oracle DB2 H2 HSQL SQLite Postgre SQLServer2005 SQLServer等多种数据库

支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 – Sequence),可自由配置,完美解决主键问题1

支持 XML 热加载:Mapper 对应的 XML支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动

支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD操作

支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )

支持关键词自动转义:支持数据库关键词(order key…)自动转义,还可自定义关键词

内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper Model Service Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用

内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List 查询

内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询

内置全局拦截插件:提供全表 delete update 操作智能分析阻断,也可自定义拦截规则,预防误操作

内置Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击

1.4 架构

在这里插入图片描述 MybatisPlus主要包含以下模块:

核心功能(core),基于Mybatis的封装,提供了Mybatis Plus的基础配置类与核心功能,如内置通用Mapper,

Lambda 表达式查询等。

注解(annotation),提供了Mybatis Plus中注解的定义。

扩展功能(extension),提供扩展及插件功能,包括分页插件,通用 Service扩展,性能分析插件等。

代码生成器(generator):通过代码生成器可以快速生成 Mapper接口 Entity实体类 Mapper XML Service

Controller 等各个模块的代码,极大的提升了开发效率。

执行流程:

(1)扫描注解Entity,反射提取注解信息如:表名称、字段名称等信息。

(2)分析注解信息并基于com.baomidou.mybatisplus.core.enums的SQL模板生成基本CRUD SQL。

(3)最后将这些SQL注入到Mybatis环境中。

因此Mybatis plus无需编写CRUD SQL语句,只需继承BaseMapper,魔术般的拥有了CRUD功能(通用CRUD)。

2. 快速搭建工程(Spring Boot 整合)

2.1 环境准备

JDK 17+ Maven 3.5.4+ MySQL 5.7 / 8.0 IDEA

2.2 建库建表

CREATE DATABASE mp CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

USE mp;

CREATE TABLE `tb_user` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_name` VARCHAR(20) NOT NULL COMMENT '用户名',
`password` VARCHAR(20) NOT NULL COMMENT '密码',
`name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
`age` INT DEFAULT NULL COMMENT '年龄',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
`deleted` TINYINT DEFAULT 0 COMMENT '逻辑删除 0未删 1已删',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO tb_user(user_name,password,name,age,email,birthday)
VALUES
('zhangsan','123456','张三',18,'test1@yh.cn','2025-01-01 10:00:00'),
('lisi','123456','李四',20,'test2@yh.cn','2025-01-02 10:00:00');

2.3 Maven 依赖

<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
<!– https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter-test –>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter-test</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!–mysql驱动–>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
</dependencies>

2.4 application.yml 配置

spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: 123456

# MP 配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 开启驼峰自动映射(默认true)
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # SQL 日志打印
global-config:
db-config:
id-type: assign_id # 主键策略:雪花算法
logic-delete-field: deleted # 逻辑删除字段
logic-delete-value: 1
logic-not-delete-value: 0
mapper-locations: classpath:mapper/*.xml

2.5 实体类 + 注解

@Data
@TableName("tb_user")
public class User {
// 主键
@TableId(type = IdType.ASSIGN_ID)
private Long id;

// 字段映射(开启驼峰可省略)
private String userName;
private String password;
private String name;
private Integer age;
private String email;
private LocalDateTime birthday;

// 逻辑删除
@TableLogic
private Integer deleted;
}

2.6 Mapper 接口

只需继承 BaseMapper 即可拥有全部 CRUD

@Mapper
public interface UserMapper extends BaseMapper<User> {
// 无需写任何方法
}

2.7 启动类

@SpringBootApplication
@MapperScan("com.mp.mapper")//mapper接口所在的包
public class MpApplication {
public static void main(String[] args) {
SpringApplication.run(MpApplication.class, args);
}
}

3. 常见配置

在MP中有大量的配置,其中有一部分是Mybatis原生的配置,另一部分是MP的配置,详情:https://mybatis.plus/config/

3.1 configLocation

configLocation即MyBatis 配置文件位置,如果您有单独的 MyBatis 配置,请将其路径配置到 configLocation 中。 MyBatis Configuration 的具体内容请参考MyBatis 官方文档

示例:

1 在resources下创建mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<!–<plugins>–>
<!–<plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin>–>
<!–</plugins>–>

</configuration>

2 在application.yml下配置configLocations,如下:

spring:
application:
name: mp
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: 123456
logging:
level:
root: debug
mybatis-plus:
config-location: classpath:mybatisconfig.xml
mapper-locations: classpath*:mapper/*.xml

3.2 mapperLocations

mapperLocations即MyBatis Mapper 所对应的 mapper配置 文件位置,如果您在 Mapper 中有自定义方法(XML 中有自定义实现),需要进行该配置,告诉 Mapper 所对应的 XML 文件位置。 如果不配置mapperLocations时,mapper的xml文件存放路径需要和mapper class文件保持一致,文件名保持 一致

示例:

新建UserMapper.xml: 将此文件放在resources/com/mp/mapper下

<?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.mp.mapper.UserMapper">
<select id="findById" resultType="com.mp.pojo.User" parameterType="java.lang.Long">
select * from tb_user where id = #{id}
</select>
</mapper>

//在UserMapper接口类中新增findById方法
package com.mp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mp.pojo.User;

public interface UserMapper extends BaseMapper<User> {
User findById(Long id);
}

测试用例:

@Test
public void testFindById() {
User user = userMapper.findById(2L);
System.out.println(user);
}

也可以给mapper XML文件定义一个和mapper接口不同的存放路径 ,如下:

mybatis-plus:
config-location: classpath:mybatisconfig.xml
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.mp.pojo

Maven 多模块项目的扫描路径需以classpath*开头 (即加载多个 jar 包下的 XML 文件)

3.3typeAliasesPackage

设置MyBaits 别名包扫描路径,通过该属性可以给包中的类注册别名,注册后在 Mapper 对应的 XML 文件中可以直接使用类名,而不用使用全限定的类名(即 XML 中调用的时候不用包含包名)。

示例:

mybatis-plus:
config-location: classpath:mybatisconfig.xml
mapper-locations: classpath*:mybatis/mapper/*.xml
type-aliases-package: com.yh.mp.pojo

#配合 注解
@Alias("user")
public class User {

}
#映射文件
<select id="findById" resultType="user" parameterType="java.lang.Long">
select * from tb_user where id = #{id}
</select>

3.4 mapUnderscoreToCamelCase

  • 类型: boolean
  • 默认值: true

是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java

属性名 aColumn(驼峰命名) 的类似映射。

注意:

在 MyBatis-Plus 中此属性默认值为true,用于生成最终的 SQL 语句

如果您的数据库命名符合规则无需使用 @TableField 注解指定数据库字段名

测试:

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
@TableId("ID")
private Long id;
//@TableField("USER_NAME")
private String userName; //驼峰命名,则无需注解
//@TableField("PASSWORD")
private String password;
//@TableField("NAME")
private String name;
//@TableField("AGE")
private Integer age;
//@TableField("EMAIL")
private String email;
//@TableField("BIRTHDAY")
private LocalDateTime birthday;
}

如果项目中有符合驼峰规则的定义也有不符合的,此时建议统一使用@TableField。

注意: 如果使用mybatis-config.xml的同时在application.properties配置mybatis-plus.configuration则报错

Property 'configuration' and 'configLocation' can not specified with together

解决方法:

只使用一种配置方法。

本案例屏蔽mybatis-plus.configuration.map-underscore-to-camel-case=true,在mybatis-config.xml中配置 settings。

<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

4. 通用CRUD

通过前面的学习,我们了解到通过继承BaseMapper就可以获取到各种各样的单表操作,接下来我们将详细讲解这 些操作,下图是BaseMapper的各方法:

在这里插入图片描述

4.1 插入操作

4.1.1 方法定义

/**
*插入一条记录
*@param entity 实体对象
*/

int insert(T entity);

4.1.2 测试用例

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
@Autowired
private UserMapper userMapper;

@Test
public void testInsert() {
User user = new User();
user.setAge(20);
user.setEmail("ewrwer@qq.com");
user.setName("张三");
user.setUserName("zhangsan");
user.setPassword("123456");
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse("1990-01-01 00:00:00", df);
user.setBirthday(localDateTime);
int result = this.userMapper.insert(user); //返回的result是受影响的行数,并不是自增后的id
System.out.println("result = " + result);
System.out.println(user.getId()); //自增后的id会回填到对象中
}

4.1.3 MP*主键生成策略

上例中Mybatis-plus自动生成ID,如何设置id的生成策略呢?

MP支持的id策略如下:

package com.baomidou.mybatisplus.annotation;
import lombok.Getter;
/**
* 生成ID类型枚举类
*/

@Getter
public enum IdType {
/**
* 数据库ID自增
*/

AUTO(0),

/**
* 该类型未设置主键类型
*/

NONE(1),

/**
* 用户输入ID
* <p>该类型可以通过自己注册自动填充插件进行填充</p>
*/

INPUT(2),

/**
* 全局唯一ID (idWorker):雪花算法:可以根据时间排序,并且呈现的是递增趋势
*/

ID_WORKER(3),

/**
* 全局唯一ID (UUID)
*/

UUID(4),

/**
1. 字符串全局唯一ID (idWorker 的字符串表示)
*/

ID_WORKER_STR(5);
private final int key;
IdType(int key) {
this.key = key;
}
}

1)自增主键:

完全采用数据库自增主键方式。

  • 设置mysql数据库主键为自增
  • 在这里插入图片描述

  • 修改User对象:
  • @TableId(value = "ID", type = IdType.AUTO)
    private Long id;
    :
    @TableId(value = "ID")
    private Long id;

  • 程序中不用设置主键
  • 2)输入主键:

    手动设置主键值。

  • mysql数据库主键为自增或不是自增都可以
  • 修改User对象:
  • @TableId(value = "ID",type = IdType.INPUT)
    private Long id;

  • 程序中需要设置主键
  • 3)使用UUID作为主键:

    生成全局唯一ID。

  • mysql数据库主键为字符串类型,不是自增类型。
  • 修改User对象。
  • @TableId(value = "ID",type = IdType.UUID)
    private String id;

  • 程序中不用设置主键
  • 4)采用雪花算法字符串作为主键:

    采用雪花算法(雪花算法生成的ID是纯数字且具有时间顺序,适合分布式场景)生成全局唯一ID,字符串类型。

  • mysql数据库主键为字符串类型,不是自增类型。
  • 修改User对象。
  • @TableId(value = "ID",type = IdType.ID_WORKER_STR)
    private String id;

  • 程序中不用设置主键
  • 5)采用雪花算法数值作为主键:

    采用雪花片算法生成全局唯一ID,数值类型。

  • mysql数据库主键为数值类型,不是自增类型。
  • 修改User对象。
  • @TableId(value = "ID",type = IdType.ID_WORKER)
    private Long id;

  • 程序中不用设置主键
  • 4.2 更新操作

    4.2.1 根据id更新

    方法定义:

    /**
    * 根据 ID 修改
    * @param entity 实体对象
    */

    int updateById(@Param(Constants.ENTITY) T entity);

    根据id更新操作步骤:

  • 首先需要设置对象的主键属性值。
  • 再设置要更新的属性值。
  • 根据主键找到对象,更新设置属性值。
  • 返回影响的记录数。
  • 注意:只能将对象中不为NULL的属性更新到表中,如果对象属性值为NULL在SQL拼接时会忽略。

    // 根据id 更新
    @Test
    public void testUpdateById() {
    User user = new User();
    user.setId(7L); //主键
    user.setAge(21); //更新的字段
    //根据id更新,更新不为null的字段
    this.userMapper.updateById(user);
    }

    4.2.2 根据条件更新

    方法定义:

    /**
    * 根据 whereEntity 条件,更新记录
    *
    * @param entity 实体对象 (set 条件值,可以为 null)
    * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
    */

    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T>
    updateWrapper);

    根据ID更新一次只能更新一条记录,根据条件更新可实现批量更新。

    根据条件更新步骤:

  • 在对象中设置要更新的属性值。
  • 设置QueryWrapper,设置更新条件,可以设置多个。
  • 返回影响的记录数。
  • 注意:只能将对象中不为NULL的属性更新到表中。测试用例:

    @Test
    public void testUpdate() {
    User user = new User();
    user.setAge(22); //更新的字段
    //更新的条件
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name","艾老师");
    //可以设置多个条件…
    //执行更新操作 UPDATE tb_user SET age=22 WHERE name = '艾老师'
    int result = this.userMapper.update(user,wrapper);
    System.out.println("result="+result);
    }

    上边根据id更新 根据条件更新的方法只能将对象中不为NULL的属性更新到表中,下边通过UpdateWrapper进行更新,将birthday字段更新为NULL.

    @Test
    public void testUpdate2() {
    //更新的条件以及字段
    UpdateWrapper<User> wrapper = new UpdateWrapper<>();
    wrapper.eq("id", 7).set("age", 23).set("birthday",null);

    //执行更新操作 UPDATE tb_user SET age=23,birthday=null WHERE id = 7
    //没有传入User对象是应为修改的字段在UpdateWrapper通过set方法设置过了
    int result = this.userMapper.update(null, wrapper);
    System.out.println("result = " + result);
    }

    4.3 删除操作

    4.3.1 根据id删除

    方法定义:

    /**
    *根据 ID 删除
    *@param id 主键ID
    */

    int deleteById(Serializable id);

    操作步骤:

  • 指定要删除记录的主键值。
  • 调用deleteById方法执行删除。
  • @Test
    public void testDeleteById() {
    //执行删除操作
    int result = this.userMapper.deleteById(7L);
    System.out.println("result = " + result);
    }

    4.3.2 根据条件删除

    方法定义:

    /**
    *根据 entity 条件,删除记录
    *@param wrapper 实体对象封装操作类(可以为 null)
    */

    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

    根据条件删除步骤:

  • 定义对象,设置属性值,指定删除条件 ,可指定多个删除条件注意:删除条件只匹配对象中不为NULL的属性值
  • 设置QueryWrapper
  • 执行删除
  • // 根据条件删除
    @Test
    public void testDeleteByMap() {
    User user = new User();
    user.setAge(20);
    user.setName("als");
    //将实体对象进行包装,包装为操作条件
    QueryWrapper<User> wrapper = new QueryWrapper<>(user);
    int result = this.userMapper.delete(wrapper);
    System.out.println("result = " + result);
    }

    注意: 定义QueryWrapper可以不包装模型对象,手动设置条件,如下:

    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("age",20);
    wrapper.eq("name","张三");

    4.3.3 批量删除

    方法定义:

    /**
    *删除(根据ID 批量删除)
    *@param idList 主键ID列表(不能为 null 以及 empty)
    */

    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    批量删除操作步骤:

  • 指定id列表
  • 执行删除
  • // 根据id 批量删除
    @Test
    public void testDeleteByIds() {
    //根据id集合批量删除 DELETE FROM tb_user WHERE ID IN ( ? , ? , ? )
    int result = this.userMapper.deleteBatchIds(Arrays.asList(1L,10L,20L));
    System.out.println("result = "+ result);
    }

    4.4 查询操作

    4.4.1 根据id查询

    方法定义:

    /**
    *根据 ID 查询
    *@param id 主键ID
    */

    T selectById(Serializable id);

    根据id查询步骤:

  • 设置查询记录的主键值。
  • 执行查询。
  • 查询结果返回一个对象。
  • // 根据id 查询
    @Test
    public void testSelectById() {
    //根据id查询数据
    User user = this.userMapper.selectById(2L);
    System.out.println("result = " + user);
    }

    4.4.2 批量查询

    方法定义:

    /**
    *查询(根据ID 批量查询)
    *@param idList 主键ID列表(不能为 null 以及 empty)
    */

    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    根据id列表查询:

  • 设置id列表。
  • 执行查询。
  • 查询对象返回List 。
  • public void testSelectBatchIds() {
    //根据id集合批量查询
    List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L));
    for(User user:users) {
    System.out.println(user);
    }
    }

    4.4.3 查询一条记录

    方法定义:

    /**
    *根据 entity 条件,查询一条记录
    *@param queryWrapper 实体对象封装操作类(可以为 null)
    */

    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    查询步骤:

  • 设置QueryWrapper对象,设置查询条件,可以设置多个条件。
  • 执行查询。
  • 注意:如果查询结果为多条记录则报错(TooManyResultsException)。

    // 查询 返回一条结果
    @Test
    public void testSelectOne() {
    QueryWrapper<User> wrapper = new QueryWrapper<User>();
    wrapper.eq("name", "李四");
    //根据条件查询一条数据,如果结果超过一条会报错
    User user = this.userMapper.selectOne(wrapper);
    System.out.println(user);
    }

    4.4.4 查询记录条数

    方法定义:

    /**
    *根据 Wrapper 条件,查询总记录数
    *@param queryWrapper 实体对象封装操作类(可以为 null)
    */

    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    测试用例:

    // 查询记录数
    @Test
    public void testSelectCount() {
    QueryWrapper<User> wrapper = new QueryWrapper<User>();
    wrapper.gt("age", 23); //年龄大于23岁
    //根据条件查询数据条数
    Integer count = this.userMapper.selectCount(wrapper);
    System.out.println("count = " + count);
    }

    4.4.5 查询多条记录

    方法定义:

    /**
    *根据 entity 条件,查询全部记录
    *@param queryWrapper 实体对象封装操作类(可以为 null)
    */

    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    @Test
    public void testSelectList() {
    QueryWrapper<User> wrapper = new QueryWrapper<User>();
    wrapper.gt("age", 23); //年龄大于23岁
    //根据条件查询数据
    List<User> users = this.userMapper.selectList(wrapper);
    for (User user : users){
    System.out.println("user = " + user);
    }
    }

    4.4.6 分页查询

    方法定义:

    /**
    *根据 entity 条件,查询全部记录(并翻页)
    *@param page分页查询条件(可以为 RowBounds.DEFAULT)
    *@param queryWrapper 实体对象封装操作类(可以为 null)
    */

    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    // 测试分页
    @Test
    public void testSelectPage() {
    QueryWrapper<User> wrapper = new QueryWrapper<User>();
    wrapper.gt("age", 20); //年龄大于20岁
    //参数1:当前页码,小于1的按1算
    //参数2:每页记录数
    Page<User> page = new Page<>(1,2);
    //根据条件查询数据
    IPage<User> iPage = this.userMapper.selectPage(page,wrapper);
    System.out.println("数据总条数:" + iPage.getTotal());
    System.out.println("总页数:" + iPage.getPages());
    //取出分页记录
    List<User> users = iPage.getRecords();
    for (User user : users) {
    System.out.println("user = " + user);
    }
    }

    5. 条件构造器

    在MP中,Wrapper接口的实现类关系如下: 在这里插入图片描述

    在MP查询中,还可以使用lambda方式查询,降低数据库列表写错的风险。

    5.1 基本比较操作

    方法含义
    eq =
    ne !=
    gt >
    ge >=
    lt <
    le <=
    between BETWEEN
    like LIKE % 值 %
    likeLeft LIKE % 值
    likeRight LIKE 值 %
    in / notIn IN / NOT IN
    orderByAsc / orderByDesc 排序

    测试用例:

    @Test
    public void testEq() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ? AND age >=? AND name IN (?,?,?)
    wrapper.eq("password", "123456")
    .ge("age", 20)
    .in("name", "李四", "王五", "赵六");
    List<User> users = this.userMapper.selectList(wrapper);
    for (User user : users) {
    System.out.println(user);
    }
    }

    Lambda方式构造条件:

    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

    //SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ? AND age >=
    ? AND name IN (?,?,?)
    wrapper.eq(User::getPassword, "123456")
    .ge(User::getAge, 20)
    .in(User::getName, "李四", "王五", "赵六");
    List<User> users = this.userMapper.selectList(wrapper);
    for(User user : users) {
    System.out.println(user);
    }

    通常在开发中要根据表达式进行判断,表达式为true则拼接条件,如下:

    eq(boolean condition, R column, Object val)
    in(boolean condition,R column,Object... values)
    ...更多省略

    一个例子:

    //比如根据name来判断,如果name不为空则拼接条件
    String name = null;
    wrapper.eq(User::getPassword, "123456")
    .ge(User::getAge, 20)
    .in(name!=null,User::getName, "李四", "王五", "赵六");

    5.2 模糊查询

    在这里插入图片描述 测试用例:

    @Test
    public void testWrapper() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //SELECT id,user_name,password,name,age,email FROM tb_user WHERE name LIKE ?
    //Parameters: % 五 %(String)
    wrapper.like("name", "五");
    List<User> users = this.userMapper.selectList(wrapper);
    for (User user:users) {
    System.out.println(user);
    }
    }

    Lambda方式构造条件:

    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.like(User::getName, "五");

    5.3 逻辑查询

    在这里插入图片描述

    测试用例:

    @Test
    public void testWrapper2() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?
    wrapper.eq("name", "李四")
    .or()
    .eq("age", 24)
    .select("id", "name", "age");
    List<User> users = this.userMapper.selectList(wrapper);
    for (User user : users) {
    System.out.println(user);
    }
    }

    Lambda方式构造条件:

    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(User::getName, "李四")
    .or()
    .eq(User::getAge, 24);

    5.4 字段查询

    在MP查询中,默认查询所有的字段,如果有需要也可以通过select方法进行指定字段。

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testWrapper() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?
    wrapper.eq("name", "李四")
    .or()
    .eq("age", 24)
    .select("id", "name", "age");
    List<User> users = this.userMapper.selectList(wrapper);
    for (User user : users) {
    System.out.println(user);
    }
    }
    }

    Lambda方式构造条件:

    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(User::getName, "李四")
    .or()
    .eq(User::getAge, 24)
    .select(User::getId, User::getName, User::getAge);

    5.5 排序

    方法定义:

    orderBy(boolean condition, boolean isAsc, R... columns)
    自定义排序规则
    参数1true有效,false无效 ,参数2:是否升序,参数3..设置多个字段
    : `orderBy(true, true, "id", "name")`->`order by id ASC,name ASC`
    也可以多个orderBy拼装,如下:
    orderBy(true, true, "id").orderBy(true, true, "name") 效果同上

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testWrapper() {
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //SELECT id,user_name,password,name,age,email FROM tb_user ORDER BY age DESC
    wrapper.orderByDesc("age");
    List<User> users = this.userMapper.selectList(wrapper);
    for (User user : users) {
    System.out.println(user);
    }
    }
    }

    Lambda方式构造条件:

    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.orderByDesc(User::getAge);

    赞(0)
    未经允许不得转载:171主机测评 » MyBatis-Plus基础使用
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址