MyBatis-Plus 实战教程三 拓展插件

文章目录

  • 扩展功能
    • 代码生成
      • 安装插件
      • 使用
    • 静态工具
    • 逻辑删除
    • 通用枚举
      • 定义枚举
      • 配置枚举处理器
      • 测试
    • JSON类型处理器
      • 定义实体
      • 使用类型处理器
    • 仓库地址

扩展功能

代码生成

在使用MybatisPlus以后,基础的Mapper、Service、PO代码相对固定,重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成PO、Mapper、Service等相关代码。只不过代码生成器同样要编码使用,也很麻烦。
这里推荐大家使用一款MybatisPlus的插件,它可以基于图形化界面完成MybatisPlus的代码生成,非常简单。

安装插件

在Idea的plugins市场中搜索并安装MyBatisPlus插件:
请添加图片描述

然后重启你的Idea即可使用。

使用

刚好数据库中还有一张address表尚未生成对应的实体和mapper等基础代码。我们利用插件生成一下。
首先需要配置数据库地址,在Idea顶部菜单中,找到other,选择Config Database:
请添加图片描述

在弹出的窗口中填写数据库连接的基本信息:
请添加图片描述

点击OK保存。
然后再次点击Idea顶部菜单中的other,然后选择Code Generator:
请添加图片描述

在弹出的表单中填写信息:
请添加图片描述

最终,代码自动生成到指定的位置了:

静态工具

有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法签名基本一致,也可以帮助我们实现CRUD功能:

示例:


@Test
void testDbGet() {User user = Db.getById(1L, User.class);System.out.println(user);
}@Test
void testDbList() {// 利用Db实现复杂条件查询List<User> list = Db.lambdaQuery(User.class).like(User::getUsername, "o").ge(User::getBalance, 1000).list();list.forEach(System.out::println);
}@Test
void testDbUpdate() {Db.lambdaUpdate(User.class).set(User::getBalance, 2000).eq(User::getUsername, "Rose");
}

需求:改造根据id用户查询的接口,查询用户的同时返回用户收货地址列表
首先,我们要添加一个收货地址的VO对象:

package com.onenewcode.mpdemo.domain.vo;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "收货地址VO")
public class AddressVO{@ApiModelProperty("id")private Long id;@ApiModelProperty("用户ID")private Long userId;@ApiModelProperty("省")private String province;@ApiModelProperty("市")private String city;@ApiModelProperty("县/区")private String town;@ApiModelProperty("手机")private String mobile;@ApiModelProperty("详细地址")private String street;@ApiModelProperty("联系人")private String contact;@ApiModelProperty("是否是默认 1默认 0否")private Boolean isDefault;@ApiModelProperty("备注")private String notes;
}

然后,改造原来的UserVO,添加一个地址属性:

接下来,修改UserController中根据id查询用户的业务接口:

@GetMapping("/{id}")
@ApiOperation("根据id查询用户")
public UserVO queryUserById(@PathVariable("id") Long userId){// 基于自定义service方法查询return userService.queryUserAndAddressById(userId);
}

由于查询业务复杂,所以要在service层来实现。首先在IUserService中定义方法:

package com.onenewcode.mpdemo.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.onenewcode.mpdemo.domain.po.User;
import com.onenewcode.mpdemo.domain.vo.UserVO;public interface UserService extends IService<User> {void deduct(Long id, Integer money);UserVO queryUserAndAddressById(Long userId);
}

然后,在UserServiceImpl中实现该方法:

@Override
public UserVO queryUserAndAddressById(Long userId) {// 1.查询用户User user = getById(userId);if (user == null) {return null;}// 2.查询收货地址List<Address> addresses = Db.lambdaQuery(Address.class).eq(Address::getUserId, userId).list();// 3.处理voUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);userVO.setAddresses(BeanUtil.copyToList(addresses, AddressVO.class));return userVO;
}

