MyBatisPlus学习笔记

To be continue…

文章目录

    • 介绍
    • 快速入门
      • 入门案例
      • 常用注解
      • 常用配置
    • 核心功能
      • 条件构造器
      • 自定义SQL
      • Service接口

介绍

MyBatisPlus只做增强不做改变,引入它不会对现有工程产生影响。只需简单配置,即可快速进行单表CRUD操作,从而节省大量时间。
官方文档:MyBatisPlus

快速入门

入门案例

  1. 引入MyBatisPlus依赖
    mybatis-plus-boot-starter集成了MyBatis和MyBatisPlus的所有功能,因此可以用MyBatisPlus的starter代替MyBatis的starter:
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>
  1. 定义Mapper
    自定义的Mapper继承MyBatisPlus提供的BaseMapper接口,并指定泛型为对应的实体类:
public interface UserMapper extends BaseMapper<User> {
}

BaseMapper接口中定义了基本的单表增删改查方法

常用注解

MyBatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息。
实体类与数据库表的映射约定为:

  • 类名驼峰转下划线作为表名
  • 名为id的字段作为主键
  • 变量名驼峰转下划线作为表的字段名

若实体类不符合约定的命名,需要使用注解进行配置,常用的注解有:

  • @TableName:用于指定表名
  • @TableId:用于指定表中的主键字段信息
  • @TableField:用于指定表中的普通字段信息

@TableId主键类型 idType枚举类型:

  • AUTO:数据库自增长(最常用)
  • INPUT:通过set方法自行输入
  • ASSIGN_ID:分配ID+接口IdentifierGenerator的方法nextId来生成id,默认实现类为DefaultIdentifierGenerator雪花算法
    默认为ASSIGN_ID

使用@TableField的常见场景:

  • 成员变量名与数据库字段名不一致
  • 成员变量名以is开头,且是布尔值
  • 成员变量名与数据库关键字冲突,例如@TableField("order") 需要加上反引号
  • 成员变量不是数据库字段,例如@TableField(exist = false)

常用配置

在application.yaml中根据需要添加配置:

mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: auto

核心功能

条件构造器

QueryWrapper和LambdaQueryWrapper通常用于构建select、delete、update的where条件部分
UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用
尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码

基于QueryWrapper的查询

@Test
// 查询出名字带o的,存款大于1000元的人的id, username, info, balance
void testQueryWrapper() {// 构建查询条件QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);// 查询List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}
@Test
// 更新用户名为jack的用户的余额为2000
void testUpdateByQueryWrapper() {// 要更新的数据User user = new User();user.setBalance(2000);// 更新的条件QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "Jack");// 执行更新userMapper.update(user, wrapper);
}

基于UpdateWrapper的更新

 @Test// 更新id为1, 2, 4的用户的余额扣200void testUpdateWrapper() {List<Long> ids = List.of(1L, 2L, 4L);UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance - 200").in("id", ids);userMapper.update(null, wrapper);}

基于LambdaQueryWrapper的查询

@Test
void testLambdaQueryWrapper() {LambdaQueryWrapper<User> wrapper = new QueryWrapper<User>().lambda().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}

自定义SQL

利用MyBatisPlus的Wrapper来构建复杂的where条件,然后自己定义SQL语句中剩余的部分

  1. 基于Wrapper构建where条件
@Test
// 将id在指定范围的用户(例如1、2、4)的余额扣减指定值
void testCustomSqlUpdate() {List<Long> ids = List.of(1L, 2L, 4L);int amount = 200;QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);userMapper.updateBalanceByIds(wrapper, amount);
}
  1. 在mapper方法参数中用Param注解声明wrapper变量名称,必须是ew
void updateBalanceByIds(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper, @Param("amount") int amount);
  1. 自定义SQL,并使用wrapper条件
    可以在方法上使用注解,也可以在xml中写SQL
  <update id="updateBalanceByIds">update tb_userset balance = balance - #{amount} ${ew.customSqlSegment}</update>

Service接口

  1. 自定义Service接口继承IService接口
@Service
public interface IUserService extends IService<User> {
}
  1. 自定义Service实现类,实现自定义接口并继承ServiceImpl类
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
  1. 开发基础业务接口
