Skip to content

条件查询 ​

MybatisPlus提供了Wrapper对象来封装各种条件,比如条件、分页、排序等等,然后主要的查询方法有下面两个:

  • T selectOne(Wrapper<T> queryWrapper):条件查询,当查询结果最多为一条记录时使用
  • List<T> selectList(Wrapper<T> queryWrapper):条件查询,当查询结果可能为多条记录时使用

本章案例代码预备 ​

实体类:

java
package com.itheima.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO) // 设置属性为ID自动增长
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer age;
}

持久层:

java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface UserMapper extends BaseMapper<User> {}

书写格式 ​

MybatisPlus支持使用多种格式组装条件,常用的有这几种:Wrapper对象封装查询条件、QueryWrapper查询条件构造器、LambdaQueryWrapper查询条件构造器(支持Lambda表达式)。

Wrapper对象封装(了解即可) ​

使用构造方法构建QueryWrapper 对象。

java
package com.itheima.mapper;

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

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void newQueryWrapperDemo() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
                .eq("username", "张三")
                .eq("password", "123456");
        User user = userMapper.selectOne(queryWrapper);
        System.out.println(user);
    }
}

QueryWrapper ​

使用 Wrappers 构建 QueryWrapper 对象。

java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void queryWrapperDemo() {
        QueryWrapper<User> queryWrapper = Wrappers.query(User.class)
                .eq("username", "张三")
                .eq("password", "123456");
        // 注意:selectOne这个方法如果查询到多条数据的话则会报错
        User user = userMapper.selectOne(queryWrapper);
        System.out.println(user);
    }
}

LambdaQueryWrapper(推荐使用) ​

使用 Wrappers 构建LambdaQueryWrapper 对象。

java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void lambdaQueryWrapper() {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class)
                .eq(User::getName, "张三")
                .eq(User::getPassword, "123456");
        User user = userMapper.selectOne(queryWrapper);
        System.out.println(user);
    }
}

提示

  • QueryWrapper:写字符串字段 "name",容易写错,适合快速写、动态表名场景。

  • LambdaWrapper 优势:修改实体字段名,代码自动提示、编译报错,避免线上 bug,生产优先用这个。

  • Service 层链式查询:userService.lambdaQuery().eq().list(),不用手动 在new Wrapper。

查询条件 ​

MybatisPlus提供了如下方法来设置查询条件

查询方法说明例子
eq、ne、gt、ge、lt、le、isNull、isNotNull比较运算eq("name", "老王") ---> name = '老王'
like、notLike、likeLeft、likeRight模糊查询likeRight("name", "王") ---> name like '王%'
in、notIn、between、notBetween范围运算in("age",{1,2,3}) ---> age in (1,2,3)
or、and拼接eq("id",1).or().eq("name","老王") ---> id = 1 or name = '老王'

以下是部分的演示代码:

java
/**
 * 查询姓吕 或者 年龄 在20-25岁之间的用户信息
 */
@Test
void test4() {
    // 构建查询条件
    LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class)
            .likeRight(User::getName, "吕") // name like '吕%'
            .or()  // or
            .between(User::getAge, 20, 25);// age between 20 and 25

    List<User> userList = userMapper.selectList(queryWrapper);

    userList.forEach(user -> System.out.println(user));
}

投影和排序 ​

除了设置查询条件外,MP还支持:投影、排序操作,使用下面方式实现。

查询方法说明例子
select投影select("name","password") ---> select name,password from 表
orderByAsc、orderByDesc排序orderByDesc("id", "name") ---> order by id DESC,name DESC

提示

投影(Projection)来自【关系代数】术语:按列筛选、垂直切表,只保留指定字段;

java
//投影和排序
//select name,age from user order by age asc
@Test
public void test4() {
    //1. 封装查询条件
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    //1-1 设置返回字段===>查询 name和age这两列
    wrapper.select(User::getName, User::getAge);
    //1-2 设置排序条件===> 按照年龄降序排序
    wrapper.orderByDesc(User::getAge);

    //2. 执行查询
    List<User> userList = userMapper.selectList(wrapper);
    System.out.println(userList);
}

分页查询 ​

MybatisPlus内置了专门用于分页的插件,使用起来非常简单,它是基于拦截器原理实现分页的, 但是mybatis-plus在3.5.9版本之后, 将分页的拦截器单独抽取出来, 我们需要在pom.xml文件中额外引入一个坐标, 建议参照官网步骤完成分页的学习:地址点击此处

使用时请注意

于 v3.5.9 起,PaginationInnerInterceptor 已分离出来。如需使用,则需单独引入 mybatis-plus-jsqlparser 依赖 , 具体请查看 安装 一章。

引入依赖 ​

在pom.xml文件中引入如下的依赖代码:

xml
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-jsqlparser</artifactId>
    <version>3.5.17</version>
</dependency>

配置拦截器 ​

代码直接复制使用即可,其中使用的时候需要处理存放的目录以及对应的Java类文件名称。

java
package com.itheima.config;

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

@Configuration
public class MybatisPlusConfig {
    /**
     * 分页插件(3.5.x 最新版写法)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //1) 创建MybatisPlusInterceptor拦截器对象
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        //2) 添加分页拦截器(指定数据库类型,性能更好)
        PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        interceptor.addInnerInterceptor(paginationInterceptor);
        
        return interceptor;
    }
}

实现分页的功能 ​

java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1() {
        Integer page = 1;// 当前页码
        Integer pageSize = 3; // 每页展示的数据条数

        // 执行分页查询
        Page<User> pageInfo = userMapper.selectPage(new Page<>(page, pageSize), Wrappers.emptyWrapper());

        long total = pageInfo.getTotal(); // 数据总条数
        System.out.println("数据总条数:" + total);
        List<User> userList = pageInfo.getRecords(); // 数据列表
        System.out.println("数据列表:" + userList);
        long current = pageInfo.getCurrent();
        System.out.println("当前页码是:" + current);
    }
}

条件修改与条件删除 ​

MyBatisPlus提供了下面两个方法来进行数据库的条件修改与删除

  • int update(T entity,Wrapper<T> updateWrapper):条件更新(参数1: 封装要修改的字段 参数2: 封装更新条件)
  • int delete(Wrapper<T> wrapper):条件删除

条件修改 ​

方式一、实体类修改 ​

基于实体类数据更新。

java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1() {
        // 基于实体类数据进行更新
        User user = new User();
        user.setPassword("Xianyu123");
        // 设置更新的条件
        LambdaUpdateWrapper<User> queryWrapper = Wrappers.lambdaUpdate(User.class).lt(User::getAge, 30);
        int updateRows = userMapper.update(user, queryWrapper);
        System.out.println("更新操作影响的数据行数:" + updateRows);
    }
}

方式二、set方法修改 ​

直接使用set方法设置需要修改的字段数据。

Java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1() {
        // 直接使用set方法设置需要更新的字段
        int updateRows = userMapper.update(
                Wrappers.lambdaUpdate(User.class)
                        .lt(User::getAge, 30)
                        .set(User::getPassword, "demo123"));
        System.out.println("更新操作影响的行数:" + updateRows);
    }
}

条件删除 ​