在查询地址时,我们采用了Db的静态方法,因此避免了注入AddressService,减少了循环依赖的风险。

逻辑删除

对于一些比较重要的数据,我们往往会采用逻辑删除的方案,即:

  • 在表中添加一个字段标记数据是否被删除
  • 当删除数据时把标记置为true
  • 查询时过滤掉标记为true的数据
    一旦采用了逻辑删除,所有的查询和删除逻辑都要跟着变化,非常麻烦。

为了解决这个问题,MybatisPlus就添加了对逻辑删除的支持。
注意,只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除。

例如,我们给address表添加一个逻辑删除字段:

alter table address add deleted bit default b'0' null comment '逻辑删除';

然后给Address实体添加deleted字段:
请添加图片描述

接下来,我们要在application.yml中配置逻辑删除字段:

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

测试:
首先,我们执行一个删除操作:

@Test
void testDeleteByLogic() {// 删除方法与以前没有区别addressService.removeById(59L);
}

方法与普通删除一模一样,但是底层的SQL逻辑变了:
请添加图片描述

查询一下试试:

@Test
void testQuery() {List<Address> list = addressService.list();list.forEach(System.out::println);
}

会发现id为59的确实没有查询出来,而且SQL中也对逻辑删除字段做了判断:

综上, 开启了逻辑删除功能以后,我们就可以像普通删除一样做CRUD,基本不用考虑代码逻辑问题。还是非常方便的。
注意:
逻辑删除本身也有自己的问题,比如:

  • 会导致数据库表垃圾数据越来越多,从而影响查询效率
  • SQL中全都需要对逻辑删除字段做判断,影响查询效率
    因此,我不太推荐采用逻辑删除功能,如果数据不能删除,可以采用把数据迁移到其它表的办法。

通用枚举

User类中有一个用户状态字段:
请添加图片描述

像这种字段我们一般会定义一个枚举,做业务判断的时候就可以直接基于枚举做比较。但是我们数据库采用的是int类型,对应的PO也是Integer。因此业务操作时必须手动把枚举与Integer转换,非常麻烦。
因此,MybatisPlus提供了一个处理枚举的类型转换器,可以帮我们把枚举类型与数据库类型自动转换。

定义枚举

我们定义一个用户状态的枚举:
请添加图片描述

代码如下:

package com.onenewcode.mpdemo.enums;import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;@Getter
public enum UserStatus {NORMAL(1, "正常"),FREEZE(2, "冻结");private final int value;private final String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
}

然后把User类中的status字段改为UserStatus 类型:
请添加图片描述

要让MybatisPlus处理枚举与数据库类型自动转换,我们必须告诉MybatisPlus,枚举中的哪个字段的值作为数据库值。
MybatisPlus提供了@EnumValue注解来标记枚举属性:
请添加图片描述

配置枚举处理器

在application.yaml文件中添加配置:

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

测试

@Test
void testService() {List<User> list = userService.list();list.forEach(System.out::println);
}

最终,查询出的User类的status字段会是枚举类型

JSON类型处理器

数据库的user表中有一个info字段,是JSON类型
格式像这样:
{“age”: 20, “intro”: “佛系青年”, “gender”: “male”}
而目前User实体类中却是String类型:
这样一来,我们要读取info中的属性时就非常不方便。如果要方便获取,info的类型最好是一个Map或者实体类。

而一旦我们把info改为对象类型,就需要在写入数据库时手动转为String,再读取数据库时,手动转换为对象,这会非常麻烦。

因此MybatisPlus提供了很多特殊类型字段的类型处理器,解决特殊字段类型与数据库类型转换的问题。例如处理JSON就可以使用JacksonTypeHandler处理器。

定义实体

首先,我们定义一个单独实体类来与info字段的属性匹配:
代码如下:

package com.onenewcode.mpdemo.domain.po;import lombok.Data;@Data
public class UserInfo {private Integer age;private String intro;private String gender;
}

