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

多表联查

上文讲过了自定义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 {@Overridepublic 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 的类型是 枚举类型的这样就会导致我们在查询插入的时候出现类型转换的错误,我们加上这个注解,开启配置枚举处理器,就可以 实现二者值之间的自动转换  

下面 我们来 写一个例子

@PostMappingvoid   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();
//我们着重看这一行 setstatususer.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.mzph.cn/web/14979.shtml

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

相关文章

Elasticsearch不删原有jdk8导致的系列安装和启动问题

以前在空机器直接装elasticsearch&#xff0c;没有遇到什么问题。今天在现有JDK上安装&#xff0c;遇到的问题记录一下&#xff1a; 1. JDK的环境变量配置与我原有的不一致报如下错误&#xff1a; [estestZK-DES-I root]$ /usr/elasticsearch/bin/elasticsearch could not fi…

python-数据分析与可视化基础

1、data1.csv中的B、C、D和E列数据分别是日期、权重、A企业的销售额、B企业的销售额。读取C、D、E列数据,并统计E列数据的算术平均数、加权平均值(权值为C列数据)、方差、中位数、最小值、最大值。并绘制E列数据的直方图。 &#xff08;1&#xff09;源代码&#xff1a; impo…

什么生信流程语言让你极度爽?

生信流程搭建有多难&#xff1f;行业为解决这一问题提出了各种各样的配方&#xff0c;有你熟悉的吗&#xff1f; 一、困境 - 乱 无数机构投入大量人力物力&#xff0c;以期获得一条条可用的生信流程。而有些流程&#xff0c;由于种种原因&#xff0c;存在着巨大的缺陷&#xf…

安全风险 - 切换后台时背景模糊处理

因为安全风险中提到当app处于后台卡片状态时&#xff0c;显示的卡片页面应该为模糊效果&#xff0c;否则容易泄露用户隐私&#xff0c;尤其当前页涉及个人信息、资产信息等&#xff0c;都会造成信息泄露&#xff01;基于这种场景&#xff0c;我研究了下这种业务下的模糊效果 找…

普通函数的参数中的auto

2.1 普通函数的参数中的auto 从c14起&#xff0c;lambda可以使用auto占位符声明或者定义参数: auto printColl [] (const auto& coll) // generic lambda{ for (const auto& elem : coll) {std::cout << elem << \n;}} 只要支持Lambda 内部的操作&…

Golang创建文件夹

方法 package zdpgo_fileimport ("os" )// AddDir 创建文件夹 func AddDir(dir string) error {if !IsExist(dir) {return os.MkdirAll(dir, os.ModePerm)}return nil }测试 package zdpgo_fileimport "testing"func TestAddDir(t *testing.T) {data : […

JAVA云HIS医院系统源码 HIS源码:云HIS系统与SaaS的关系

云HIS系统与SaaS的关系 云HIS系统是一种基于云计算技术的医院信息系统&#xff0c;它采用B/S架构&#xff0c;通过云端SaaS服务的方式提供。用户可以通过浏览器访问云HIS系统&#xff0c;无需关注系统的部署、维护、升级等问题。云HIS系统通常具有模板化、配置化、智能化等特点…

hot100 -- 回溯(上)

目录 &#x1f35e;科普 &#x1f33c;全排列 AC DFS &#x1f6a9;子集 AC DFS &#x1f382;电话号码的字母组合 AC DFS &#x1f33c;组合总和 AC DFS &#x1f35e;科普 忘记 dfs 的&#xff0c;先看看这个&#x1f447; DFS&#xff08;深度优先搜索&#xf…

百度软件测试面试经历,期望薪资27K

一面 1、 请为百度搜索框设计测试用例&#xff1f; 2、百度设计框上线前需要进行那些测试&#xff1f; 界面测试&#xff0c;功能测试&#xff0c;性能测试&#xff0c;安全性测试&#xff0c;易用性测试&#xff0c;兼容性测试&#xff0c;UI测试。 3、如何查看http状态码…

重学java 38.创建线程的方式⭐

It is during our darkest moments that we must focus to see the light —— 24.5.24 一、第一种方式_继承extends Thread方法 1.定义一个类,继承Thread 2.重写run方法,在run方法中设置线程任务(所谓的线程任务指的是此线程要干的具体的事儿,具体执行的代码) 3.创建自定义线程…

基于灰狼优化算法优化支持向量机(GWO-SVM)回归预测

代码原理 基于灰狼优化算法优化支持向量机&#xff08;GWO-SVM&#xff09;的回归预测代码的原理和流程如下&#xff1a; 1. **初始化灰狼群体**&#xff1a;随机生成一定数量的灰狼&#xff0c;并初始化它们的位置和速度。 2. **初始化SVM模型参数**&#xff1a;根据问题要…

【JAVA基础之网络编程】UDP和TCP协议以及三次握手和四次挥手的过程

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1. 网络编程 1.1 概述 1.2 网络编程的三要素 1.2.1 IP地址 1.2.2 InetAddress 1.2.3 端口和协议 1.3 UDP协议 1.3.1 UDP发送数据 1.3.2 UDP接收数据 1.4…

C语言——小知识和小细节18

一、力扣题目 1、题目本体 2、题解 本题目我们使用异或分组的方法来解决。可以在我之前的文章《C语言——操作符CSDN博客》中看一下异或的特点。 由于异或的运算规则为相同为0&#xff0c;不同为1&#xff0c;而且是在二进制补码上进行操作的&#xff0c;我们可以发现的一个…

c++|多态

c|多态 1 多态的概念2 多态的定义及其实现2.1 满足多态的条件2.2 虚函数2.3 虚函数的重写2.4 析构函数适合加virtural吗2.4 C11 override 和 final2.5 三个概念的对比 3 多态的原理4 抽象类4.1 概念4.2 纯虚函数 1 多态的概念 多态的概念&#xff1a;通俗来说&#xff0c;就是…

【再探】设计模式—代理模式

代理是指授权代理人在一定范围内代表其向第三方进行处理有关事务。 1 代理模式 需求&#xff1a;1&#xff09;将业务代码与非业务代码分离&#xff0c;在不改变代码结构的基础上&#xff0c;为其添加新的功能。2&#xff09;为系统中的某些操作做同一处理&#xff0c;例如进…

[实例] Unity Shader 逐像素漫反射与半兰伯特光照

漫反射光照是Unity中最基本最简单的光照模型&#xff0c;本篇将会介绍在片元着色器中实现反射效果&#xff0c;并会采用半兰伯特光照技术对其进行改进。 1. 逐顶点光照与逐像素光照 在Unity Shader中&#xff0c;我们可以有两个地方可以用来计算光照&#xff1a;在顶点着色器…

z3-加法器实验

补码器加减法&#xff0c;运算方法简介 我们要知道什么是补码的加法&#xff0c;我们为什么要用补码的加法&#xff1f; 补码的加法其实就是将两个补码形式的二进制数字直接相加&#xff0c;处理的时候忽略超出固定位数的进位。补码的加法运算和无符号二进制数的加法操作一样&…

【最新区块链论文录用资讯】CCF A — SP 2024 共17篇

Conference&#xff1a;45th IEEE Symposium onSecurity and Privacy CCF level&#xff1a;CCF A Categories&#xff1a;网络与信息安全 Year&#xff1a;2024 Num&#xff1a;17 Efficient Zero-Knowledge Arguments For Paillier Cryptosystem Paillier 加密系统的有效…

基于python的网页自动刷新工具

1.下载webdriver https://msedgewebdriverstorage.z22.web.core.windows.net/?prefix122.0.2365.59/下载Edge的浏览器驱动 2.安装selenium pip install selenium4.11.1 3.写代码 # -*- coding: utf-8 -*- import tkinter as tk from tkinter import messagebox import thr…

【halcon】set_part 实现平移和缩放 彻悟版

背景 之前写了一篇关于set_part 的文章 &#xff0c;确实也实现了平移和缩放。平移是对的&#xff0c;但是缩放其实有畸变。这个问题一直都困扰着我&#xff0c;知道昨天连续测试了好几个小时&#xff0c;直到晚上11点终于完美解决。 坐标和高宽 坐标 再讲set_part 之前&am…