mybatis-plus 优雅的写service接口中方法(3)

news2025/3/15 7:47:59

多表联查

上文讲过了自定义sql ,和wrapper的使用,但是我们可以发现 我们查询的都是数据库中的一张表,那么怎么进行多表联查呢,当然也是用自定义sql来进行实现

比如说  查询 id 为 1  2 4 的用户 并且 地址在北京 的 用户名称 普通的sql查询如下

select  u.username
from  tb_user u,address a where u.id=a.user_id and a.city='北京'  and u.id i
n(1,2,4);

用join on 实现多表的sql为  

select  u.username
from  tb_user u join address a on u.id=a.user_id where  a.city='北京'  and u.id in(1,2,4);

那么 我们如何用mp 来进行改造 自定义sql 来进行多表查询呢

     先用  wrapper 来进行后面 where  条件的拼接  再用自定义sql 拼接

废话不多说 直接上代码  

 然后再usermapper中定义方法 

@Select("SELECT u.* FROM user u INNER JOIN address a ON u.id = a.user_id ${ew.customSqlSegment}")
List<User> queryUserByWrapper(@Param("ew")QueryWrapper<User> wrapper);

service接口

mp不仅对基本的 mapper层进行了接口的封装,还对service层进行了接口的封装,使得 基础的crud也可以直接在controller层直接调用service层直接查询,更加提升了代码的简洁性

而使用Iservice中的方法也很简单  

通常我们有两个  一个是接口service,一个是实现接口的实现类     我们只需要让接口继承 iservice,然后让自己的实现类 实现自己的接口,并且继承serviceimpl   废话不多说  我们直接上代码

其中User是对应的数据库实体类   ,同样Usermapper 也是  

 但是我们这样说是显得太过宽泛  我们直接上例子 对service接口进行测试

接口测试

我们 假如说  现在有一个需求   根据用户的id 来进行扣减用户的余额   ,而在用户表中有一个状态  只有状态正常的

并且余额充足的才能进行余额的扣减    

现在 我们在 Usercontroller 中定义 一个方法

//根据id扣除余额
    @PutMapping("/{id}/deduction/{money}")
    void deductMoney(@PathVariable Long id,
                     @PathVariable Integer money){
        myService.deductMoney(id,money);
    }

然后是 userservice接口

package com.itheima.mp.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;

public interface IUserService extends IService<User> {
    void deductBalance(Long id, Integer money);
}

最后是实现类

package com.itheima.mp.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Override
    public void deductBalance(Long id, Integer money) {
        // 1.查询用户
        User user = getById(id);
        // 2.判断用户状态
        if (user == null || user.getStatus() == 2) {
            throw new RuntimeException("用户状态异常");
        }
        // 3.判断用户余额
        if (user.getBalance() < money) {
            throw new RuntimeException("用户余额不足");
        }
        // 4.扣减余额
        baseMapper.deductMoneyById(id, money);
    }
}

 mapper中的实现接口为  

@Update("UPDATE user SET balance = balance - #{money} WHERE id = #{id}")
void deductMoneyById(@Param("id") Long id, @Param("money") Integer money);

但是 但是这样是否有点不太优雅   那么  我们怎么把他变得优雅? 来  让我们改造一下

优雅的接口测试

首先  我们可以看到 在 我们对比用户状态的时候 用户状态异常的数字是写死的,这样写有没有问题,没有问题,但是假如我们以后用了多个用户状态的的数字,以后想改 是不是特别 的麻烦  ,所以我们干脆定义一个枚举类型,来进行 用户状态的对比

我们原来user实体类中的类型 是 

是interger类型的对比 ,下面 我们 定义一个如下的枚举   

 并在mp的yaml文件中配置枚举处理器

mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

配置好 之后再把user实体类中的 状态的类型 改成 枚举类型     

好,那么现在我们来解释一下  枚举类型中的注解  

使用enumvalue 注解,代表着  枚举类中的哪个值 作为 数据库status字段的值    

比如说   我们  数据库中定义的字段status为  int类型的,然后我们对应的数据库user表的实体类user 的类型是 枚举类型的这样就会导致我们在查询插入的时候出现类型转换的错误,我们加上这个注解,开启配置枚举处理器,就可以 实现二者值之间的自动转换  

下面 我们来 写一个例子