使用类型处理器

接下来,将User类的info字段修改为UserInfo类型,并声明类型处理器:
请添加图片描述

同时,为了让页面返回的结果也以对象格式返回,我们要修改UserVO中的info字段:
请添加图片描述

仓库地址

https://github.com/onenewcode/mp-demo.git

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

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

相关文章

openpnp - src - 配置文件载入过程的初步分析

文章目录 openpnp - src - 配置文件载入过程的初步分析概述笔记自己编译用的git版本报错截图问题1 - 怎么在调试状态下, 定位到抛异常的第一现场?结合单步调试找到的现场, 来分析报错的原因openpnp配置文件读取的流程END openpnp - src - 配置文件载入过程的初步分析 概述 从…

工厂模式(Factory)

简单工厂模式 简单工厂模式又叫静态工厂模式&#xff0c;顾名思义&#xff0c;它是用来实例化目标类的静态类。下面我主要通过一个简单的实例说明简单工厂及其优点。 工厂方法模式 工厂方法模式和简单工厂模式在结构上的不同是很明显的。工厂方法模式的核心是一个抽象工厂类…

npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。

1 bug描述 使用vscode执行npm run dev指令时出现 “npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次 “ 的错误提示&#xff0c;原因是系统里没有安装n…

【机器学习】loss损失讨论

大纲 验证集loss上升&#xff0c;准确率也上升&#xff08;即将overfitting&#xff1f;&#xff09;训练集loss一定为要为0吗 Q1. 验证集loss上升&#xff0c;准确率也上升 随着置信度的增加&#xff0c;一小部分点的预测结果是错误的&#xff08;log lik 给出了指数级的惩…

微信小程序设计之页面文件pages

一、新建一个项目 首先&#xff0c;下载微信小程序开发工具&#xff0c;具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后&#xff0c;注册小程序账号&#xff0c;具体注册方法&#xff0c;可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…

C++笔记-RTTR编译安装简单使用

这里以Linux为例&#xff0c;我使用的机器的gcc版本是4.9.2 使用的RTTR的版本是0.9.5 编译&安装 首先在官网将rttr的0.9.5版本下载下来。 Home |RTTR 按照官方的安装流程&#xff1a; 但这里可能会出现一个问题&#xff1a; 按照解答&#xff0c;切换成root用户&#x…

【设计模式】第13节:结构型模式之“享元模式”

一、简介 所谓“享元”&#xff0c;顾名思义就是被共享的单元。享元模式的意图是复用对象&#xff0c;节省内存&#xff0c;前提是享元对象是不可变对象。 实现&#xff1a;通过工厂模式&#xff0c;在工厂类中&#xff0c;通过一个Map或者List来缓存已经创建好的享元对象&am…

文件夹比较工具怎么用 对比两个文件夹找出多余的文件

在日常工作中&#xff0c;经常会接触到大量的文件&#xff0c;长时间堆积&#xff0c;文件夹会越来越多&#xff0c;从而导致文件重复&#xff0c;如果想要找出想要的文件会比较麻烦&#xff0c;那么你知道应该怎么来查找吗&#xff1f;下面就让我们来学习一下文件夹比较工具怎…

香港服务器运行不正常原因简析

​  网站在线业务的部署需要服务器的存在。于我们而言&#xff0c;租用正规服务商(正规机房)的服务器&#xff0c;一般情况下是会很少出现问题。但&#xff0c;要知道&#xff0c;再稳定的服务器也有出现问题的时候&#xff0c;香港服务器也不例外&#xff0c;而且恰恰这个原…

分类预测 | Matlab实现KOA-CNN-GRU-selfAttention多特征分类预测(自注意力机制)

分类预测 | Matlab实现KOA-CNN-GRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09; 目录 分类预测 | Matlab实现KOA-CNN-GRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09;分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matla…

C语言基础简述(一)

