MyBatisPlus的基本使用之QueryWrapper

本文详细介绍了MyBatis-Plus中的QueryWrapper和LambdaQueryChainWrapper查询封装类,比较了两者在设置查询条件和使用方式上的异同,并通过代码示例展示了如何进行基本查询、复杂查询、分页查询以及乐观锁的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QueryWrapper是MyBatis-Plus中的一个查询封装类,用于构建带有条件的查询语句。

1. QueryWrapper

使用普通的方式来设置查询条件,而不是使用Lambda表达式。

  • 一系列方法设置查询条件。手动指定数据库表的列名作为方法的参数
    • select 设置查询的字段
    • eq、ne、gt、ge、lt、le 设置等于、不等于、大于、大于等于、小于、小于等于。
    • orderBy 排序方式
    • last 自定义SQL语句

2.区别

  • LambdaQueryChainWrapper使用Lambda表达式来设置查询条件,更加直观和类型安全
  • -而QueryWrapper使用普通方式来设置查询条件,更加灵活和通用

3.代码示例

package com.example.demo.mybatisplus.service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.zmybatisplus.entity.User;
import com.example.demo.zmybatisplus.mapper.UserMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
public class UserTest {

    @Autowired
    private UserMapper userMapper;

    //----------------------------------  查询 ---------------------------------------------------

