【MyBatis-Plus】MyBatis进阶使用

目录

一、MyBatis-Plus简介

1.1 介绍

1.2 优点

1.3 结构

二、MyBatis-Plus基本使用

2.1 配置

2.2 代码生成

2.3 CRUD接口测试

三、MyBatis-Plus策略详解

3.1 主键生成策略

3.2 雪花ID生成器

3.3 字段自动填充策略

3.4 逻辑删除

四、MyBatis-Plus插件使用

4.1 乐观锁插件

4.1.1 什么是乐观锁和悲观锁?

4.1.2 乐观锁实现

4.2 分页插件 


一、MyBatis-Plus简介

1.1 介绍

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变(也就是说mybatis有的plus都有),为简化开发、提高效率而生。

1.2 优点

  • 代码生成器: MyBatis-Plus 提供了一个代码生成器,可以根据数据库表自动生成实体类、mapper 接口和 XML 映射文件,大大提高了开发效率。
  • CRUD 操作简化: MyBatis-Plus 提供了一系列 CRUD 操作的方法,例如 save()saveOrUpdate()updateById() 和 deleteById(),这些方法可以简化常见的数据库操作。
  • 分页查询: MyBatis-Plus 提供了分页查询的支持,您可以使用 PageHelper 插件或者内置的分页功能来实现分页查询。
  • 性能优化: MyBatis-Plus 提供了二级缓存和批量操作的支持,可以提高数据库操作的性能。
  • 代码简洁: MyBatis-Plus 提供了许多有用的注解,可以简化 MyBatis 的代码,例如 @TableId@TableField 和 @TableLogic
  • 可扩展性: MyBatis-Plus 提供了许多扩展点,您可以通过自定义插件或拦截器来扩展 MyBatis-Plus 的功能。

如果您正在使用 MyBatis,我强烈建议您使用 MyBatis-Plus !!! 

1.3 结构

  1. 核心模块(Core Module):核心模块包含了Mybatis-Plus的核心功能和基本组件。它提供了通用的Mapper接口、通用的CRUD方法的实现、条件构造器、分页插件等核心功能的实现。核心模块是整个框架的基础,其他模块都依赖于它。

  2. 代码生成器(Code Generator):代码生成器是一个可选的辅助工具,用于根据数据库表结构自动生成实体类、Mapper接口、XML映射文件等基础代码。通过代码生成器,开发者可以快速生成基础代码,减少手写重复代码的工作量。

  3. 扩展模块(Extension Module):扩展模块是Mybatis-Plus提供的一些扩展功能和增强组件的集合。它包括了一些常用的增强功能,如逻辑删除、字段自动填充、乐观锁等。开发者可以通过引入扩展模块,轻松地增加这些功能的支持。

  4. 注解(annotation):用于对实体类、Mapper接口以及SQL语句进行配置和标记。通过使用注解,可以简化配置文件的编写,提高代码的可读性和可维护性。  

简介 | MyBatis-PlusMyBatis-Plus 官方文档icon-default.png?t=N7T8https://baomidou.com/pages/24112f/#%E7%89%B9%E6%80%A7

二、MyBatis-Plus基本使用

2.1 配置

1、导入pom依赖

        <!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!--自动生成模版引擎--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!--代码生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency>

2、配置数据库与mybatis-plus

server:port: 8080
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql://localhost:3306/bookshopmybatis-plus:# Mybatis Mapper所对应的XML位置mapper-locations: classpath:mapper/*.xml# 别名包扫描路径type-aliases-package: com.ycxw.mybatis_test.model# 是否开启自动驼峰命名规则(camel case)映射configuration:map-underscore-to-camel-case: true
logging:level:com.ycxw.mybatis_test.mapper: debug

2.2 代码生成

1、添加代码生成器