@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {@Qualifier("IUserService")private final IUserService userService;@ApiOperation("新增用户接口")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO) {// 把DTO拷贝到POUser user = BeanUtil.copyProperties(userDTO, User.class);// 新增userService.save(user);}@ApiOperation("删除用户接口")@DeleteMapping("{id}")public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id) {userService.removeById(id);}@ApiOperation("根据id查询用户接口")@GetMapping("{id}")public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id) {User user = userService.getById(id);return BeanUtil.copyProperties(user, UserVO.class);}@ApiOperation("根据id批量查询用户接口")@GetMappingpublic List<UserVO> queryUserById(@ApiParam("用户id集合") @RequestParam("id")List<Long> ids) {List<User> users = userService.listByIds(ids);return BeanUtil.copyToList(users, UserVO.class);}
}
  1. 开发复杂业务接口
    controller层
    @ApiOperation("扣减用户余额接口")@PutMapping("/{id}/deduction/{money}")public void deductMoneyById(@ApiParam("用户id") @PathVariable("id") Long id,@ApiParam("扣减的金额") @PathVariable("money") Integer money) {userService.deductMoneyById(id, money);}

service层

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic void deductMoneyById(Long id, Integer money) {User user = getById(id);if (user == null || user.getStatus() == 2) {throw new RuntimeException("用户状态异常!");}if (user.getBalance() < money) {throw new RuntimeException("用户余额不足!");}baseMapper.deductMoneyById(id, money);}
}

mapper层

@Update("update tb_user set balance = balance - #{money} where id = #{id}")
void deductMoneyById(@Param("id") Long id, @Param("money") Integer money);

启动项目,打开swagger页面调试接口
http://localhost:8080/doc.html
在这里插入图片描述

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

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

相关文章

Python根据图片生成学生excel成绩表

学习笔记&#xff1a; 上完整代码 import os import re from openpyxl import Workbook, load_workbook from openpyxl.drawing.image import Image as ExcelImage from PIL import Image as PilImage# 定义图片路径和Excel文件路径 image_dir ./resources/stupics # 图片所…

DPIN与CESS Network达成全球战略合作,推动DePIN与AI领域创新突破

2025年1月13日, DPIN电竞酒店首次亮相&#xff0c;并于马来西亚马六甲和新加坡成功举办《A*STAR前沿考察盛典》。DPIN基金会透露&#xff0c;过去两个月&#xff0c;DPIN成功验证了去中心化GPU算力的首个应用&#xff0c;证明电竞酒店可成为快速落地的创新场景。 活动期间&…

Red Hat8:搭建FTP服务器

目录 一、匿名FTP访问 1、新建挂载文件 2、挂载 3、关闭防火墙 4、搭建yum源 5、安装VSFTPD 6、 打开配置文件 7、设置配置文件如下几个参数 8、重启vsftpd服务 9、进入图形化界面配置网络 10、查看IP地址 11、安装ftp服务 12、遇到拒绝连接 13、测试 二、本地…

K8S开启/关闭审计日志

K8S默认禁用审计 开启/关闭 k8s 审计日志 默认 Kubernetes 集群不会输出审计日志信息。通过以下配置&#xff0c;可以开启 Kubernetes 的审计日志功能。 准备审计日志的 Policy 文件配置 API 服务器&#xff0c;开启审计日志重启并验证 准备审计日志 Policy 文件 apiVersio…

OpenCV基础:获取子矩阵的几种方式

目录 相关阅读 方法一&#xff1a;使用切片操作 方法二&#xff1a;使用高级索引 方法三&#xff1a;使用条件筛选 方法四&#xff1a;使用 numpy 的 take 函数 相关阅读 OpenCV基础&#xff1a;矩阵的创建、检索与赋值-CSDN博客 OpenCV基础&#xff1a;图像运算-CSDN博客…

深度学习项目--基于LSTM的火灾预测研究(pytorch实现)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 LSTM模型一直是一个很经典的模型&#xff0c;这个模型当然也很复杂&#xff0c;一般需要先学习RNN、GRU模型之后再学&#xff0c;GRU、LSTM的模型讲解将…

计算机网络-物理层

重点内容 物理层的任务几种常用的信道复用技术几种常用的宽带接入技术&#xff0c;重点是FTTx 目录 重点内容 一.物理层的基本概念 二.数据通信基础知识 2.1通信系统模型 2.2信道 2.2.1调制 调制的两大类及其特点 1. 基带调制&#xff08;Baseband Modulation / Coding…

在服务器上增加新网段IP的路由配置

在服务器上增加新网段IP的路由配置 前提条件步骤一:检查当前路由表步骤二:添加新路由步骤三:验证新路由步骤四:持久化路由配置脚本示例结论在网络管理中,路由配置是一项基本且重要的任务。它决定了数据包在网络中的传输路径。本文将详细介绍如何在服务器上增加新的路由配置…

无降智o1 pro——一次特别的ChatGPT专业模式探索