@PostMapping
    void   userSelect(@Param("id") Long id){
//通过枚举类型 加用户id进行查询
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().eq(User::getId, id).eq(User::getStatus, UserStatus.NORMAL);
    User user1 = myService.getBaseMapper().selectOne(wrapper);
    System.out.println(user1);

    //使用枚举类型插入用户

    User user = new User();
//我们着重看这一行 setstatus
    user.setStatus(UserStatus.NORMAL);
    user.setUsername("wang");
    user.setPassword("123456");
    UserInfo userInfo = new UserInfo();
    userInfo.setAge(1);
    userInfo.setGender("22");
    userInfo.setIntro("6666666");
    user.setInfo(userInfo);
    myService.save(user);
}

 下面我们用apifox进行测试  

可以看到  用了enumvalue注解  已经成功的把枚举类型转换成数据库类型了,是不是灰常的优雅

优雅的json处理器

在上文中我们看到 怎么还有个userinfo 那玩意是什么鬼 ,下面我们来解释一下 

 在数据库中 我们的info字段定义的是一个json类型

但是 在我么们user实体类中确实 一个string类型的 字段  ,在我们插入的时候 会非常的麻烦 我们需要把字符串类型写成类似于json类型进行插入,这样太麻烦   

我们  直接可以定义一个json类型的实体类 ,然后把user实体类的类型换成该json类型的实体类 ,然后再user实体类字段上加上json类型处理器的注解  就可以完成转换

@Data
@AllArgsConstructor(staticName = "set")
@NoArgsConstructor
public class UserInfo {
    private Integer age;
    private  String intro;
    private  String gender;
}

这样我们再插入的时候 就可以完成 json类型之间的转换了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1695231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

告诉老板,AI大模型应该这样部署!

导语 随着大语言模型创新的快速步伐&#xff0c;企业正在积极探索用例并将其第一个生成式人工智能应用程序部署到生产中。 随着今年LLM或LLMOps的部署正式开始&#xff0c;企业根据自己的人才、工具和资本投资结合了四种类型的LLM部署方法。请记住&#xff0c;随着新的 LLM 优…

第199题|关于函数的周期性问题|函数强化训练(六)|武忠祥老师每日一题 5月24日

解题思路&#xff1a;解这道题我们要用到下面这个结论 f(x)连续&#xff0c;以T为周期时&#xff0c;原函数以T为周期的充分必要条件是&#xff1a; (A) sin x显然是以π为周期的&#xff0c;我们可以看到并不等于0,根据结论&#xff0c;A的原函数显然不是周期函数。 (B) 的…

Linux|如何在 awk 中使用流控制语句

引言 当您从 Awk 系列一开始回顾我们迄今为止介绍的所有 Awk 示例时&#xff0c;您会注意到各个示例中的所有命令都是按顺序执行的&#xff0c;即一个接一个。但在某些情况下&#xff0c;我们可能希望根据某些条件运行一些文本过滤操作&#xff0c;这就是流程控制语句的方法。 …

Windows VS2022 C语言使用 sqlite3.dll 访问 SQLite数据库

今天接到一个学生C语言访问SQLite数据库的的需求: 第一步,SQLite Download Page下载 sqlite3.dll 库 下载解压,发现只有两个文件: 于是使用x64 Native Tools Command Prompt 终端 生成 sqlite3.lib 和 sqlite3.exp文件 LIB -def:sqlite3.def -out:sqlite3.lib -machin…

Cloneable接口和深拷贝

在java中如何对对象进行拷贝呢&#xff1f;我们可以使用Object类中的clone方法。 一、浅拷贝 在使用clone方法对对象进行拷贝的时候&#xff0c;需要注意&#xff1a; 1.需要重写clone方法&#xff1b; 2.clone方法的返回值是Object类&#xff0c;需要强制类型转化&#xf…

微信小程序-常用的视图容器类组件

一.组件分类 小程序中的组件也是由宿主环境提供的&#xff0c;开发者可以基于组件快速搭建出漂亮的页面结构。 官方把小程序的组件分为了9大类: (1) 视图容器 (2) 基础内容 (3) 表单组件 (4)导航组件 (5) 媒体组件 (6) map 地图组件 (7) canvas 画布组件 (8) 开放能力 (9) 无…

spark学习

standalone环境部署 1.standalone架构 standalone是完整的spark运行环境&#xff0c;其中&#xff1a;Master角色以Master进程存在&#xff0c;Worker角色以Woker进程存在&#xff0c;Driver角色在运行时存在Master进程内&#xff0c;Executeor运行在Worker进程内 standalon…

前缀和,差分算法理解