package com.ycxw.mybatis_test.config;import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;import java.util.Arrays;
import java.util.Collections;
import java.util.List;@Slf4j
public class MySQLGenerator {private final static String URL = "jdbc:mysql://localhost:3306/bookshop";private final static String USERNAME = "root";private final static String PASSWORD = "123456";private final static DataSourceConfig.Builder DATA_SOURCE_CONFIG =new DataSourceConfig.Builder(URL, USERNAME, PASSWORD);public static void main(String[] args) {FastAutoGenerator.create(DATA_SOURCE_CONFIG).globalConfig((scanner, builder) ->builder.author("云村小威").outputDir(System.getProperty("user.dir") + "\\src\\main\\java").commentDate("yyyy-MM-dd").dateType(DateType.TIME_PACK).disableOpenDir()).packageConfig((builder) ->builder.parent("com.ycxw.mybatis_test").entity("entity").service("service").serviceImpl("service.impl").mapper("mapper").xml("mapper.xml").pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "\\src\\main\\resources\\mapper"))).injectionConfig((builder) ->builder.beforeOutputFile((a, b) -> log.warn("tableInfo: " + a.getEntityName()))).strategyConfig((scanner, builder) ->builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all"))).addTablePrefix("tb_", "t_", "lay_", "meeting_", "sys_").entityBuilder().enableChainModel().enableLombok().enableTableFieldAnnotation().controllerBuilder().enableRestStyle().enableHyphenStyle().build()).templateEngine(new FreemarkerTemplateEngine()).execute();}protected static List<String> getTables(String tables) {return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));}}

这段 Java 代码是用于自动生成 MyBatis-Plus 代码的。它使用 FastAutoGenerator 来生成实体类、服务类、服务实现类、映射器接口和映射器 XML 文件。

代码主要做了以下事情:

  1. 定义数据源配置,指定数据库 URL、用户名和密码。
  2. 创建 FastAutoGenerator 实例,并指定数据源配置。
  3. 配置全局配置,包括作者、输出目录、注释日期和日期类型等。
  4. 配置包配置,包括父包名、实体包名、服务包名、服务实现包名、映射器包名和 XML 包名等。
  5. 配置注入配置,在输出文件之前记录表信息。
  6. 配置策略配置,包括要生成的表名、要移除的前缀、实体类配置、控制器类配置等。
  7. 指定模板引擎为 Freemarker。
  8. 执行代码生成。

当运行此代码时,它将生成 MyBatis-Plus 代码,并将其输出到指定目录。

3、运行该类输入需要生成的数据表名

tips:

        在这里可以发现除了entity实体包下的Book类其他的类和接口都是空了,其实它自带了增删改查等方法的,可以直接调用,如果需要更复杂的数据接口可以自行编写。

最后注意添加mapper注释交给spring管理,并在启动器添加扫描mapper的注释:

2.3 CRUD接口测试

package com.ycxw.mybatis_test.controller;import com.github.yitter.idgen.YitIdHelper;
import com.ycxw.mybatis_test.entity.Book;
import com.ycxw.mybatis_test.service.IBookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** <p>* 书本信息表 前端控制器* </p>** @author 云村小威* @since 2023-12-16*/
@RestController
@RequestMapping("/book")
public class BookController {@Autowiredprivate IBookService bookService;@GetMapping("/list")public Object list() {return bookService.list();}@PostMapping("/save")public Object add(Book book) {/*设置雪花id*/book.setId(YitIdHelper.nextId());return bookService.save(book);}@PatchMapping("/update")public Object edit(Book book) {return bookService.updateById(book);}@DeleteMapping("/{id}")public Object del(@PathVariable Long id) {return bookService.removeById(id);}}

查询测试: 

等等。。。 

三、MyBatis-Plus策略详解

3.1 主键生成策略

@Getter
@Setter
@Accessors(chain = true)
@TableName("t_book")
public class Book implements Serializable {private static final long serialVersionUID = 1L;/*** 书本编号*/@TableId(value = "id", type = IdType.AUTO)private Long id;
  • @TableId注解属性

属性类型必须指定默认值描述
valueString""主键字段名
typeEnumIdType.NONE指定主键类型

IdType属性:

描述
AUTO数据库 ID 自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert 前自行 set 主键值
ASSIGN_ID分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)
ID_WORKER分布式全局唯一 ID 长整型类型(please use ASSIGN_ID)
UUID32 位 UUID 字符串(please use ASSIGN_UUID)
ID_WORKER_STR分布式全局唯一 ID 字符串类型(please use ASSIGN_ID)

3.2 雪花ID生成器

提示

自 3.3.0 开始,默认使用雪花算法+UUID(不含中划线)

自定义示例工程:

  • spring-boot 示例 :传送门
方法主键生成策略主键类型说明
nextIdASSIGN_ID,ID_WORKERID_WORKER_STRLong,Integer,String支持自动转换为 String 类型,但数值类型不支持自动转换,需精准匹配,例如返回 Long,实体主键就不支持定义为 Integer
nextUUIDASSIGN_UUID,UUIDString默认不含中划线的 UUID 生成

示例:

为什么要用ID生成器?

UUID 的主要优点是:

  • 它能够生成真正随机的标识符,不需要依赖于数据库或其他外部服务。
  • 它可以跨不同的系统和平台使用,而不需要进行任何修改。

Snowflake ID 的主要优点是:

  • 它能够生成递增的唯一标识符。
  • 它可以分布式生成,因此可以扩展到大型系统。

        首先UUID它是随机生成的,生成的id可能跨度较大。在性能方面,Snowflake ID 优于 UUID。Snowflake ID 的生成速度更快,存储空间更小,并且具备递增性。但是,Snowflake ID 需要依赖于数据库或其他外部服务来存储和管理元数据,并且需要进行额外的配置和维护。

在实际应用中,可以选择使用 UUID 或 Snowflake ID,具体取决于具体的需求和场景。

3.3 字段自动填充策略

  • @TableField 字段注解
    /*** 书本名称*/@TableField(value = "bookname",fill = FieldFill.INSERT)private String bookname;
属性类型必须指定默认值描述
valueString""数据库字段名
existbooleantrue是否为数据库表字段
fillEnumFieldFill.DEFAULT字段自动填充策略

Fill 属性值

描述
DEFAULT默认不处理
INSERT插入时填充字段
UPDATE更新时填充字段
INSERT_UPDATE插入和更新时填充字段

在这里我们可以设置该字段是否自动填充以及什么时候填充,一般在时间字段设置自动填充方便查询数据的插入和更新时间,当然下面只是一个简单的案例:

我们还需要编写 自定义实现类 MyMetaObjectHandler

package com.ycxw.mybatis_test.config;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("插入时自动填充 ....");this.strictInsertFill(metaObject, "bookname", String.class, "暂无"); // 起始版本 3.3.0(推荐使用)}@Overridepublic void updateFill(MetaObject metaObject) {log.info("修改时自动填充 ....");this.strictUpdateFill(metaObject, "updateTime", String.class, "未填写修改名称"); // 起始版本 3.3.0(推荐)}
}

