学习笔记--MybatisPlus

server/2024/9/29 15:42:05/

官网:MyBatis-Plus 🚀 为简化开发而生

快速入门

入门案例

  1. 引入MybatisPlus的起步依赖

  1. 定义Mapper

问题:

MybatisPlus中Invalid bound statement (not found): com.itheima.mp.mapper.UserMapper.insert

一定要指定实体类!!!

常见注解

一定要指定出来,不然时默认雪花算法,很长

小结:

常见配置

一般不用自己配置,全都有默认配置

小结

核心用法

条件构造器

wrapper

案例

  1. 查询出名字中带o的,存款大于等于1000元的人的idusername、info、balance字段

  1. 更新用户名为jack的用户的余额为2000、

  1. 需求:更新id为1,2,4的用户的余额,扣200

  1. lambdaQueryWrapper编写

小结

自定义SQL

我们可以利用MyBatisPlus的wrapper来构建复杂的where条件,然后自己定义SQL语句中剩下的部分。

步骤:

  1. 先在test中书写

  1. 在usermapper层中书写自定义的sql方法

  1. 然后去所对应的usermapper.xml文件中去书写剩下的sql语句和连接where条件

Service接口

基本用法

使用

测试类:

接口类:

实现类:

小结

基于Restful风格实现接口

swagger依赖和web依赖

swagger依赖需要配置

开始创建DTO和VO对象(导课程资料)

新增用户

创建接口

问题

关于为什么不建议使用@Autowired进行属性注入,这里有一些可能的原因:

  1. 隐式依赖:使用@Autowired进行属性注入可能会隐藏类的依赖关系。在类的代码中,你无法直接看到哪些依赖项是通过@Autowired注入的,这可能会使代码更难理解和维护。
  2. 测试困难:当使用@Autowired进行属性注入时,类的依赖项是在运行时通过Spring容器自动注入的。这可能会使单元测试更加困难,因为你需要模拟或替换这些依赖项。相比之下,使用构造器注入可以使依赖项在类的构造函数中明确列出,从而更容易进行单元测试。
  3. 无法注入不可变对象:由于@Autowired通常用于属性注入,因此它无法用于注入不可变对象(即其值在创建后不能更改的对象)。在这种情况下,你需要使用其他注入方式(如构造器注入或setter注入)。
  4. 潜在的循环依赖:在使用@Autowired进行属性注入时,可能会出现循环依赖的问题。例如,如果类A依赖于类B,而类B又依赖于类A,那么Spring容器可能无法正确解析这些依赖关系。虽然Spring容器可以处理某些类型的循环依赖,但最好还是尽量避免这种情况。
  5. 不是所有类都适合使用Spring管理:虽然Spring是一个强大的框架,但它并不适合管理所有类型的类。有些类可能更适合使用传统的Java类来管理,而不是作为Spring Bean。在这些情况下,使用@Autowired进行属性注入可能会使代码变得复杂且难以维护。

改写为构造器注入

开始编写业务

删除用户

根据id查询用户

根据id批量查询用户

根据id扣减用户金额

controller层

service层

mapper层

测试:localhost:8080/doc.html(基于swagger测试)

IService的Lambda方法

案例来学习

查询

根据复杂条件来查询用户

controller层

service层

更新

批量新增

修改后:

结果还是比较耗时

改进方法:

在配置文件里面,mysql后面添加这样一句语句即可

扩展功能

代码生成

传统

  1. 安装插件

  1. idea中配置数据库连接

  1. 配置

静态工具Db

出现循环调用的时候可以使用db来进行操作

需要传递实体类类型

一、改造根据id查询用户的接口,查询用户的同时,查询出用户对应的所有地址

  1. 使用静态方式改写,controller层

  1. service层

是:isNotEmpty

二、改造根据id批量查询用户的接口,查询用户的同时,查询出用户对应的所有地址

  1. 静态该写controller层代码

  1. service层

逻辑删除

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

  • 在表中添加一个字段标记数据是否被删除
  • 当删除数据时把标记置为true
  • 查询时过滤掉标记为true的数据

一旦采用了逻辑删除,所有的查询和删除逻辑都要跟着变化,非常麻烦。

so:

MybatisPlus就添加了对逻辑删除的支持。

