Mybatis(17)Mybatis-Plus条件构造器(2)& 自定义 SQL
文章目录
- [Mybatis(17)Mybatis-Plus条件构造器(2)& 自定义 SQL](#Mybatis(17)Mybatis-Plus条件构造器(2)& 自定义 SQL)
- [1. LambdaQueryWrapper](#1. LambdaQueryWrapper)
- 2.LambdaUpdateWrapper
- [3.自定义 SQL](#3.自定义 SQL)
- 4.总结:
-
- [Lambda 表达式:](#Lambda 表达式:)
- [MP 和 Mybatis 的重要性:](#MP 和 Mybatis 的重要性:)
- [MP 和 Mybatis 的使用选择:](#MP 和 Mybatis 的使用选择:)
- 下一篇博客:
观前提醒:
如果你是第一次点击这篇博客,需要你回看Mybatis-plus系列的这个博客:
Mybatis(16)Mybatis-Plus条件构造器(1)
这篇博客的代码,都是需要自己敲一下的。
建议你看着我说的知识点,自己尝试一下,创建 Springboot项目,使用 Mybatis-plus 框架,访问数据库。
这里使用的数据库是 MySQL。
图形化工具:Navicat
sql文件获取:https://gitee.com/mrbgvhbhjv/java-ee-course

简介:
目前,条件构造器,还有另外两种:LambdaQueryWrapper ,LambdaUpdateWrapper 的举例使用介绍。
QueryWrapper 和 UpdateWrapper存在⼀个问题,就是需要写死字段名,如果字段名发生变更,可能会因为测试不到位酿成事故。
MyBatis-Plus 给我们提供了⼀种基于Lambda表达式的条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名,也提高了代码的可读性和可维护性。
-
LambdaQueryWrapper
-
LambdaUpdateWrapper
分别对应 QueryWrapper和UpdateWrapper。
更详细的使用,建议看官方文档:MyBatis-Plus 🚀 为简化开发而生
1. LambdaQueryWrapper
使用 lambda表达式,有两种写法:
- 直接创建 LambdaQueryWrapper类的对象。
- QueryWrapper 对象,调用 lambda() 方法。

从sql语句上看,等同于下面这个代码:

但是,lambda表达式 多了一层校验功能。
代码:
java
@Test
void selectByCondition2(){
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().select(UserInfo::getId,UserInfo::getUsername,UserInfo::getPassword,
UserInfo::getAge,UserInfo::getGender,UserInfo::getPhone)
.eq(UserInfo::getAge,20)
.like(UserInfo::getUsername,"ad");
List<UserInfo> userInfos = userInfoMapper.selectList(queryWrapper);
// 等价于 sql:select id,username,`password`,age,gender,phone from user_info where age=20 and username like "%ad%";
// 第一种输出方式:lambda表达式
// userInfos.forEach(System.out::println);
// 第二种:流(stream)
// userInfos.stream().forEach(x -> System.out.println(x));
// 第三种:for each循环
for (UserInfo userInfo : userInfos) {
System.out.println(userInfo.toString());
}
}
// 另一种写法:使用 LambdaQueryWrapper
@Test
void selectByCondition2(){
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.select(UserInfo::getId,UserInfo::getUsername,UserInfo::getPassword,
UserInfo::getAge,UserInfo::getGender,UserInfo::getPhone)
.eq(UserInfo::getAge,20)
.like(UserInfo::getUsername,"ad");
List<UserInfo> userInfos = userInfoMapper.selectList(queryWrapper);
// 等价于 sql:select id,username,`password`,age,gender,phone from user_info where age=20 and username like "%ad%";
// 第一种输出方式:lambda表达式
// userInfos.forEach(System.out::println);
// 第二种:流(stream)
// userInfos.stream().forEach(x -> System.out.println(x));
// 第三种:for each循环
for (UserInfo userInfo : userInfos) {
System.out.println(userInfo.toString());
}
}
运行结果:

lambda表达式的好处:
如果 实体类中的某一个属性变了(id 变为 userId),使用 QueryWrapper 构建的 sql语句,代码是不会报错的。
如果使用 lambda表达式,就会报错,提醒你出错了。

2.LambdaUpdateWrapper
LambdaUpdateWrapper用法和 LambdaQueryWrapper相似
使用 lambda表达式,有两种写法:
- 直接创建 LambdaUpdateWrapper类的对象。
- UpdateWrapper对象,调用 lambda() 方法。
代码:

从sql语句上看,等同于下面这个代码:

但是,lambda表达式 多了一层校验功能。
代码:
java
@Test
void updateByCondition5(){
UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
updateWrapper.lambda().set(UserInfo::getDeleteFlag,0)
.lt(UserInfo::getAge,20);
userInfoMapper.update(updateWrapper);
}
//另一种写法:使用 LambdaUpdateWrapper
@Test
void updateByCondition5(){
LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(UserInfo::getDeleteFlag,0)
.lt(UserInfo::getAge,20);
userInfoMapper.update(updateWrapper);
}
lambda表达式,主要是避免硬编码的问题 ,当 实体类的属性,发生变化的时候,lambda表达式 能够自动检验 get和set 方法,是否有问题。
3.自定义 SQL
MP 给我们提供了很多的 增删查改方法,但是,并没有涵盖所有的 sql语句。
我们就可以自己去定义 sql语句,就像在 Mybatis 一样。
Mybatis-plus 是 Mybatis 的增强版,是在 Mybatis的基础上实现的,MP自然也涵盖了 Mybatis 的功能。
MP的自定义 sql,其实就是 Mybatis 中,定义接口,实现接口的套路。
自定义 sql 有两种方式(Mybatis 中,定义接口的两种方式):
- 注解,例如 @Select
- xml文件
3.1 注解的方式:
其中,注解是一样的。
和 Mybaits 注解实现接口的方式,是一样的。
3.2 xml 的方式:
但是,xml 的方式,配置文件的内容,有点不同,这里详细说说 xml :
配置mapper路径
yaml
mybatis-plus:
mapper-locations: "classpath*:/mapper/**.xml" # Mapper.xml
定义方法
java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
List<UserInfo> selectAll();
}
编写XML
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.mapper.UserInfoMapper">
<select id="selectAll" resultType="com.example.demo.model.UserInfo">
select * from user_info where delete_flag = 0;
</select>
</mapper>
测试
java
@Test
void selectAll() {
List<UserInfo> list = userInfoMapper.selectAll();
for (UserInfo userInfo : list) {
System.out.println(userInfo.toString());
}
}
---------------------------------------------------
@Test
void selectAll() {
List<UserInfo> list = userInfoMapper.selectList(null);
for (UserInfo userInfo : list) {
System.out.println(userInfo.toString());
}
}
Mybatis-plus 中,也提供了查询所有记录的方法,selectList()。
如果参数为 null,默认查询所有记录。
3.3 使用 Wrapper 自定义 SQL
MyBatis-Plus 提供了强大的 Wrapper 条件构造器,允许开发者自定义 SQL 语句,以满足更复杂的数据库查询需求。为了使用这一功能,请确保你的 mybatis-plus 版本不低于 3.0.7。
示例1(查询):
注意事项
- 版本要求 :确保你的项目中使用的
mybatis-plus版本至少为3.0.7,以支持自定义 SQL 功能。 - 参数命名 :在自定义 SQL 时,传递 Wrapper 对象作为参数时,参数名必须为
ew,或者使用注解@Param(Constants.WRAPPER)明确指定参数为 Wrapper 对象。 - 使用
${ew.customSqlSegment}:在 SQL 语句中,使用${ew.customSqlSegment}来引用 Wrapper 对象生成的 SQL 片段。 - 不支持基于 entity 的 where 语句:自定义 SQL 时,Wrapper 对象不会基于实体类自动生成 where 子句,你需要手动编写完整的 SQL 语句。
示例
以下是一个使用 Wrapper 自定义 SQL 的示例:
java
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT * FROM user ${ew.customSqlSegment}")
List<User> selectByCustomSql(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
}
在上述示例中,我们定义了一个 selectByCustomSql 方法,它使用了一个自定义的 SQL 语句,并通过 ${ew.customSqlSegment} 引入了 Wrapper 对象生成的 SQL 片段。
使用方法
要使用自定义 SQL,只需调用上述方法并传入一个 Wrapper 对象:
java
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "张三");
List<User> userList = userMapper.selectByCustomSql(queryWrapper);
在这个例子中,selectByCustomSql 方法将执行一个带有 where 条件的查询,该条件由传入的 queryWrapper 对象生成。
通过这种方式,你可以灵活地结合 MyBatis-Plus 的 Wrapper 功能和自定义 SQL,以满足各种复杂的数据库操作需求。
示例2(更新):
我们希望通过 自定义sql ,实现这样的 sql语句:
sql
UPDATE user_info SET age = age+10 WHERE id IN (1,2,3)
接口代码:

测试代码:

运行结果:

总结:
以上,演示的是 注解 的方式,但是,xml 的方式,和实现接口的方式,是一样的。
只需要把注解中的 sql语句,放到 xml代码中,sql的语句部分。
4.总结:
Lambda 表达式:
Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名,也提高了代码的可读性和可维护性.
- LambdaQueryWrapper
- LambdaUpdateWrapper
分别对应 QueryWrapper和UpdateWrapper
lambda表达式的代码,或者 QueryWrapper和UpdateWrapper,个人开发习惯不同,选择一种进行使用即可。
更详细的使用,建议看官方文档:MyBatis-Plus 🚀 为简化开发而生
官方文档写得非常详细。里面的内容,基本涵盖工作的所有场景
MP 和 Mybatis 的重要性:
两个都很重要,企业中都会用到这两种框架。
小公司:使用 Mybaits-plus 会更多,因为框架是现有的。
大公司:使用 Mybatis 会更多,不是他们不同 MP,而是大公司,有能力自己封装成 MP 这样的框架。
自己封装,要花费很高的研发成本,但是,使用起来,比 MP 更加好用。
小公司,没有这么高的研发经费。
大公司,注重开发效率,开发便捷,自己封装框架,用起来方便。
MP 和 Mybatis 的使用选择:
Mybatis-Plus 包含了 Mybatis 的所有功能,还在其基础上,进行了加强。
十分建议,直接导入 MP的依赖 就行,使用 MP。
Mybaits 的功能,导入 MP的依赖 后,依旧可以使用。
之前学过了 xml直接生成功能,也是可以直接生成,在 MP 的环境中使用的。
但是,MP 有更加强大的功能,建议使用 MP 进行项目的开发。
下一篇博客:
最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!