MyBatis-Plus 基础

教程

视频教程:https://www.bilibili.com/video/BV1Xu411A7tL
详细文档:https://b11et3un53m.feishu.cn/wiki/PsyawI04ei2FQykqfcPcmd7Dnsc

常见注解

MybatisPlus就是根据PO实体的信息来推断出表的信息,从而生成SQL的。默认情况下:

  • 把PO实体的类名驼峰转下划线作为表名
  • 把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型
  • 把名为id的字段作为主键

@TableName

表名注解,标识实体类对应的表

@TableId

主键注解,标识实体类中的主键字段

两个属性value和type,其中type的常用类型

  • AUTO:利用数据库的id自增长
  • INPUT:手动生成id
  • ASSIGN_ID:雪花算法生成Long类型的全局唯一id,这是默认的ID策略

@TableField

普通字段注解

一般情况下我们并不需要给字段添加@TableField注解,一些特殊情况除外:

  • 成员变量名与数据库字段名不一致
  • 成员变量是以is开头且是布尔值,MybatisPlus识别字段时会把is去除,这就导致与数据库不符。
  • 成员变量名与数据库的关键字冲突。使用@TableField注解给字段名添加````转义
  • 变量不是数据表里的字段

示例:

@TableName("tb_user")
public class User {//自增长@TableId(type = IdType.AUTO)private Long id;//变量名与数据表字段名不一致@TableField("user_name")private String name;private Integer age;//成员变量是以is开头且是布尔值@TableField("is_married")private Boolean isMarried;//成员变量名与数据库的关键字冲突@TableField("`order`")private String order;//变量不是数据表里的字段@TableField(exist = false)private String info;
}

常见配置

MybatisPlus也支持基于yaml文件的自定义配置

官方文档:https://www.baomidou.com/reference/

示例:

mybatis-plus:type-aliases-package: com.itheima.mp.domain.po # 别名扫描包。当mapper.xml中定义实体类类型,就不用定义全路径名了 mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址。当前这个是默认值,可以不写,如果和这个不一样需要自定义configuration:map-underscore-to-camel-case: true # 是否开启下划线和驼峰的映射,默认开启cache-enabled: false # 是否开启二级缓存,默认开启global-config:db-config:id-type: assign_id # id为雪花算法生成,设为auto就是自增长update-strategy: not_null # 更新策略:只更新非空字段

大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值或者需要修改的,例如:

  • 实体类的别名扫描包
  • 全局id类型(默认是雪花算法)
mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: auto # 全局id类型为自增长

条件构造器

Wrapper(条件构造器)

继承关系:

在这里插入图片描述

Wrapper
AbstractWrapper:提供了where中包含的所有条件构造方法(eq、gt、lt、like等)

  • QueryWrapper:拓展了一个select方法,允许指定查询字段
  • UpdateWrapper:拓展了一个set方法,允许指定SQL中的SET部分
  • AbstractLambdaWrapper:避免写死字段名,基于Lambda表达式
    • LambdaUpdateWrapper
    • LambdaQueryWrapper

条件构造器的使用选择:

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

QueryWrapper示例:
在这里插入图片描述

    //查询名字里带o并且balance大于1000的QueryWrapper<User> queryWrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);List<User> userList = userMapper.selectList(queryWrapper);

构造器常用方法:

  • eq 就是 equal等于
  • ne 就是 not equal不等于
  • gt 就是 greater than大于
  • lt 就是 less than小于
  • ge 就是 greater than or equal 大于等于
  • le 就是 less than or equal 小于等于
  • in 就是 in 包含(数组)
  • isnull 就是 等于null
  • between 就是 在2个条件之间(包括边界值)
  • like就是 模糊查询

UpdateWrapper示例:

UPDATE user SET balance = balance + 200WHERE id in (1, 2, 4)
    //更新id符合条件的行中balance加200List<Long> ids = new ArrayList<>();Collections.addAll(ids, 1L, 2L, 4L);UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>().setSql("balance = balance + 200").in("id", ids);userMapper.update(null, updateWrapper);