    //简单查询
    @Test
    public void testSelect() {
        //所有
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
        //多个
        List<User> userList2 = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));
        userList2.forEach(System.out::println);
        //单个
        User user3 = userMapper.selectById(1L);
        System.out.println(user3);
    }

    //等值条件查询,-- HashMap
    @Test
    public void testSelectByMap() {
        HashMap<String, Object> map = new HashMap<>();
        //定义查询条件
        map.put("name", "小垃圾"); //where k = v
        map.put("age",0);
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }

    //Wrapper查询---1.数字的比较 2.字符串的模糊查询
    @Test
    public void testSelectByWrapper() {

        //链式调用构造查询条件
       QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.isNotNull("name")
                .like("email","john")
                .le("age",26)
                .lt("version",2)
                .orderByAsc("id","age");

        //选择API执行query
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);

        //        eq相等   ne不相等,   gt大于,    lt小于         ge大于等于       le 小于等于
        //        equal/ not equal/ greater than/ less than/ less than or equal/ great than or equal/

        //模糊查询 like  notLike  likeLeft(%x)  likeRight   notLikeLeft  notLikeRight

    }


    //Wrapper查询---1. 查询区间内的记录  between
    //              2.集合  in (in  notIn)(inSql   notInSql)
    @Test
    void test2SelectByWrapper(){
        //查询区间内的记录  between
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("name").between("age",20,30);
        Long count = userMapper.selectCount(wrapper);
        System.out.println("count = " + count);

        //集合IN : in  notIn
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.in("id",Arrays.asList(1L,2L,3L,4L));
        Long c=userMapper.selectCount(queryWrapper);
        System.out.println("count="+c);

        // 集合  IN ( sql语句 )  :  inSql   notInSql
        //例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
        //例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
        QueryWrapper<User> queryWrapper2=new QueryWrapper<>();
        //queryWrapper2.inSql("id","1,2,3,4");//两种写法
        queryWrapper2.inSql("id","select id from user where id<=4");
        Long c2=userMapper.selectCount(queryWrapper);
        System.out.println("count="+c2);

    }

    //Wrapper查询---分组查询 groupBy  having
    @Test
    public void testGroupByByWrapper(){
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.select("version","sum(age) as num")
                .groupBy("version")
                .having("sum(age)>0")
                .orderByDesc("num");

        //使用Map获取返回结果
        List<Map<String,Object>> list=userMapper.selectMaps(wrapper);

        list.forEach(System.out::println);
    }


    //Wrapper更新---
    @Test
    public void testUpdateWrapper() {

        //修改--所有的记录

//        //方式1
//        UpdateWrapper<User> updateWrapper=new UpdateWrapper<>();
//        updateWrapper.set("name","updateName").set("email",null);
//        userMapper.update(updateWrapper);
//
//        //方式2
//        String sql = "name = 'updateName1', email = null ";
//        int affectedRows = userMapper.update(new UpdateWrapper<User>().setSql(sql));
//        System.out.println("Affected rows: " + affectedRows);

        //修改 -- id=1的记录  UpdateWrapper拥有 QueryWrapper一样的条件方法
        UpdateWrapper<User> updateWrapper2 = new UpdateWrapper<>();
        updateWrapper2.set("name", "updateName111").set("email", "人文氛围v给xxx@123.cpm").eq("id", 1);
        userMapper.update(null, updateWrapper2);


    }

    //分页查询
    @Test
    public void testPage() {
        Page<User> page = new Page<>(2,5); //开启拦截器后,会注册一个page对象  当前页,每页条数
        //方法源码:   <P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
        userMapper.selectPage(page,null); //分页查询
        page.getRecords().forEach(System.out::println); //获取分页后的数据 打印
        System.out.println(page.getTotal()); //获取记录总数
    }

    //链式查询:  使用 Lambda 表达式的链式查询对象
    /*
     public List<User> getUserListByQueryWrapper() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("age", 25)
                .like("name", "John")
                .orderByDesc("create_time");

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

    public List<User> getUserListByLambdaQueryChainWrapper() {
        LambdaQueryChainWrapper<User> lambdaQueryWrapper = new LambdaQueryChainWrapper<>(userMapper);
        lambdaQueryWrapper.eq(User::getAge, 25)
                .like(User::getName, "John")
                .orderByDesc(User::getCreateTime);

        List<User> userList = lambdaQueryWrapper.list();
        return userList;
    }

    public List<User> getUserListByLambdaQueryChainWrapperWithPage(int pageNum, int pageSize) {
        LambdaQueryChainWrapper<User> lambdaQueryWrapper = new LambdaQueryChainWrapper<>(userMapper);
        lambdaQueryWrapper.eq(User::getAge, 25)
                .like(User::getName, "John")
                .orderByDesc(User::getCreateTime)
                .page(new Page<>(pageNum, pageSize));

        List<User> userList = lambdaQueryWrapper.list();
        return userList;
    }
     */




    //---------------------------增删改-查-------------------------------------------
    //加入了逻辑删除之后,查询会自动增加 delfalg=0;
    @Test
    public void testSelectById() {
        System.out.println("----- selectById method test -----");
        User user = userMapper.selectById(1L);
        Assertions.assertNotNull(user);
        System.out.println(user);

    }

    @Test
    public void testInsert() {
        System.out.println("----- insert method test -----");
        User user = new User();
        user.setName("John 雪花算法");
        user.setAge(25);
        user.setEmail("john.doe@example.com");
        int result = userMapper.insert(user);
        Assertions.assertEquals(1, result);
        System.out.println("Inserted user ID: " + user.getId());
    }

    @Test
    public void testUpdateById() {
        System.out.println("----- updateById method test -----");
        User user = new User();
        user.setId(1L);
        user.setAge(0);//update注解优先自定义设值
        int result = userMapper.updateById(user);
        Assertions.assertEquals(1, result);
    }

    //配置了全局逻辑删除 delfalg=0;
    @Test
    public void testDeleteById() {
        System.out.println("----- deleteById method test -----");
        int result = userMapper.deleteById(5L);
        Assertions.assertEquals(1, result);
        int r=userMapper.deleteBatchIds(Arrays.asList(1L,2L,3L));
    }


    //-------------------------- 乐观锁     ---------------------------------
    /*
    乐观锁(OptimisticLockerInnerInterceptor)机制:
       当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
     */
    @Test//乐观锁测试
    public void testOptimisticLocker(){
        //1、查询用户信息
        User user = userMapper.selectById(1L);
        //2、修改用户信息
        user.setEmail("123@qq.com");
        user.setName("小垃圾");
        //3、更新操作
        userMapper.updateById(user);  //WHERE id=? AND version=?
    }

    @Test
    public void testOptimisticLocker2(){
        //模拟多线程
        User user = userMapper.selectById(2L);
        user.setEmail("111jdw@qq.com");
        user.setName("帅小伙111");//我们在这里对线程1修改值

        //线程2插队
        User user2 = userMapper.selectById(2L);
        user2.setEmail("222jdw@qq.com");
        user2.setName("帅小伙222");
        userMapper.updateById(user2); //线程2抢先提交

        userMapper.updateById(user);//线程1失败,乐观锁在这种情况下防止了脏数据存在,没有乐观锁就会有覆盖掉线程2的操作
    }






}
### 使用 MyBatis Plus 的 QueryWrapper 进行查询 MyBatis Plus 中的 `QueryWrapper` 是一个非常强大且灵活的工具,用于构建复杂的 SQL 查询语句。通过 `QueryWrapper`,可以方便地设置各种查询条件,从而简化了数据库操作。 #### 创建 QueryWrapper 实例并添加简单条件 可以通过创建一个新的 `QueryWrapper` 对象来开始构建查询逻辑: ```java import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 假设 User 是实体类名 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("age", 20); // 添加等于条件 ``` 此代码片段展示了如何初始化 `QueryWrapper` 并为其指定一个简单的相等条件[^2]。 #### 复杂条件组合 除了基本的操作符外,还可以链式调用多个方法以实现更复杂的要求: ```java queryWrapper.ge("salary", 5000).le("salary", 8000); // 表达 salary >= 5000 AND salary <= 8000 ``` 这里使用了大于等于 (`ge`) 和小于等于 (`le`) 方法来限定薪资范围。 #### 自定义表达式的应用 对于某些特定场景下的需求,比如日期处理,则可能需要用到自定义SQL片断的方式来进行精确匹配: ```java String column = "hiredate"; Object value = "2023/09/01"; queryWrapper.apply("{0} >= TO_DATE({1}, 'yyyy/MM/dd')", column, value); // 构建 hiredate >= TO_DATE('2023/09/01', 'yyyy/MM/dd') ``` 这段例子中演示了当涉及到 Oracle 数据库中的 `TO_DATE()` 函数时应怎样正确运用 `apply()` 方法[^3]。 #### 转换为 Lambda 形式 如果希望减少硬编码字段名称带来的风险,可以选择转换成 `LambdaQueryWrapper` 或者直接利用 `new QueryWrapper().lambda()` 方便地访问 lambda 版本的方法: ```java LambdaQueryWrapper<User> lambdaQueryWrapper = new QueryWrapper<User>().lambda(); lambdaQueryWrapper.eq(User::getAge, 20L); // 或者也可以这样写 QueryWrapper<User> wrapperWithLambda = new QueryWrapper<User>(); wrapperWithLambda.lambda() .eq(User::getName, "Tom"); ``` 以上就是有关于 MyBatis Plus 下 `QueryWrapper` 功能的一些介绍以及实际使用的案例展示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值