注意,只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除。

步骤

  1. 我们给address表添加一个逻辑删除字段
alter table address add deleted bit default b'0' null comment '逻辑删除';
  1. 给Address实体添加deleted字段

  1. 在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)
  1. 测试
@Test
void testDeleteByLogic() {// 删除方法与以前没有区别addressService.removeById(59L);
}

方法与普通删除一模一样,但是底层的SQL逻辑变了:

开启了逻辑删除功能以后,我们就可以像普通删除一样做CRUD,基本不用考虑代码逻辑问题。还是非常方便的。

注意: 逻辑删除本身也有自己的问题,比如:

  • 会导致数据库表垃圾数据越来越多,从而影响查询效率
  • SQL中全都需要对逻辑删除字段做判断,影响查询效率

因此,我不太推荐采用逻辑删除功能,如果数据不能删除,可以采用把数据迁移到其它表的办法。

通用枚举

问题产生:

有一个用户状态属性

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

MybatisPlus提供了一个处理枚举的类型转换器,可以帮我们把枚举类型与数据库类型自动转换

实现

  1. 在需要进行转换的枚举对象上加上@EnumValue注解

  1. 配置枚举处理器

application.yaml文件中添加配置

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

  1. 用枚举对象来代替原有的字段

  1. 修改业务中的代码

  1. po修改后,也得对vo类进行修改

  1. 查询结果的问题

解决这个问题,需要返回回显的数据为1或者2,则需要在枚举类变量上面添加注解

小结

插件功能

分页插件

  1. 配置插件

  1. 进行测试

通用的分页查询

案例

  1. 建议将分页查询条件单独定义为一个PageQuery实体:

PageQuery是前端提交的查询参数,一般包含四个属性:

  • pageNo:页码
  • pageSize:每页数据条数
  • sortBy:排序字段
  • isAsc:是否升序

  1. UserQuery继承这个实体:
package com.itheima.mp.domain.query;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery extends PageQuery {@ApiModelProperty("用户名关键字")private String name;@ApiModelProperty("用户状态:1-正常,2-冻结")private Integer status;@ApiModelProperty("余额最小值")private Integer minBalance;@ApiModelProperty("余额最大值")private Integer maxBalance;
}
  1. 分页实体PageDTO
package com.itheima.mp.domain.dto;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;@Data
@ApiModel(description = "分页结果")
public class PageDTO<T> {@ApiModelProperty("总条数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("集合")private List<T> list;
}
  1. 开发接口

controller层

