[Mybatis-Plus笔记] MybatisPlus-03-QueryWrapper条件构造器

一、准备工作

为了更好的理解条件构造器,建议配置 Mybatis-Plus 的日志输出到控制台

在 yaml 配置文件中加入下面内容:

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

如此配置后,我们可以在控制台看到 Mybatis-Plus 生成的 SQL 语句

二、条件构造器入门

1. 使用方式

(1)普通 QueryWrapper

下面的测试类中,实现了从表中查询 age 字段小于 20 的用户

然后利用 selectList 方法,将条件构造器作为参数传入,即可得到符合条件的数据

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testQueryWrapper() {
        QueryWrapper condition = new QueryWrapper();
        // 方法名 lt 表示小于,参数是字段名与值
        condition.lt("age", 20);
        List<User> users = userMapper.selectList(condition);
        System.out.println(users);
    }

}

[注意]

  • 不指定 QueryWrapper 的泛型无法进行链式编程

SQL 语句为:

SELECT id,name,age,email FROM user WHERE (age < ?)

(2)lambda 方式 QueryWrapper

通过指定实体类的 get 方法来确定列,避免了写错类名带来的麻烦

需要指定泛型为实体类,并以 lambda() 方法开头

可以链式编程

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testQueryWrapper() {
        QueryWrapper<User> condition = new QueryWrapper<User>();
//        condition.lt("age", 20);
        condition.lambda().lt(User::getAge, 20);
        List<User> users = userMapper.selectList(condition);
        System.out.println(users);
    }

}

SQL 语句也是:

SELECT id,name,age,email FROM user WHERE (age < ?)

(3)LambdaQueryWrapper

使用 LambdaQueryWrapper 就不用指定再写 lambda() 方法开头了

但不可再通过列名来指定字段

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testQueryWrapper() {
        LambdaQueryWrapper<User> condition = new LambdaQueryWrapper<User>();
//        condition.lt("age", 20);  // 不可用
        condition.lt(User::getAge, 20);
        List<User> users = userMapper.selectList(condition);
        System.out.println(users);
    }

}

SQL 语句依然是:

SELECT id,name,age,email FROM user WHERE (age < ?)

2. 条件的逻辑连接

(1)与运算

对同一个条件构造器添加多个条件,默认用与运算(或者说且运算)连接

如下例完成 20 <= age <= 30 的条件构造(ge 和 le 分别表示 >= 和 <=)

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testQueryWrapper() {
        QueryWrapper<User> condition = new QueryWrapper<User>();
        condition.lambda()
                .ge(User::getAge, 20).le(User::getAge, 30);
        List<User> users = userMapper.selectList(condition);
        System.out.println(users);
    }

}

SQL 语句为:

SELECT id,name,age,email FROM user WHERE (age >= ? AND age <= ?)

(2)或运算

多个条件间用 or() 方法分隔,条件就会用或运算连接

如下例完成 age < 20 || age > 30 的条件构造(lt 和 gt 分别表示 < 和 >)

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testQueryWrapper() {
        QueryWrapper<User> condition = new QueryWrapper<User>();
        condition.lambda().
                lt(User::getAge, 20).or().gt(User::getAge, 30);
        List<User> users = userMapper.selectList(condition);
        System.out.println(users);
    }

}

SQL 语句为:

SELECT id,name,age,email FROM user WHERE (age < ? OR age > ?)

(3)括号

条件构造器中,and() 方法表示括号(或者说嵌套),而不是且运算

我们需要将括号中的内容作为参数传入 and() 方法

例如,我们需要在年龄低于 20 或者高于 35 的用户中,找出使用 @gmail 邮箱的用户

可以像下面这样:

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testQueryWrapper() {
        QueryWrapper<User> condition = new QueryWrapper<User>();
        condition.lambda()
                .and(
                        i -> i.lt(User::getAge, 20).or().gt(User::getAge, 35)
                ).likeLeft(User::getEmail, "@gmail.com");
        List<User> users = userMapper.selectList(condition);
        System.out.println(users);
    }

}

关于 and() 方法中的 lambda 表达式,在 idea 中 按住 ctrl 将鼠标放在 i 上,可以看到,i 指代的是一个 LambdaQueryWrapper<User>

在这里插入图片描述

SQL 语句为:

SELECT id,name,age,email FROM user WHERE ((age < ? OR age > ?) AND email LIKE ?)