定义了自动填充,我们在新增或修改时就可以不为该字段赋值。

3.4 逻辑删除

为什么要使用逻辑删除?

  1. 保留历史记录:通过逻辑删除,可以保留项目的完整历史记录,而无需物理删除数据。这对于调试、审计和数据分析非常有用。
  2. 恢复数据:如果项目数据被意外删除,通过逻辑删除可以轻松恢复。而物理删除的数据则无法恢复。
  3. 性能优化:逻辑删除可以提高项目的性能,因为不需要物理删除数据。这对于大型项目或具有大量数据的项目尤为重要。
  4. 安全性:逻辑删除可以提高项目的安全性,因为不需要物理删除数据,可以防止不必要的数据泄露。
  5. 合规性:一些行业或法规可能要求保留数据一段特定时间。逻辑删除可以帮助项目遵守这些规定,而无需永久存储数据。

        通过mybatis-plus扩展的逻辑删除功能,再调用删除接口时将删除自动转为修改。将数据状态修改为不可查询到(前提是该表含有特定的状态列)

使用方法:

1、全局配置

2、局部配置

这里不可以配置@TableLogic注解,但必须指定@TableField并设置对应数据库中的字段名。

 

3、测试

例如删除第一条数据:

再次查看该数据表:

调用查询测试:

可以发现刚才删除的数据将不能查到,而数据库仍存在。

四、MyBatis-Plus插件使用

4.1 乐观锁插件

4.1.1 什么是乐观锁和悲观锁?

        乐观锁悲观锁是两种不同的并发控制机制,用于防止多用户同时修改同一份数据时产生数据不一致的问题。

  • 乐观锁假设在并发操作时,数据不会被其他用户修改,因此在执行更新操作前不需要对数据加锁。在提交更新时,会检查数据是否已经被修改。如果数据已经被修改,则会抛出异常,要求用户重新获取数据并重新提交更新。
  • 悲观锁假设在并发操作时,数据可能会被其他用户修改,因此在执行更新操作前需要先对数据加锁。在更新操作执行完成后,锁才会被释放。这样可以确保在数据更新时,不会被其他用户修改。

乐观锁的优点:

  • 性能好,因为在大多数情况下不需要加锁。
  • 可伸缩性好,因为不需要维护锁状态。
  • 不会出现死锁。

乐观锁的缺点:

  • 可能出现数据不一致的问题,因为在提交更新时,数据可能已经被其他用户修改。
  • 需要应用程序代码来处理并发冲突。

悲观锁的优点:

  • 可以保证数据一致性,因为在更新数据时,其他用户不能修改数据。
  • 不需要应用程序代码来处理并发冲突。

悲观锁的缺点:

  • 性能差,因为在更新数据时需要加锁。
  • 可伸缩性差,因为需要维护锁状态。
  • 可能出现死锁。

4.1.2 乐观锁实现

当要更新一条记录的时候,希望这条记录没有被别人更新。
乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果 version 不对,就更新失败

 

所以先给需要加锁的表添加version列,同时在实体类中加上@Version注解

@Version
private Integer version;

1、配置插件

package com.ycxw.mybatis_test.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;// Spring Boot 方式
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}
}

2、编写修改接口测试

    @PutMapping("/edit")public Object update(){Book b1 = bookService.getById("16");b1.setPrice(133F);bookService.updateById(b1);return "1";}

调用查询接口可以看到:首先查询该数据,在修改version值并判断该数据的version值是否等于当前的version值。 

        可以看到version值已变成2了,没修改一次就会加1。这就意味着当我修改改数据时version变为了2,而其他人同时修改该数据时首先查询到的是1,而我已经修改为2,他人再修改时条件已不再成立将无法修改。

以下案例进行验证:

    @PutMapping("/edit")public Object update(){/*模仿两人同时修改不同数据时*/Book b1 = bookService.getById("16");b1.setPrice(133F);Book b2 = bookService.getById("16");b2.setPrice(210F);bookService.updateById(b1);bookService.updateById(b2);return "1";}

        可以看到只有第一条修改成功了,且version变为3(首先查询的值为2,修改后自动变为3)。如果他人同时于此修改时,而version判断不成立则无法修改。 

4.2 分页插件 

1、首先添加分页插件配置,与乐观锁配置位置一样,该类可以同时配置多个插件。

