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>

使用$进行条件拼接。

测试通过:

总结

相关推荐
IT利刃出鞘7 分钟前
Intellij Idea--解决Cannot download “https://start.spring.io‘: Connect timedout
java·ide·intellij-idea
Victor35616 分钟前
MySQL(174)如何理解MySQL的多版本并发控制(MVCC)?
后端
Victor35617 分钟前
MySQL(176) 如何在MySQL中处理数据的并发一致性?
后端
中国lanwp18 分钟前
Spring 全局异常处理机制:多个 @ControllerAdvice 与重复 @ExceptionHandler
java·数据库·spring
Ashlee_code20 分钟前
关税战火中的技术方舟:新西兰证券交易所的破局之道 ——从15%关税冲击到跨塔斯曼结算联盟,解码下一代交易基础设施
java·python·算法·金融·架构·系统架构·区块链
Victor35622 分钟前
MySQL(175)MySQL中的视图如何影响查询性能?
后端
yh云想38 分钟前
SQL 四大语言分类详解:DDL、DML、DCL、DQL
数据库·sql·oracle
江湖中的阿龙44 分钟前
SpringBoot:基于 Redis 自定义注解实现后端接口防重复提交校验(幂等操作)
spring boot·redis·后端·幂等操作
孟婆来包棒棒糖~1 小时前
Docker快速入门
运维·spring boot·docker·容器·tomcat
hqxstudying2 小时前
SpringBoot启动项目详解
java·spring boot·后端