LambdaQueryWrapper基于Lambda表达式,使用getter方法结合反射技术获取变量名,可以避免硬编码。
示例:

    //查询名字里带o并且balance大于1000的LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);List<User> userList = userMapper.selectList(queryWrapper);

自定义sql

上面的更新示例中,把sql语句的一部分写到业务代码中了,这种写法在一些企业也是不允许的,因为SQL语句最好都维护在持久层,而不是业务层。

所以,MybatisPlus让我们可以利用Wrapper生成查询条件,再结合Mapper.xml编写SQL语句剩下的部分。

业务代码基于Wrapper构建where条件

    // 1. 更新条件List<Long> ids = new ArrayList<>();Collections.addAll(ids, 1L, 2L, 4L);int amount = 200;// 2. 定义方法LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>().in(User::getId, ids);// 3. 调用自定义sql方法userMapper.updateBalanceByIds(wrapper, 200);

在mapper方法参数中用Param注解声明wrapper变量名称,必须是ew,可以写成 "ew" 或者 Constants.WRAPPER


import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;public interface UserMapper extends BaseMapper<User> {void updateBalanceByIds(@Param(Constants.WRAPPER) LambdaUpdateWrapper<User> wrapper, @Param("amount") int amount);
}

在xml文件中编写sql,并使用传入的Wrapper条件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.user.mapper.UserMapper"><update id="updateBalanceByIds">UPDATE user SET balance = balance + #{amount} ${ew.customSqlSegment}</update></mapper>

IService接口

在这里插入图片描述

IService接口方法详细说明

IService的 Lambda 方法

Service 中对 LambdaQueryWrapperLambdaUpdateWrapper 的用法进一步做了简化。我们无需自己通过 new 的方式来创建 Wrapper,而是直接调用 lambdaQuery()lambdaUpdate() 方法:

lambdaQuery() 示例:

	@Overridepublic List<UserVO> queryUsers(String username, Integer status, Integer minBalance, Integer maxBalance) {// 查询用户List<User> users = userService.lambdaQuery().like(username != null, User::getUsername, username).eq(status != null, User::getStatus, status).ge(minBalance != null, User::getBalance, minBalance).le(maxBalance != null, User::getBalance, maxBalance).list();// 处理voreturn BeanUtil.copyToList(users, UserVO.class);}

lambdaQuery() 方法中除了可以构建条件,还需要在链式编程的最后添加一个 list(),这是在告诉MyBatisPlus 我们的调用结果需要是一个 list 集合。这里不仅可以用 list(),可选的方法有:

  • one():最多1个结果
  • list():返回集合结果
  • count():返回计数结果

MybatisPlus会根据链式编程的最后一个方法来判断最终的返回结果。

lambdaUpdate() 示例:

    // 扣减余额 update tb_user set balance = balance - ?int remainBalance = user.getBalance() - money;lambdaUpdate().set(User::getBalance, remainBalance) // 更新余额.set(remainBalance == 0, User::getStatus, 2) // 动态判断,是否更新status.eq(User::getId, id).eq(User::getBalance, user.getBalance()) // 乐观锁.update();

修改余额的操作为了防止并发问题,加上了乐观锁,判断当前的余额和之前查到的余额是否一致。

视频教程 - IService的Lambda方法

批量新增

    // 准备10万条数据List<User> list = new ArrayList<>(1000);for (int i = 1; i <= 100000; i++) {list.add(buildUser(i));// 每1000条批量插入一次if (i % 1000 == 0) {userService.saveBatch(list);list.clear();}}

要想将多条插入SQL合并为一条,还需要在 jdbc 的 url 后面添加参数 &rewriteBatchedStatements=true

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=truedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: MySQL123

https://www.bilibili.com/video/BV1S142197x7/?p=12

扩展功能

代码生成器

推荐使用一款 MybatisPlus 的插件,它可以基于图形化界面完成 MybatisPlus 的代码生成,非常简单。
在这里插入图片描述
在这里插入图片描述
新版idea好像不能在导航栏增加 “other” 选项卡了,生成代码的两个选项迁移到"tools"选项卡了。

使用:
点击Idea顶部菜单中的other,然后选择 Code Generator
在这里插入图片描述
https://www.bilibili.com/video/BV1S142197x7?p=14

Db静态工具

有的时候 Service 之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个Db静态工具类。

    // 利用Db实现复杂条件查询List<User> list = Db.lambdaQuery(User.class).like(User::getUsername, "o").ge(User::getBalance, 1000).list();

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

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

相关文章

VMware Workstation Pro 17 下载 以及 安装 Ubuntu 20.04.6 Ubuntu 启用 root 登录

1、个人免费版本 VMware Workstation Pro 17 下载链接怎么找&#xff1f;直接咕咕 VMware 找到如下链接。链接如下&#xff1a;Workstation 和 Fusion 对个人使用完全免费&#xff0c;企业许可转向订阅 - VMware 中文博客 点进去链接之后你会看到如下&#xff0c;注意安装之后仍…

30、使用ESP8266跟SG90舵机制作四足蜘蛛机器人

目录 1、简介 2、使用例子 3、代码解析 4、资源下载 正文 1、简介 本篇使用ESP8266跟SG90舵机制作四足蜘蛛机器人,使用的180度舵机有8个,需要一块16路舵机控制板,也可以使用小一点的控制板8路也够了。下面开始今天的教程,源码在文章末尾自行下载,力求大家都能看懂。…

python 将数据保存到现有的Excel文件的新工作表

out_file ‘query.xlsx’ df1 pd.DataFrame(out_data) 若直接写入&#xff1a; df1.to_excel(out_file, indexFalse, sheet_name‘v5v7’) # 将第二个DataFrame保存到现有的Excel文件的新工作表 with pd.ExcelWriter(out_file, engine‘openpyxl’, mode‘a’) as writer:…

深度学习——激活函数、损失函数、优化器

深度学习——激活函数、损失函数、优化器 1、激活函数1.1、一些常见的激活函数1.1.1、sigmoid1.1.2、softmax1.1.3、tanh1.1.4、ReLU1.1.5、Leaky ReLU1.1.6、PReLU1.1.7、GeLU1.1.8、ELU 1.2、激活函数的特点1.2.1、非线性1.2.2、几乎处处可微1.2.3、计算简单1.2.4、非饱和性1…

智慧政务数据中台建设及运营解决方案

数据中台&#xff1a;政府数字化转型的引擎 数据中台作为政府数字化转型的核心驱动力&#xff0c;起源于美军的作战体系&#xff0c;强调高效、灵活与强大。它不仅促进了政府决策的科学性&#xff0c;还推动了政府服务的精细化与智能化。 数据中台的应用场景&#xff1a;数字…

webpack4 - 配置文件分离(详细教程)

webpack根据开发和生成环境一般可以将配置文件拆分&#xff0c;拆分dev和prod两种环境 |- package.json|- /build|- webpack.base.js|- webpack.dev.js|- webpack.prod.js在scripts里修改相应的命令 "dev": "webpack-dev-server --config build/webpack.dev.j…

单片机最小系统

若要系统正常运行&#xff0c;确保稳定工作&#xff0c;一个单片机系统最少需要四个部分&#xff1a;电源电路 单片机对工作电压是有要求的&#xff0c;如果电压过大&#xff0c;会烧坏&#xff0c;如果电压过小&#xff0c;无法运行。晶振电路 单片机的原子指令的执行依赖晶振…

计算机毕设-基于springboot的社区居民诊疗健康管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

Pycharm访问MySQL数据库·上

1.MySQL驱动模块Connector #导入数据库的驱动工具 import mysql.connector #连接数据库必备的条件 config {"host": "localhost","port": 3306,"user": "root","password": "888888","database&…

【LLM】大模型领域相关博主博客

苏剑林 真神&#xff0c;无需多言 博客地址: https://spaces.ac.cn/ Lil’Log openai的大佬&#xff0c;涉及的领域非常广&#xff0c;擅长把某个方向系统地梳理出来 博客地址: https://lilianweng.github.io/tags/ Distill 通过生动的动图和可视化技术把技术细节解释清楚 博…

day11 性能测试(4)——Jmeter使用(黑马的完结,课程不全)直连数据库+逻辑控制器+定时器

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、复习 1.1 断言&#xff08;3种&#xff09; 1.2 关联&#xff08;3种&#xff09; 1.3 录制脚本 2、Jmeter直连数据库 2.1 直连数据库——使用场景 2.2 直连数据库——操作步骤 2.2.1 案例1&…

React的状态管理库-Redux

核心思想&#xff1a;单一数据源、状态是只读的、以及使用纯函数更新状态。 组成部分 Store&#xff08;存储&#xff09; 应用的唯一状态容器&#xff0c;存储整个应用的状态树,使用 createStore() 创建。 getState()&#xff1a;获取当前状态。dispatch(action)&#xff…

解决MAC装win系统投屏失败问题(AMD显卡)

一、问题描述 电脑接上HDMI线后&#xff0c;电脑上能显示有外部显示器接入&#xff0c;但是外接显示器无投屏画面 二、已测试的方法 1 更改电脑分辨&#xff0c;结果无效 2 删除BootCamp&#xff0c;结果无效 3更新电脑系统&#xff0c;结果无效 4 在设备管理器中&#…

PWM调节DCDC参数计算原理

1、动态电压频率调整DVFS SOC芯片的核电压、GPU电压、NPU电压、GPU电压等&#xff0c;都会根据性能和实际应用场景来进行电压和频率的调整。 即动态电压频率调整DVFS&#xff08;Dynamic Voltage and Frequency scaling&#xff09;&#xff0c;优化性能和功耗。 比如某SOC在…

lc54螺旋矩阵——模拟

54. 螺旋矩阵 - 力扣&#xff08;LeetCode&#xff09; 就兜圈&#xff0c;先外层&#xff0c;再内层&#xff0c;每一圈&#xff0c;先上->右->下->左&#xff0c;要计算多少圈&#xff0c;观察规律就是行和列中更小的那个的二分之一&#xff0c;注意额外讨论下最后…

【C++】OOP(二):定义基类和派生类

15.2 定义基类和派生类 15.2.1 定义基类 我们首先完成 Quote 类的定义&#xff1a; #include <string>class Quote {public:Quote() default; // 默认构造函数Quote(const std::string &book, double sales_price):bookNo(book), price(sales_price) { }std::st…

面向对象设计规则和各类设计模式

面向对象设计&#xff08;Object-Oriented Design, OOD&#xff09;是一种软件设计方法论&#xff0c;它使用对象、类、继承、封装、多态等概念来组织代码。面向对象设计的核心目标是提高软件的可维护性、可扩展性和复用性。在面向对象设计中&#xff0c;遵循一定的设计原则和模…

做T和做T+0有什么区别

做T和做T0在股市中实际上有紧密的联系&#xff0c;但也有所区别。以下是对两者的详细比较&#xff1a; 一、定义与原理 做T&#xff1a; 广义上&#xff0c;做T指的是一种通过低买高卖或高卖低买来赚取差价的交易策略。这种策略可以应用于不同的交易周期&#xff0c;包括日内交…

leetcode 面试经典 150 题:移除元素

链接移除元素题序号27类型数组解题方法双指针难度简单 题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要…

软件安装不成功,一直出现“chrome_elf.dll丢失”问题是什么原因?“chrome_elf.dll丢失”要怎么解决和预防?

软件安装遇阻&#xff1a;“chrome_elf.dll丢失”问题全解析与解决方案 在软件安装与运行的过程中&#xff0c;我们时常会遇到各式各样的错误提示&#xff0c;其中“chrome_elf.dll丢失”便是较为常见的一种。这个错误不仅阻碍了软件的正常安装&#xff0c;也给用户带来了不小…