参数为 :

Parameters: 20(Integer), 35(Integer), %@gmail.com(String)

可见 likeLeft() 方法自动给参数左侧加上了 % 通配符
类似的还有 likeRight() 在右侧加 %
like() 在左右侧都加 %

3. 更多条件判断方法

lt, le, gt, ge 这些代表条件判断的代码,最早还是在 Shell 脚本中见到的

想要了解更多的话推荐这一篇文章:Mybatis Plus详解(三)——条件构造器详解

三、补充

1. 增加布尔值参数

在条件构造器添加条件是,可以再加入一个 boolean 值表示是否要将此条件加入。

看下例中,服务层实现了根据年龄区间查询用户的功能:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public List<User> selectByAgeRange(Integer low, Integer high) {
        QueryWrapper<User> condition = new QueryWrapper<>();
        condition.lambda()
                .ge(User::getAge, low)
                .lt(User::getAge, high);
        return userMapper.selectList(condition);
    }
}

但是参数为 null 时会怎样呢?测试一下看看:

@SpringBootTest
public class UserServiceTest {
    @Autowired
    UserService userService;
    @Test
    void testSelectByAgeRange() {
        List<User> users = userService.selectByAgeRange(null, 20);
        System.out.println(users);
    }
}

用 null 和 20 做参数,一般希望能忽略下限,查询小于 20 岁的用户,但实际上没有查到任何结果

Mybatis-Plus 日志如下:

==>  Preparing: SELECT id,name,age,email FROM user WHERE (age >= ? AND age < ?)
==> Parameters: null, 20(Integer)
<==      Total: 0

如果某个参数为空,则不将此条件加入构造,可以这样写:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    public List<User> selectByAgeRange(Integer low, Integer high) {
        QueryWrapper<User> condition = new QueryWrapper<>();
        condition.lambda()
                .ge(low != null, User::getAge, low)
                .lt(high != null, User::getAge, high);
        return userMapper.selectList(condition);
    }
}

ge 和 lt 方法中多了一个布尔值参数,当这个参数为真时才会加入此条件

再次执行测试,日志如下:

==>  Preparing: SELECT id,name,age,email FROM user WHERE (age < ?)
==> Parameters: 20(Integer)
<==    Columns: id, name, age, email
<==        Row: 2, Tao Chi Yuen, 17, chiyuentao@icloud.com
<==        Row: 4, Ueno Hikari, 18, hikari9@hotmail.com
<==        Row: 12, Mildred Ramirez, 19, ramirez2@icloud.com
<==      Total: 3

2. 查询映射

select() 方法可以指定查询的内容,参数为字符串可变参数,将表的字段名做为参数传入

默认查询所有字段,如果没有参数传入则无效

Mybatis-Plus 会在多个参数间添加逗号,然后放在 SQL 语句的 SELECT 之后

我们直接用 SQL 语句作为参数传入也可以

select() 方法的效果不会叠加,多次调用 select() 方法时以最后一次为准,最后一次无参数不会覆盖之前的

示例:

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testSelect() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.select("age");
        wrapper.select("name, email");
        wrapper.select("name AS userName, email AS userEmail");
        wrapper.select();
        userMapper.selectList(wrapper);
    }
}

Mybatis-Plus 日志如下:

==>  Preparing: SELECT name AS userName, email AS userEmail FROM user
==> Parameters: 
<==    Columns: userName, userEmail
<==        Row: Pauline Cole, paulic59@icloud.com
<==        Row: Tao Chi Yuen, chiyuentao@icloud.com
<==      Total: 2

3. selectMaps() 方法

如果查询到的数据是不能装进实体类中的,就要调用 selectMaps() 方法了,用 List<Map<String, Object>> 接收结果

比如聚合函数查询平均年龄,如下:

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    UserMapper userMapper;
    @Test
    void testSelectMaps() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.select("AVG(age) AS averageAge");
        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        
        System.out.println(maps);
        BigDecimal averageAge = (BigDecimal) maps.get(0).get("averageAge");
        System.out.println("averageAge = " + averageAge);
    }
}

另外,AVG() 聚合函数得到的结果是 BigDecimal 类型,而不是 double

Mybatis-Plus 日志如下:

==>  Preparing: SELECT AVG(age) AS averageAge FROM user
==> Parameters: 
<==    Columns: averageAge
<==        Row: 21.8438
<==      Total: 1
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值