条件查询
MybatisPlus提供了Wrapper对象来封装各种条件,比如条件、分页、排序等等,然后主要的查询方法有下面两个:
- T selectOne(Wrapper<T> queryWrapper):条件查询,当查询结果最多为一条记录时使用
- List<T> selectList(Wrapper<T> queryWrapper):条件查询,当查询结果可能为多条记录时使用
本章案例代码预备
实体类:
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;
}持久层:
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 对象。
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 对象。
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 对象。
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 = '老王' |
以下是部分的演示代码:
/**
* 查询姓吕 或者 年龄 在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)来自【关系代数】术语:按列筛选、垂直切表,只保留指定字段;
//投影和排序
//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文件中引入如下的依赖代码:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>3.5.17</version>
</dependency>配置拦截器
代码直接复制使用即可,其中使用的时候需要处理存放的目录以及对应的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;
}
}实现分页的功能
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):条件删除
条件修改
方式一、实体类修改
基于实体类数据更新。
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方法设置需要修改的字段数据。
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);
}
}