文章目录
- 1. 文章引言
- 2. 代码演示
- 3. 分析LambdaQueryWrapper
- 3.1 引入LambdaQueryWrapper的原因
- 3.2 LambdaQueryWrapper和QueryWapper的区别
- 4. 重要总结
1. 文章引言
今天在公司写代码时,发现同事使用LambdaQueryWrapper
来查询数据,而我一直习惯使用QueryWrapper
。
我对此便来了兴趣,决定尝试了解LambdaQueryWrapper
。
2. 代码演示
为了分析LambdaQueryWrapper
,给出如下两段代码:
- 通过
LambdaQueryWrapper
查询
@Test
public void testLambdaQueryWrapper(){
//初始化变量
Long applicationId = 62L;
String type = "pageFrameApp";
// LambdaQueryWrapper查询
LambdaQueryWrapper<AppConfig> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(AppConfig::getAppId, applicationId);
if (isNotNull(type)) {
lambdaQueryWrapper.eq(AppConfig::getConfigType, type);
}
long count = appConfigService.count(lambdaQueryWrapper);
//输出统计数量
System.out.println("输出统计结果:"+count);
}
输出统计结果如下图:
输出mybatis-plus
打印的SQL
语句,如下所示:
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@62c02089] will not be managed by Spring
==> Preparing: SELECT COUNT( * ) FROM app_config WHERE (app_id = ? AND type = ?)
==> Parameters: 62(Long), pageFrameApp(String)
<== Columns: COUNT( * )
<== Row: 1
<== Total: 1
- 通过
QueryWrapper
查询
@Test
public void testQueryWrapper(){
//初始化变量
Long applicationId = 62L;
String type = "pageFrameApp";
// LambdaQueryWrapper查询
QueryWrapper<AppConfig> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("app_id", applicationId);
if (isNotNull(type)) {
queryWrapper.eq("type", type);
}
long count = appConfigService.count(queryWrapper);
//输出统计数量
System.out.println("输出统计结果:"+count);
}
输出结果如下图所示:
输出mybatis-plus
打印的SQL
语句,如下所示:
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@31d09031] will not be managed by Spring
==> Preparing: SELECT COUNT( * ) FROM app_config WHERE (app_id = ? AND type = ?)
==> Parameters: 62(Long), pageFrameApp(String)
<== Columns: COUNT( * )
<== Row: 1
<== Total: 1
3. 分析LambdaQueryWrapper
由上面两段代码的演示来看,你会神奇地发现:
-
输出结果是相同的
-
mybatis-plus
打印的SQL
语句也是相同
为什么会相同呢?我们不妨去看看它们的源码。
QueryWrapper
继承AbstractWrapper
这个类,如下图所示:
LambdaQueryWrapper
继承AbstractLambdaWrapper
,而AbstractLambdaWrapper
继承是AbstractWrapper
,如下图所示。
你会发现,不论是LambdaQueryWrapper
,还是QueryWrapper
,本质上继承的都是AbstractWrapper
这个抽象类。
因而,它们的执行结果相同,只是查询方式不同而已。
3.1 引入LambdaQueryWrapper的原因
但是,既然有了QueryWrapper
,为什么还要有LambdaQueryWrapper
?我认为有以下两点:
- 适配
jdk1.8
我们都知道,现在主流jdk的版本是jdk1.8
,而jdk1.8
引入了Lambda
表达式。
MyBatis-Plus
为了适配jdk1.8
,让路走得更宽,才引入了LambdaQueryWrapper
。
- 让代码变的更简单
我们再次去看上述QueryWrapper
的代码,eq
方法要手动写如数据表的字段,我们偶尔会写错。
同时,去看上述LambdaQueryWrapper
的代码,eq
方法是通过对象属性去映射数据表的字段。
基于以上两点,我认为有必要引入LambdaQueryWrapper
类。
3.2 LambdaQueryWrapper和QueryWapper的区别
QueryWrapper
要手动写入数据表的字段,千万不要写错数据表的字段,比如上述代码中的eq
方法。
LambdaQueryWrapper
虽然不用引入数据表的字段,而是通过对象的属性去映射,但这容易出错。
【注意】这里对象的属性是驼峰格式的,不然会报出:unknown column 'xxx' in 'where clause'
比如数据表的字段是app_id
,而对象的属性是appid
,而我们又没有加上@TableField("app_id")
注解 (注解的value值是数据表的字段),如下代码所示:
/** 应用id */
private Long appid;
此时启动测试类,便报出Unknown column 'appid' in 'where clause'
问题,如下图所示:
若我们加上@TableField("app_id")
注解,如下代码所示:
/** 应用id */
@TableField("app_id")
private Long appid;
此时启动测试类,便不会报错,如下图所示:
当然,我们把appid
修改为appId
,即便不添加@TableField("app_id")
注解,通过LambdaQueryWrapper
查询也不会出错。
4. 重要总结
我们在使用QueryWrapper
时,要手动写入数据表的字段,注意字段不要写错,不然也会报出unknown column 'xxx' in 'where clause'
这个错误
此外,我们在使用LambdaQueryWrapper
时,要注意对象的属性和数据表字段的映射,不然极容易报出unknown column 'xxx' in 'where clause'
这个错误。