MybatisPlus-06.核心功能-自定义SQL

一.自定义SQL

MP这么方便了,为什么还要使用自定义SQL?那是因为直接使用MP会在service层写SQL语句,这是不符合开发规范的。

所谓自定义SQL即:

下面我们来看两个案例来理解:

1.将id在指定范围的用户(例如1、2、4)的余额扣减指定值 这种sql语句使用mp编写起来很简单,如下:

我们使用springboot三层架构编写时,是要将这部分代码编写到service层中的。这就相当于我们直接将sql语句写在了service层当中,这在许多企业开发规范中是不允许的。要求sql语句必须写在mapper层。

但是放弃mp去纯手写太复杂,mp擅长写复杂where条件,前面的部分mp也能写。但是在有些场景下mp就写不了前面的语句了。因此我们选择前面使用sql语句。后面使用mp写。

这种使用count聚合函数并且还起别名的mp也没办法实现。因此使用自定义sql。

使用mp构造复杂where语句,前面的sql语句手写,然后拼起来。当然我们不是在service层去拼,而是将mp构造的条件传递到mapper层。在mapper或xml中组装。

后面直接使用$符号将wrapper条件拼接上去,名称为ew.customSqlSegment。

二.代码实现

sql 复制代码
@Test
    void testCustomSqlUpdate() {
        // 将用户id为1,2,4的用户余额减200
        List<Long> ids = List.of(1L,2L,4L);
        int amount = 200;
        // 1.构造Wrapper来定义where语句
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
                .in("id",ids);
        userMapper.updateBalance(queryWrapper,amount);
    }

Mapper层

java 复制代码
package com.itheima.mp.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper extends BaseMapper<User> {

    void updateBalance(@Param("ew") QueryWrapper<User> queryWrapper, @Param("amount") int amount);
//
//    void saveUser(User user);
//
//    void deleteUser(Long id);
//
//    void updateUser(User user);
//
//    User queryUserById(@Param("id") Long id);
//
//    List<User> queryUserByIds(@Param("ids") List<Long> ids);
}

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.itheima.mp.mapper.UserMapper">
<!--    <insert id="saveUser" parameterType="com.itheima.mp.domain.po.User">-->
<!--        INSERT INTO `user` (`id`, `username`, `password`, `phone`, `info`, `balance`)-->
<!--        VALUES-->
<!--        (#{id}, #{username}, #{password}, #{phone}, #{info}, #{balance});-->
<!--    </insert>-->
<!--    <update id="updateUser" parameterType="com.itheima.mp.domain.po.User">-->
<!--        UPDATE `user`-->
<!--        <set>-->
<!--            <if test="username != null">-->
<!--                `username`=#{username}-->
<!--            </if>-->
<!--            <if test="password != null">-->
<!--                `password`=#{password}-->
<!--            </if>-->
<!--            <if test="phone != null">-->
<!--                `phone`=#{phone}-->
<!--            </if>-->
<!--            <if test="info != null">-->
<!--                `info`=#{info}-->
<!--            </if>-->
<!--            <if test="status != null">-->
<!--                `status`=#{status}-->
<!--            </if>-->
<!--            <if test="balance != null">-->
<!--                `balance`=#{balance}-->
<!--            </if>-->
<!--        </set>-->
<!--        WHERE `id`=#{id};-->
<!--    </update>-->
<!--    <delete id="deleteUser" parameterType="com.itheima.mp.domain.po.User">-->
<!--        DELETE FROM user WHERE id = #{id}-->
<!--    </delete>-->

<!--    <select id="queryUserById" resultType="com.itheima.mp.domain.po.User">-->
<!--        SELECT *-->
<!--        FROM user-->
<!--        WHERE id = #{id}-->
<!--    </select>-->

<!--    <select id="queryUserByIds" resultType="com.itheima.mp.domain.po.User">-->
<!--        SELECT *-->
<!--        FROM user-->
<!--        <if test="ids != null">-->
<!--            WHERE id IN-->
<!--            <foreach collection="ids" open="(" close=")" item="id" separator=",">-->
<!--                #{id}-->
<!--            </foreach>-->
<!--        </if>-->
<!--        LIMIT 10-->
<!--    </select>-->

    <update id="updateBalance">
        update tb_user set balance = balance - #{amount} ${ew.customSqlSegment}
    </update>
</mapper>

使用$进行条件拼接。

测试通过:

总结

相关推荐
编程充电站pro10 分钟前
面试陷阱:SQL 子查询 vs JOIN 的性能差异
数据库·sql
李慕婉学姐30 分钟前
【开题答辩过程】以《基于 Spring Boot 的宠物应急救援系统设计与实现》为例,不会开题答辩的可以进来看看
数据库·spring boot·宠物
canonical_entropy1 小时前
DDD本质论:从哲学到数学,再到工程实践的完整指南之理论篇
后端·低代码·领域驱动设计
一只大头猿1 小时前
基于SpringBoot和Vue的超市管理系统
前端·vue.js·spring boot
木易 士心1 小时前
MPAndroidChart 用法解析和性能优化 - Kotlin & Java 双版本
android·java·kotlin
后端小张1 小时前
SpringBoot 控制台秒变炫彩特效,秀翻同事指南!
java·后端
it技术1 小时前
Pytorch项目实战 :基于RNN的实现情感分析
pytorch·后端
好家伙VCC1 小时前
**标题:发散创新:探索AR开发框架的核心技术**随着增强现实(AR)技术的飞速发展,AR开发框架成为了开发者们关注的焦
java·ar
chools2 小时前
学习问题日记-4
java
懒人Ethan2 小时前
解决一个C# 在Framework 4.5反序列化的问题
java·前端·c#