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>

使用$进行条件拼接。

测试通过:

总结

相关推荐
子兮曰16 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!17 小时前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰17 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里17 小时前
java中的继承和多态的区别
java
小羊没烦恼!17 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝17 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕17 小时前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码17 小时前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖17 小时前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时18 小时前
01-06-A-JVM排查实战详解
java·jvm