  1. 改造PageQuery实体
package com.itheima.mp.domain.query;import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;@Data
public class PageQuery {private Integer pageNo;private Integer pageSize;private String sortBy;private Boolean isAsc;public <T>  Page<T> toMpPage(OrderItem ... orders){// 1.分页条件Page<T> p = Page.of(pageNo, pageSize);// 2.排序条件// 2.1.先看前端有没有传排序字段if (sortBy != null) {p.addOrder(new OrderItem(sortBy, isAsc));return p;}// 2.2.再看有没有手动指定排序字段if(orders != null){p.addOrder(orders);}return p;}public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc){return this.toMpPage(new OrderItem(defaultSortBy, isAsc));}public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {return toMpPage("create_time", false);}public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {return toMpPage("update_time", false);}
}
  1. 改造PageDTO实体
package com.itheima.mp.domain.dto;import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageDTO<V> {private Long total;private Long pages;private List<V> list;/*** 返回空分页结果* @param p MybatisPlus的分页结果* @param <V> 目标VO类型* @param <P> 原始PO类型* @return VO的分页对象*/public static <V, P> PageDTO<V> empty(Page<P> p){return new PageDTO<>(p.getTotal(), p.getPages(), Collections.emptyList());}/*** 将MybatisPlus分页结果转为 VO分页结果* @param p MybatisPlus的分页结果* @param voClass 目标VO类型的字节码* @param <V> 目标VO类型* @param <P> 原始PO类型* @return VO的分页对象*/public static <V, P> PageDTO<V> of(Page<P> p, Class<V> voClass) {// 1.非空校验List<P> records = p.getRecords();if (records == null || records.size() <= 0) {// 无数据,返回空结果return empty(p);}// 2.数据转换List<V> vos = BeanUtil.copyToList(records, voClass);// 3.封装返回return new PageDTO<>(p.getTotal(), p.getPages(), vos);}/*** 将MybatisPlus分页结果转为 VO分页结果,允许用户自定义PO到VO的转换方式* @param p MybatisPlus的分页结果* @param convertor PO到VO的转换函数* @param <V> 目标VO类型* @param <P> 原始PO类型* @return VO的分页对象*/public static <V, P> PageDTO<V> of(Page<P> p, Function<P, V> convertor) {// 1.非空校验List<P> records = p.getRecords();if (records == null || records.size() <= 0) {// 无数据,返回空结果return empty(p);}// 2.数据转换List<V> vos = records.stream().map(convertor).collect(Collectors.toList());// 3.封装返回return new PageDTO<>(p.getTotal(), p.getPages(), vos);}
}
  1. service层

原始版

简化版


http://www.ppmy.cn/server/111268.html

相关文章

ASPICE认证准备:步骤详解与策略指南

ASPICE认证准备&#xff1a;(要明确的是&#xff1a;在ASPICE行业中专业来说&#xff0c;ASPICE项目是没有认证&#xff0c;而只有评估。不过&#xff0c;为了方便沟通&#xff0c;人们常将这一评估过程称为认证。) 1. 确定认证目标和范围 明确要认证的软件开发过程以及涉及的…

用亚马逊AI代码开发助手Amazon Q Developer开发应用(上篇)

快用人工智能帮程序员写代码&#xff01;今天小李哥就来介绍亚马逊推出的国际前沿人工智能AI代码开发助手Amazon Q Developer。目前该代码助手在Hugging Face代码生成权威测试集SWE-bench中排名第一&#xff0c;可以根据我们的需求生成整个代码项目&#xff0c;并可以帮助我们解…

11、Django Admin启用对计算字段的过滤

重新定义admin.py中的Hero管理模型如下&#xff1a; admin.register(Hero) class HeroAdmin(admin.ModelAdmin):list_display ("name", "is_immortal", "category", "origin", "is_very_benevolent")list_filter ("…

Hive SQL 练习

1、统计每天首次登录的人数 -- 统计每天首次登录的人数 -- 步骤&#xff1a;先找出第一次登录的时间&#xff0c;再按首次登录时间分组求人数-- 方法1&#xff1a; select first_login_time, count(user_id) as cnt from (select user_id, date_formate(min(login_ts), yyyy-…

macos 自定义用户目录方法, /Users/xxx 用户文件存储路径自定义方法

在macos中,我们的用户数据全部都存储在了 /Users/xxx 文件夹下, 而这个文件夹默认是和我们的macos系统文件存放在了同一个磁盘卷宗(分区)里面的, 这个就给我们在遭遇系统崩溃或者其他情况重装系统时带来了极大的不便, 如果是格式化后全新安装 数据全部丢失,如果是覆盖安装同…

oceanbase OBCE 第四章实验 事务与远程执行

实验环境&#xff1a;企业版V3 1-1-1 前期准备&#xff1a; 新建一个 oracle 租户 1C2GB 新建资源规格&#xff1a; create resource unit u1_ora max_cpu1,min_cpu1,max_memory2G,min_memory2G,max_iops128,max_disk_size10G,max_session_num100; 新建资源池&#xff1a; c…

51单片机-第十节-独立按键及数码管优化

一、优化独立按键&#xff1a; 独立按键的实现中&#xff0c;为了解决抖动问题&#xff08;在按下和抬起时&#xff0c;按键会在高低电平之间抖动10ms&#xff09;&#xff0c;我们在按下后Delay(20)&#xff0c;随后进入循环&#xff0c;直到检测到按键抬起&#xff0c;再Del…

2024年最值得购买的百元蓝牙耳机有哪些?四款热门畅销机型推荐

2024年&#xff0c;面对琳琅满目的蓝牙耳机选择&#xff0c;消费者可能会感到困惑&#xff0c;特别是当预算限制在百元左右时&#xff0c;2024年最值得购买的百元蓝牙耳机有哪些&#xff1f;当然在这个价格区间内&#xff0c;市场上也不乏性能卓越、性价比高的产品&#xff0c;…