目录 1. 标准输入输出库 2. 定义变量 3. 关于基本数据类型 3.1 计算机如何存储数据 3.2 基本数据类型 3.2.1 数值类型 3.2.1.1 整数类型 3.2.1.2 浮点数类型 3.2.2 字符类型 3.2.2.1 ASCII表 4. 进制数之间的转换 4.1 十进制整数和二进制之间的相互转换 5. C语言运…

椭圆曲线在SM2加解密中的应用(三)

一、SM2加密运算 1.1加密原始数据 SM2加密运算首先是用户A对数据加密&#xff0c;用户A拥有原始数据 椭圆曲线系统参数长度为klen比特的消息M公钥Pb 椭圆曲线系统参数&#xff0c;已经在 椭圆曲线参数&#xff08;二&#xff09;中详细介绍&#xff1b;M就是需要加密消息&am…

Ajax学习笔记第三天

做决定之前仔细考虑&#xff0c;一旦作了决定就要勇往直前、坚持到底&#xff01; 【1 ikunGG邮箱注册】 整个流程展示&#xff1a; 1.文件目录 2.页面效果展示及代码 mysql数据库中的初始表 2.1 主页 09.html:里面代码部分解释 display: inline-block; 让块元素h1变成行内…

前端移动web高级详细解析三

模拟移动设备&#xff0c;方便查看页面效果 屏幕分辨率 分类&#xff1a; 物理分辨率&#xff1a;硬件分辨率&#xff08;出厂设置&#xff09; 逻辑分辨率&#xff1a;软件 / 驱动设置 结论&#xff1a;制作网页参考 逻辑分辨率 视口 作用&#xff1a;显示 HTML 网页的区…

winodos下使用VS2022编译eclipse-paho.mqtt.c并演示简单使用的 demo

本文演示C语言如何使用eclipse-paho.mqtt.c库&#xff0c;包含自行编译库的步骤或者下载编译好的文件。 1.下载paho.mqtt.c库源码&#xff08;zip 文件&#xff09; 到官网选择C版本的paho源码进行下载 Eclipse Paho | The Eclipse Foundation 或者到下述连接下载 Releases ec…

SpringBoot面试题8:运行 Spring Boot 有哪几种方式?Spring Boot 需要独立的容器运行吗?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:运行 Spring Boot 有哪几种方式? 运行Spring Boot应用有多种方式,具体取决于你的需求和环境。以下是几种常见的运行Spring Boot应用的方式: 使…

论文阅读——GPT3

来自论文&#xff1a;Language Models are Few-Shot Learners Arxiv&#xff1a;https://arxiv.org/abs/2005.14165v2 记录下一些概念等。&#xff0c;没有太多细节。 预训练LM尽管任务无关&#xff0c;但是要达到好的效果仍然需要在特定数据集或任务上微调。因此需要消除这个…

Java毕业设计 SpringBoot 新能源充电桩管理系统

Java毕业设计 SpringBoot 新能源充电桩管理系统 SpringBoot 新能源充电桩管理系统 功能介绍 管理员 登录 验证码 注册 系统用户管理 普通用户管理 通知公告管理 留言管理 充电站管理 充电桩管理 充电桩预约 充电管理 订单管理 修改密码 普通用户 登录 修改个人资料 通知公告…

【洛谷算法题】P5709-Apples Prologue / 苹果和虫子【入门2分支结构】

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5709-Apples Prologue / 苹果和虫子【入门2分支结构】&#x1f30f;题目描述&am…

解决MySQL大版本升级导致.Net(C#)程序连接报错问题

数据库版本从MySQL 5.7.21 升级到 MySQL8.0.21 数据升级完成后&#xff0c;直接修改程序的数据库连接配置信息 <connectionStrings> <add name"myConnectionString" connectionString"server192.168.31.200;uidapp;pwdFgTDkn0q!75;databasemail;&q…