前缀和是什么&#xff1a; 前缀和指一个数组的某下标之前的所有数组元素的和&#xff08;包含其自身&#xff09;。前缀和分为一维前缀和&#xff0c;以及二维前缀和。前缀和是一种重要的预处理&#xff0c;能够降低算法的时间复杂度 说个人话就是比如有一个数组&#xff1a; …

【408真题】2009-13

“接”是针对题目进行必要的分析&#xff0c;比较简略&#xff1b; “化”是对题目中所涉及到的知识点进行详细解释&#xff1b; “发”是对此题型的解题套路总结&#xff0c;并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材&#xff08;2025版&…

【NumPy】NumPy与Pandas集成应用:数据处理的强强联合

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

从git上拉取项目进行操作

1.Git的概念 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速的处理从很小到非常大的项目版本管理。它实现多人协作的机制是利用clone命令将项目从远程库拉取到本地库&#xff0c;做完相应的操作后再利用push命令从本地库将项目提交至远程库。 2.Git的工作流程…

mysql 删除特殊字符 表中存了特殊字符 换行符 回车符 word字符 查询不到

省流&#xff1a; UPDATE t1 SET f1 REPLACE(REPLACE( f1 , CHAR(10), ), CHAR(13), ); 用 replace() 函数将 换行符char(10) 和 回车符char(13) 替换为空字符串。 char(10)&#xff1a;换行 char(13)&#xff1a;回车 发现表里存进很多换行符&#xff0c;如下图&#xff1a…

【知识拓展】ngrok-高性价比的内网穿透工具

前言 使用google colab运行的web应用无法打开进行测试。 第一时间想到是否有相关工具能将内网映射到外网供访问。于是找到了ngrok。 ngrok 是什么&#xff0c;我们为什么要使用它&#xff1f; ngrok官网是一个全球分布的反向代理&#xff0c;无论您在哪里运行&#xff0c;它…

vue3 <script setup> 语法糖时间组件

<template><div><p>当前时间Current Time: {{ currentTime }}</p></div> </template><script setup> import { ref, onBeforeUnmount, onMounted } from vueconst currentTime ref()let interval // 声明 interval 变量const getTo…

二叉树OJ题目

一.二叉树第k层结点个数 有这样的一个思路&#xff1a;我既然要求第k层的结点个数&#xff0c;我肯定是要用到递归&#xff0c;那么当我在递归到第k层的时候我就开始判断&#xff0c;这一层是不是我所需要的那一层&#xff0c;如果是&#xff0c;就计数有几个节点&#xff0c;…

IDEA中好用的插件

IDEA中好用的插件 CodeGeeXMybatis Smart Code Help ProAlibaba Java Coding Guidelines​(XenoAmess TPM)​通义灵码常用操作 TranslationStatisticGrep Console CodeGeeX 官网地址&#xff1a;https://codegeex.cn/ 使用手册&#xff1a;https://zhipu-ai.feishu.cn/wiki/Cu…

cocosCreator动态生成二维码

cocosCreator 版本&#xff1a;3.7.2 开发语言&#xff1a;typeScript 我们在游戏开发中&#xff0c;经常会生成一个专属于玩家个人的二维码&#xff0c;比如说推广、充值等功能。 接到这个任务&#xff0c;在网上找了下&#xff0c;还是有很多教程的。但是这些教程大部分都是用…

虚拟化技术[3]之网络虚拟化

网络虚拟化 网络虚拟化简介核心层网络虚拟化接入层网络虚拟化虚拟机网络虚拟化案例: VMware网络虚拟化技术虚拟网络接口卡虚拟交换机vSwitch分布式交换机端口组VLAN 网络虚拟化简介 传统的数据中心&#xff1a;服务器之间操作系统和上层软件异构、接口与数据格式不统一&#x…

微信小程序连接阿里云快速入门【物联网】

一、前言 1.1 项目背景 随着5G的逐渐普及&#xff0c;万物互联的浪潮已经席卷而来。在万物互联的场景下&#xff0c;如何实现设备之间的互联互通&#xff0c;成为了一个亟待解决的问题。 微信小程序作为一款轻量级的小程序开发框架&#xff0c;以其简洁的语法和丰富的组件库…

【制作100个unity游戏之26】unity2d横版卷轴动作类游13(附带项目源码)

最终效果 系列导航 文章目录 最终效果系列导航前言存储点灯光后处理存储位置信息存储更多数据存储场景信息持久化存储数据引入Unity 的可序列化字典类调用 游戏结束源码完结 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各…