这段时间和朋友们交流 ChatGPT 的使用心得&#xff0c;大家都提到一个很“神秘”的服务&#xff1a;它基于 O1 Pro 模型&#xff0c;能够在对话里一直保持相对高水平的理解和回复&#xff0c;不会突然变得“降智”。同时&#xff0c;整体使用还做了免折腾的网络设置——简单一点…

如何在 Google Cloud Shell 中使用 Visual Studio Code (VS Code)?

Google Cloud Shell 是一个基于浏览器的命令行界面&#xff0c;它提供了一个临时的虚拟机环境&#xff0c;允许开发者在没有本地环境配置的情况下使用 Google Cloud 的各种服务。它还提供了一个免费的 5GB 存储空间以及可以在其中执行所有 Google Cloud 操作的命令行界面。 Vis…

ToDesk设置临时密码和安全密码都可以当做连接密码使用

ToDesk 在各领域办公都已经是非常常见了 为了安全 ToDesk 设置了连接密码&#xff0c;想连接 需要输入远程码和连接密码 我们刚打开 系统默认给我们用的是临时密码&#xff0c;安全性确实很强 和定时Tokey一样&#xff0c;固定时间切换。 但是 如果我们要经常连接这个电脑&a…

语义检索效果差?深度学习rerank VS 统计rerank选哪个

前段时间我开发了一个用白话文搜索语义相近的古诗词的应用&#xff08;详见&#xff1a;《朋友圈装腔指南&#xff1a;如何用向量数据库把大白话变成古诗词》&#xff09;&#xff0c;但是有时候搜索结果却不让人满意&#xff0c;排名靠前的结果和查询的语义没啥关系&#xff0…

vue 学习笔记 - 创建第一个项目 idea

1、安装Vue CLI 查看npm版本号 &#xff08;可跳过&#xff09; % npm -v 11.0.0安装Vue CLI % npm install -g vue/cli2、创建项目 进入工程文件目录 % cd /Users/ruizhifeng/work/aina-client查看vue 版本号 &#xff08;可跳过&#xff09; % vue --version vue/cli 5…

Unity HybridCLR Settings热更设置

需要热更的程序集放到 热更新Assembly Definitions中。 记得补充元数据AOT dlls 打包完成后遇到TypeLoadException: could not load type 时 可能需要在Assets/link.xml中增加对应的设置 <assembly fullname"your assembly" preserve"all"/> link…

【tailscale 和 ssh】当服务器建立好节点,但通过客户端无法通过 ssh 连接

背景 当服务器建立好节点&#xff0c;一切显示正常但通过客户端无法通过 vs code 中的 ssh 连接到服务器 问题解决 因为服务器是重装过的&#xff0c;所以忘记在服务器上下载 ssh 了。。。安装完成并启动 SSH 服务后便可正常连接&#xff01; sudo apt update sudo apt in…

CSS:语法、样式表、选择器

目录 一、语法 二、创建 外部样式表 内部样式表 内联样式 三、选择器 ID选择器 类选择器 伪类选择器 :hover a:link a:active a:visited 属性选择器 伪元素选择器 ::first-letter ::first-line ::selection ::placeholder ::before 和::after 通配选择器 标…

HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (三、影视搜索页功能实现)

在HarmonyOS NEXT开发环境中&#xff0c;可以使用nutpi/axios库来简化网络请求的操作。本文将展示如何使用HarmonyOS NEXT框架和nutpi/axios库&#xff0c;从零开始实现一个简单的影视APP&#xff0c;主要关注影视搜索页的功能实现。 为什么选择nutpi/axios&#xff1f; nutpi…

计算机网络 (47)应用进程跨越网络的通信

前言 计算机网络应用进程跨越网络的通信是一个复杂而关键的过程&#xff0c;它涉及多个层面和组件的协同工作。 一、通信概述 计算机网络中的通信&#xff0c;本质上是不同主机中的应用进程之间的数据交换。为了实现这种通信&#xff0c;需要借助网络协议栈中的各层协议&#x…

QT开发技术 【基于TinyXml2的对类进行序列化和反序列化】一

一、对TinyXml2 进行封装 使用宏 实现序列化和反序列化 思路&#xff1a; 利用宏增加一个类函数&#xff0c;使用序列化器调用函数进行序列化 封装宏示例 #define XML_SERIALIZER_BEGIN(ClassName) \ public: \virtual void ToXml(XMLElement* parentElem, bool bSerialize …

C++速览之智能指针

1、存在的问题 c 把内存的控制权对程序员开放&#xff0c;让程序显式的控制内存&#xff0c;这样能够快速的定位到占用的内存&#xff0c;完成释放的工作。但是此举经常会引发一些问题&#xff0c;比如忘记释放内存。由于内存没有得到及时的回收、重复利用&#xff0c;所以在一…