package com.ycxw.mybatis_test.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;// Spring Boot 方式
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();/*配置乐观锁*/mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());/*配置分页*///interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbTypemybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加return mybatisPlusInterceptor;}
}

 2、编写查询接口测试

    @GetMapping("/list")public Object list() {//简单的分页查询Page<Book> page = new Page<>(1,5);Page<Book> res = bookService.page(page, wrapper);res.getTotal();//数据总数res.getPages();//数据总页数return res.getRecords();}

 

以上只是一个简单的查询案例,mp通过page类实现了简单分页模型。需要进行条件查询则要了解查询构造器:

        QueryWrapper是Mybatis-Plus提供的一个条件构造器,用于快速构建SQL查询语句的条件部分。

        QueryWrapper的语法类似于Mybatis的XML文件中的where标签,其最终会被转换为SQL语句的条件部分。我们可以通过链式调用的方式,不断添加查询条件,从而构建出复杂的查询条件。

代码示例:

    @GetMapping("/list")public Object list(@RequestParam(value = "bookname", required = false, defaultValue = "")  String bookname) {//查询条件QueryWrapper<Book> wrapper = new QueryWrapper<>();/*** 设置查询条件 bookname like %name%* 如:*    warpper.eq("price",100,300) == price 在 100 ~ 300 之间*    ...*/wrapper.like("bookname",bookname);//分页条件条件Page<Book> page = new Page<>(1,5);Page<Book> res = bookService.page(page, wrapper);res.getTotal();//数据总数res.getPages();//数据总页数return res.getRecords();}

 可以看到通过like方法指定注入需要查询的列名,自定拼接到sql中

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

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

相关文章

从零开始:VuePress2 + GitHub Pages 搭建你的第一个免费博客网站

可能你也想拥有一个属于自己的博客网站&#xff0c;但是自己搭个博客网站不知道从何下手&#xff0c;而且还需要租个云服务器&#xff0c;虽然一个月只需几十块钱&#xff0c;但是我们的博客网站是要长期维护的&#xff0c;日积月累也要不少钱呢。 现在我就教你用 VuePress2 …

JVM-1-运行时数据区

程序计数器&#xff08;Program Counter Register&#xff09; 是一块较小的内存空间&#xff0c;它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里[1]&#xff0c;字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令&…

【ICCV 2022】Masked Autoencoders Are Scalable Vision Learners

何凯明一作文章&#xff1a;https://arxiv.org/abs/2111.06377 本文的出发点&#xff1a;是BERT的掩码自编码机制&#xff1a;移除一部分数据并对移除的内容进行学习。mask自编码源于CV但盛于NLP&#xff0c;恺明对此提出了疑问&#xff1a;是什么导致了掩码自编码在视觉与语言…

Apache OfBiz 反序列化命令执行漏洞(CVE-2023-49070)

项目介绍 Apache OFBiz是一个非常著名的电子商务平台&#xff0c;是一个非常著名的开源项目&#xff0c;提供了创建基于最新J2EE/XML规范和技术标准&#xff0c;构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类WEB应用系统的框架。OFBiz最主要的特…

自定义注解

自定义注解 自定义注解 以实战案例为驱动,快速掌握此怎么自己自定义注解,也好出去自己吹牛逼~哈哈哈 假设我们打车,需要检验验证码,我们需要一个注解字来进行核验,我们怎么操作呢? 大纲总览 ​​ 1.定义注解 可以自己创一个包单门存放自己的注解: 如​constraints​ 包 然后…

Linux高级系统编程-MySQL数据库基本使用语法

DDL:数据定义语言 作用 : 用于完成对数据库对象&#xff08;数据库、数据表、视图、索引等&#xff09;的创建、删除、修改 数据库操作 查询数据库 - > 显示当前 mysql 中的数据库列表 > show databases; - > 显示指定名称的数据的创建的 SQL 指令 > show c…

车规MCU应用场景及国产替代进展

目录 1.车规MCU应用场景 1.1 车身域 1.2 动力底盘域 1.3 座舱域和智驾域 1.4 网联域 2.国产替代进展 3.小结 前面一篇文章征途漫漫:汽车MCU的国产替代往事-CSDN博客对车规MCU国产替代的背景与一些往事进行了简单叙述&#xff0c;今天来聊聊车规MCU具体会在汽车哪些地方用…

sql宽字节注入

magic_quotes_gpc&#xff08;魔术引号开关&#xff09; https://www.cnblogs.com/timelesszhuang/p/3726736.html magic_quotes_gpc函数在php中的作用是判断解析用户提交的数据&#xff0c;如包括有&#xff1a;post、get、cookie过来的数据增加转义字符“\”&#xff0c;以…

PDF如何转换制作成翻页电子书

很多朋友想将PDF转换制作成一本翻页电子书&#xff0c;却不知道如何操作。其实&#xff0c;转换翻页电子书的过程并不难&#xff0c;只需要掌握一些基本的技巧和方法就可以了。 基本该怎么操作呢&#xff1f; 1.首先需要一个工具帮助我们成功转换&#xff0c;推荐使用FLBOOK这…

【LeetCode刷题笔记】155.最小栈

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多算法知识专栏&#xff1a;算法分析&#x1f525; 给大家跳段街舞感谢…

滑动窗口最大值(LeetCode 239)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路方法一&#xff1a;暴力法方法二&#xff1a;优先队列方法三&#xff1a;单调队列 参考文献 1.问题描述 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动…

【LeetCode刷题-树】--173.二叉搜索树迭代器

173.二叉搜索树迭代器 本题就是实现二叉树的中序遍历&#xff0c;利用数组本身实现迭代器 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.va…

如何在Docker部署draw.io流程图软件并实现公网远程访问

前言 提到流程图&#xff0c;大家第一时间可能会想到Visio&#xff0c;不可否认&#xff0c;VIsio确实是功能强大&#xff0c;但是软件为收费&#xff0c;并且因为其功能强大&#xff0c;导致安装需要很多的系统内存&#xff0c;并且是不可跨平台使用。所以&#xff0c;今天给…

牛客小白月赛83 解题报告

题目链接&#xff1a; https://ac.nowcoder.com/acm/contest/72041#question A题 解题思路 签到 代码 #include <bits/stdc.h> using namespace std;int main() {int a, b, c, d, e;cin >> a >> b >> c >> d >> e;int A, B, C, D…

【人工智能】实验二: 洗衣机模糊推理系统实验与基础知识

实验二: 洗衣机模糊推理系统实验 实验目的 理解模糊逻辑推理的原理及特点&#xff0c;熟练应用模糊推理。 实验内容 设计洗衣机洗涤时间的模糊控制。 实验要求 已知人的操作经验为&#xff1a; “污泥越多&#xff0c;油脂越多&#xff0c;洗涤时间越长”&#xff1b;“…

DDD挤水分和强行加异性为好友-UMLChina建模知识竞赛第4赛季第25轮

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题&#xff0c;即可获得本轮优胜。第4题为附加题&#xff0c;对错不影响优胜者…

开源免费图床Lychee本地部署搭建个人云图床并公网访问【内网穿透】

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站&#xff0c;可以看做是云存储的一部分&#xff0c;既可…

作者推荐 |【深入了解系统性能优化】「实战技术专题」全方面带你透彻探索服务优化技术方案(方案分析篇)

全方面带你透彻探索服务优化技术方案 前提背景影响一个系统性能的方方面面代码优化数据库优化网络优化硬件优化 常用的性能评价/测试指标响应时间并发数吞吐量响应时间、并发数和吞吐量之间的关系运作流程关系 性能优化方案的建议避免过早优化进行系统性能测试寻找系统瓶颈&…

R 语言相关资源分享

简介 分享一个 Github 仓库&#xff0c;包含了大量 R 语言教程和资源&#xff0c;旨在帮助各种技能水平和背景的用户深化对 R 的理解。 下面给出一些截图&#xff0c;感兴趣的读者可以自行探索&#xff5e;

JVM-2-对象

对象创建 当Java虚拟机遇到一条字节码new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应的类加载过程。 为对象分配空间…