Mybatis(17)Mybatis-Plus条件构造器(2)& 自定义 SQL

Mybatis(17)Mybatis-Plus条件构造器(2)& 自定义 SQL

文章目录

观前提醒:

如果你是第一次点击这篇博客,需要你回看Mybatis-plus系列的这个博客:
Mybatis(16)Mybatis-Plus条件构造器(1)

这篇博客的代码,都是需要自己敲一下的。

建议你看着我说的知识点,自己尝试一下,创建 Springboot项目,使用 Mybatis-plus 框架,访问数据库。

这里使用的数据库是 MySQL。

图形化工具:Navicat

sql文件获取:https://gitee.com/mrbgvhbhjv/java-ee-course

简介:

目前,条件构造器,还有另外两种:LambdaQueryWrapperLambdaUpdateWrapper 的举例使用介绍。

QueryWrapper 和 UpdateWrapper存在⼀个问题,就是需要写死字段名,如果字段名发生变更,可能会因为测试不到位酿成事故。

MyBatis-Plus 给我们提供了⼀种基于Lambda表达式的条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名,也提高了代码的可读性和可维护性。

  • LambdaQueryWrapper

  • LambdaUpdateWrapper

分别对应 QueryWrapper和UpdateWrapper。

更详细的使用,建议看官方文档:MyBatis-Plus 🚀 为简化开发而生

1. LambdaQueryWrapper

使用 lambda表达式,有两种写法:

  1. 直接创建 LambdaQueryWrapper类的对象。
  2. 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表达式,有两种写法:

  1. 直接创建 LambdaUpdateWrapper类的对象。
  2. 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 中,定义接口的两种方式):

  1. 注解,例如 @Select
  2. 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 进行项目的开发。

下一篇博客:

最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!

下一篇博客:综合案例1:图书管理系统(1)项目准备,用户登录接口,添加图书接口

相关推荐
橘子131 小时前
redis主从复制
数据库·redis·缓存
白太岁1 小时前
Redis:(5) 分布式锁实现:原子性设置锁与 Lua 释放锁
数据库·redis·分布式
zhu62019762 小时前
Postgres数据库docker快速安装
数据库·docker·容器
ruleslol2 小时前
MyBatis-Plus10:逻辑删除
mybatis-plus
王德印2 小时前
工作踩坑之导入数据库报错:Got a packet bigger than ‘max_allowed_packet‘ bytes
java·数据库·后端·mysql·云原生·运维开发
数据知道2 小时前
PostgreSQL:如何直接在数据库中查询 CSV/JSON文件?
数据库·postgresql·json
Elastic 中国社区官方博客2 小时前
Elasticsearch 9.3 增加 bfloat16 向量 支持
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
XLYcmy3 小时前
智能体大赛 核心功能 惊喜生成”——创新灵感的催化器
数据库·ai·llm·prompt·agent·检索·万方
AI_56783 小时前
ableau可视化进阶:颜色与交互设计让数据会说话
数据库·云原生·excel