当前位置: 首页 > article >正文

MyBatisPlus--快速入门

MyBatisPlus介绍

从名字中就可以感觉到MybatisPlus与MyBatis之间的渊源,而MyBatis是一个非常流行的持久层框架,主要来做数据库的增删改查,而MyBatisPlus这种命名方式让人不得不往MyBatis的升级版去联想,事实也确实如此,MyBatisPlus就是对MyBatis框架的增强与升级,但MyBatisPlus并不是来替代MyBatis的,MyBatisPlus的官网logo是一只蓝色的小鸟,MyBatis官网的logo是一只红色的小鸟,并且在MyBatisPlus官网下的标语就是 MyBatis 最佳搭档,只做增强不做改变,为简化开发、提高效率而生。因此两者是一种合作的关系。

而且两者搭配使用,可以翻倍提高开发效率。因此MybatisPlus也成为了企业开发的必备工具。

那么MyBatisPlus是如何对MyBatis进行增强的呢?

我们可以从MyBatisPlus的官网文档入手

image-20250530165410823

在实际开发中,书写的大多数SQL语句都是单表得CRUD,花费时间最多的就是单表CRUD的代码编写上,而这些功能往往都是比较重复的,比较基础的,比较浪费时间,而MyBatisPlus就帮助开发者干了一件事情:只需要简单配置,设置不用配置,约定大于配置,那么MyBatisPlus就可以帮助开发者实现单表的CRUD的操作,,开发者只需要直接调用对应的方法就能实现对应的功能,这样就节省了开发中大量去编写单表CRUD的时间,开发效率也会随之水涨船高,这就是MyBatisPlus最重要的功能。

但是MyBatisPlus不仅仅帮我们实现了单表CRUD功能,还有一些拓展功能,比如,代码生成,自动分,逻辑删除等等。

官方文档:简介 | MyBatis-Plus

官方文档主要分为四大部分:

  • 快速入门:快速了解MyBatisPlus的基本特性。

  • 核心功能:以后再开发中写的最多的代码

  • 拓展:拓展的一些高级功能

  • 插件:一些插件功能,比如分页插件,乐观锁插件等等

快速入门

快速开始

入门案例:

需求:基于项目,实现下列功能

  • 新增用户功能

  • 根据ID查询用户

  • 根据ID批量查询用户

  • 根据ID更新用户

  • 根据ID删除用户

以前的MyBatis冗余代码:

 <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="com.lyc.mybatisplusdemo.mapper.UserMapper">​<insert id="saveUser" parameterType="com.lyc.mybatisplusdemo.pojo.User">insert into `user` (`id`,`username`,`password`,`phone`,`info`,`status`,`balance`)values (#{id},#{username},#{password},#{phone},#{info},#{status},#{balance})</insert><update id="updateUser" parameterType="com.lyc.mybatisplusdemo.pojo.User">update `user`<set><if test="username != null">username = #{username},</if><if test="password != null">password = #{password},</if><if test="phone != null">phone = #{phone},</if><if test="info != null">info = #{info},</if><if test="status != null">status = #{status},</if><if test="balance != null">balance = #{balance},</if></set>where id = #{id}</update><delete id="deleteUser" parameterType="com.lyc.mybatisplusdemo.pojo.User">delete  from `user` where id = #{id}</delete><select id="getUserById" resultType="com.lyc.mybatisplusdemo.pojo.User">select * from `user` where id = #{id}</select><select id="getUserByIds" resultType="com.lyc.mybatisplusdemo.pojo.User">select * from `user`<if test="ids != null">where id in<foreach collection="ids" item="id" open="(" close=")" separator=",">#{id}</foreach></if>limit 10</select></mapper>

虽然逻辑很简单,就是一些单表的增删改查的语句,浪费了大量的时间,导致开发效率受到了影响,而如果使用MyBatisPlus,这些单表查询语句都不需要书写了,

如何使用MyBatisPlus?

步骤:

  • 引入MyBatisPlus的起步依赖

MyBatisPlus官方提供了Starter,其中集成了MyBatis和MyBatisPlus的所有功能,并且实现了自动装配的效果。

因此我们可以使用MyBatisPlus的starter代替MyBatis的starter:

 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.12</version></dependency>
  • 自定义Mapper

自定义的Mapper集成MyBatisPlus提供的BaseMapper接口:

因为BaseMapper中已经提前定义好了大量的增删改查的方法,而且命名方式简单明了。

那么我们就可以继承BaseMapper,从而调用这些方法。

 public interface UserMapper extends BaseMapper<User> {}

注意事项:在继承BaseMapper接口时,需要将泛型的类型换成实体类的类型。

测试代码:

 package com.lyc.mybatisplusdemo.mapper;​import com.lyc.mybatisplusdemo.pojo.User;import jakarta.annotation.Resource;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;​import java.time.LocalDateTime;import java.util.List;​@SpringBootTestclass UserMapperTest {@Resourceprivate UserMapper userMapper;@Testvoid testInsert(){User user = new User();user.setId(5L);user.setUsername("lyc");user.setPassword("123456");user.setPhone("12345678901");user.setBalance(200);user.setInfo("{\"age\":24,\"intro\":\"英文老师\",\"gender\":\"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.saveUser(user);}@Testvoid testSelectById(){User user = userMapper.getUserById(5L);System.out.println("user = "+user);}@Testvoid testSelectByIds(){List<User> users = userMapper.getUserByIds(List.of(1L,2L,3L,4L,5L));users.forEach(System.out::println);}@Testvoid testUpdateById(){User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateUser(user);}}

因为MyBatisPlus是对MyBatis的增强,因此即使我们将依赖替换成MyBatisPlus,开始在Mapper.xml中的文件依然可以使用。

进行测试:

image-20250530191202267

而使用MyBatisPlus无需再书写SQL语句以及声明方法了。

将这些都删除。

在修改测试单元代码,直接调用父类BaseMapper中的方法即可

 package com.lyc.mybatisplusdemo.mapper;​import com.lyc.mybatisplusdemo.pojo.User;import jakarta.annotation.Resource;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;​import java.time.LocalDateTime;import java.util.List;​@SpringBootTestclass UserMapperTest {@Resourceprivate UserMapper userMapper;@Testvoid testInsert(){User user = new User();user.setId(5L);user.setUsername("lyc");user.setPassword("123456");user.setPhone("12345678901");user.setBalance(200);user.setInfo("{\"age\":24,\"intro\":\"英文老师\",\"gender\":\"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}@Testvoid testSelectById(){User user = userMapper.selectById(5L);System.out.println("user = "+user);}@Testvoid testSelectByIds(){List<User> users = userMapper.selectBatchIds(List.of(1L,2L,3L));users.forEach(System.out::println);}@Testvoid testUpdateById(){User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}@Testvoid testDeleteById(){userMapper.deleteById(5L);}}

再次进行测试:

image-20250530192047060

测试成功。

查询数据库看是否插入数据

image-20250530192117561

测试成功。

总结:

使用MyBatisPlus的基本步骤:

  • 使用MyBatisPlus依赖,代替MyBatis依赖

  • 定义Mapper接口并继承BaseMaper

MyBatisPlus确实做到了对Mybatis的无侵入:润物无声

常见注解

MyBatisPlus是如何获取数据库信息的呢?

原因:MyBatisPlus通过扫描实体类,并给予反射获取实体类信息作为数据库表信息。

在前面的入门案例中,在继承BaseMapper类后需要指定泛型,就是对应的实体类的类型,而MyBatisPlus就可以基于反射拿到实体类类型,拿到实体类类型就可以基于反射拿到对应的class对象,即对应字节码,拿到对应字节码就可以拿到实体类信息,就基于实体类信息作为数据库表信息。

为了拿到准确的数据表信息,MyBatisPlus有一系列的约定。

  • 类名驼峰转下划线作为表名

  • 名为id的字段作为主键

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

如果实体类不符合约定,就必须自己去定义表明主键名,以及字段名。

如何自定义呢?MyBatisPlus为我们提供了注解来帮助我们自定义设置。

常用注解:

  • @TableName:用来指定表名

  • @Tabled:用来指定表中的主键字段信息

  • @TableField:用来指定表中的普通字段信息

如果实体类和表的对应关系不符合MyBatisPlus的约定,就可以使用这些注解声明。

注意事项:

我们在使用MyBatisPlus,一定要保证自己的实体类以及表中有一个名为id的字段(如果实体类中主键不为ID,那么也要使用注解@Tabled("id")),要使MyBatisPlus找到主键。

在数据库中的主键可以添加约束,比如 Auto_increment(自增),而在实体类中我们可以使用@Tabled(value="id",type = "IdType.AUTO")等等,

IdType枚举:

  • Auto:数据库自增长(数据库自己生成)

  • INPUT:通过set方法自行输入(由调用者填入)

  • ASSIGN_ID:分配id,基于接口IdentiterGenertaor的方法nextld()来生成id(我们也可以重写方法来覆盖原来的方法),默认实现类为DefaultIdentifiterGenerator,它内部自带一种雪花算法来帮助我们生成id,生成的是一个Long型的整数,长度为20位。(由MyBatisPlus帮助生成ID)

使用@TableField的常见场景

  • 成员变量名与数据库字段名不一致

  • 成员名以is开头,且类型为布尔值的字段,MyBatisPlus会基于反射类型的机制去获取字段名称,会将is减去作为变量名,变量名驼峰转下划线作为表的字段名便不起作用了,这时可能就与数据库中的字段名不一致。这种就需要去使用@TableField。

  • 成员变量名与数据库关键字冲突,这时我们需要使用转义字符,例如

 @TableField("`order`")
  • 成员变量不是数据库字段,这时就需要使用@TableField(exist = false)

更多详情在官方文档中查看:注解配置 | MyBatis-Plus

案例展示:

 @TableName("tb_user")public class User {​//用户ID//主键自增@TableId(type = IdType.AUTO)private Long id;//用户名@TableField("`username`")private String username;//密码@TableField(exist = false)private String password;//注册手机号private String phone;//详细信息private String info;//使用状态(1正常2冻结)private Integer status;//账户余额private Integer balance;//创建时间private LocalDateTime createTime;//更新时间private LocalDateTime updateTime;

image-20250530203106065

使用 @TableId(type = IdType.AUTO)就可以使id自增,但是如果不设置type,那默认策略是什么呢?

进行测试:

将测试单元中的setId()省略,以及实体类的 @TableId(type = IdType.AUTO)注解省略,再次进行测试:

测试成功,检查数据库

发现id值为long型,有20位,证明使用的是MybatisPlus中的雪花算法

image-20250530221920189

证明默认使用的策略就是ASSIGN_ID(雪花算法)。

常见配置

在前面我们只是导入了MyBatisPlus的起步依赖,就可以自动装配,无需配置就可直接使用,十分方便,但是MyBatisPlus也是支持一些自定义配置的,那么MyBatisPlus支持哪些常见的配置呢?

MyBatisPlus的配置项继承了MyBatis原生配置和自己特有的配置。例如:

 mybatis-plus:type-aliases-package: com.lyc.mp.pojo # 别名扫描包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 # 主键策略 雪花算法update-strategy: not_null # 更新策略 只更新非空字段

第一个: type-aliases-package:类型别名的扫描包,需要指定对应的实体类的包,就会扫描实体类

作用:将来在定义Mapper.xml文件中的语句时,如果需要定义实体类的类型,就不需要写全路径名,直接写类的简化名即可。

第二个: mapper-locations:mapper.xml文件的地址,可以扫描到指定包下的Mapper.xml文件。(MyBatisPlus更擅长单表查询,如果业务的SQL语句过于复杂或多表查询,就不建议使用MyBatisPlus,还是建议写Mapper.xml文件)

第三个: map-underscore-to-camel-case: true:开启驼峰命名与下划线命名的映射,开启后实体类与数据库中的字段名就会自动转换格式

第四个:cache-enabled: false:是否开启二级缓存

第五个:id-type:在前面学习的注解@TableId中的type中的默认配置,在配置文件中是全局配置,优先级没有注解高,如果注解配的是主键自增,那么是以注解内容为准,如果注解没有配置,则以配置类中的配置为准。

第六个:update-strategy: 更新策略,我们在前面中学习的MyBatisPlus只更新实体类中存在的字段,实体类中没有而数据库中存在的字段并不更新,这就是更新策略,上述讲的这种策略就是只更新非空字段。

以上的配置大多数都是有默认值的,几乎都不需要配置,除非要自定义修改。

如果要进行自定义修改时记不清配置名,有两种方法:

  • 查询官网:配置 | MyBatis-Plus

  • 根据集成工具代码提示及补全,因此只需要记忆一小部分即可,无需全部记忆

总结:

MyBatisPlus的基本使用流程:

  1. 引入起步依赖

  2. 自定义Mapper接口继承BaseMapper接口

  3. 在实体类添加注解声明表信息

  4. 在application.yml根据需要添加配置。

以上就是MyBatisPlus的快速入门,希望对大家有所帮助!

相关文章:

MyBatisPlus--快速入门

MyBatisPlus介绍 从名字中就可以感觉到MybatisPlus与MyBatis之间的渊源&#xff0c;而MyBatis是一个非常流行的持久层框架&#xff0c;主要来做数据库的增删改查&#xff0c;而MyBatisPlus这种命名方式让人不得不往MyBatis的升级版去联想&#xff0c;事实也确实如此&#xff0…...

鸿蒙 HarmonyOS - SideBarContainer 组件自学指南

在日常开发中&#xff0c;如果你有类似「左侧导航 右侧内容」的布局需求&#xff0c;比如后台管理界面、文件管理器、设置页等&#xff0c;​​SideBarContainer​​ 是非常值得掌握的组件。它自带侧边栏和主内容区的分离机制&#xff0c;还支持折叠、拖拽、控制按钮和多种显示…...

数据交易场景的数据质量评估

在现代数字化时代&#xff0c;数据已成为推动商业发展的核心驱动力。基于不同的交易产品和业务场景&#xff0c;数据产品的质量和准确性直接影响到数据资产的价值及其在市场中的流通性。因此&#xff0c;为数据产品提供全面、深入的数据质量评估报告&#xff0c;不仅有助于提升…...

C++ list基础概念、list初始化、list赋值操作、list大小操作、list数据插入

list基础概念&#xff1a;list中的每一部分是一个Node&#xff0c;由三部分组成&#xff1a;val、next、prev&#xff08;指向上一个节点的指针&#xff09; list初始化的代码&#xff0c;见下 #include<iostream> #include<list>using namespace std;void printL…...

39. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(函数写法)

39. 自动化异步测试开发之编写异步业务函数、测试函数和测试类&#xff08;函数写法&#xff09; 一、异步业务函数解析 1.1 页面导航函数 async def get(async_driver, url: str http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx):await…...

Go语言defer关键字:延迟执行的精妙设计

深度解析Go语言defer关键字&#xff1a;延迟执行的精妙设计 引言 在Go语言中&#xff0c;defer语句是一种独特而强大的控制流机制&#xff0c;它通过​​延迟执行​​的方式解决资源管理、错误处理和异常恢复等关键问题。理解defer的工作原理是掌握Go并发编程和错误处理的关键…...

提升WSL中Ubuntu编译速度的完整指南

在 WSL&#xff08;Windows Subsystem for Linux&#xff09;中使用 make 编译项目时&#xff0c;如果发现编译速度非常慢&#xff0c;通常是由以下几个原因导致的。以下是一些常见的排查和优化方法&#xff1a; &#x1f50d; 一、常见原因及解决方案 ✅ 1. 文件系统性能问题…...

【Linux 学习计划】-- 命令行参数 | 环境变量

目录 命令行参数 环境变量 环境变量的本质是什么&#xff1f; 相关配置文件 修改环境变量的相关操作 代码获取env —— environ 内建命令 结语 命令行参数 试想一下&#xff0c;我们的main函数&#xff0c;也是一个函数&#xff0c;那么我们的main函数有没有参数呢&am…...

服务器Docker容器创建与VScode远程连接SSH使用

一、拉取容器 1、win r 输入cmd打开终端命令行 2、终端输入 ping 192.168.xx.xxx 查看是否连接到服务器。如输出显示“字节 时间 TTL”等如下界面&#xff0c;则连接成功。否则输出“请求超时” 如果不能连接&#xff0c;则需要修改设备的IP&#xff0c;需要在设置-网络和In…...

体现物联网环境下安全防护的紧迫性 :物联网环境下的个人信息安全:隐忧与防护之道

摘要&#xff1a;随着物联网的飞速发展&#xff0c;个人信息在物联网环境下面临的安全风险日益严峻。本文深入探讨了物联网环境下个人信息泄露的主要途径&#xff0c;分析了当前个人信息安全保护面临的挑战&#xff0c;并从技术、法律、企业责任和个人意识等多方面提出了相应的…...

LiveQing 视频点播流媒体 RTMP 推流服务功能:搭建 RTMP 视频流媒体服务详细指南

LiveQing视频点播流媒体RTMP推流服务功能&#xff1a;搭建RTMP视频流媒体服务详细指南 一、流媒体服务搭建二、推流工具准备三、创建鉴权直播间四、获取推流地址五、配置OBS推流六、推流及播放七、获取播放地址7.1 页面查看视频源地址7.2 接口查询 八、相关问题解决8.1 大疆无人…...

LeetCode 高频 SQL 50 题(基础版)之 【连接】部分 · 下

前五道题&#xff1a;LeetCode 高频 SQL 50 题&#xff08;基础版&#xff09;之 【连接】部分 上 题目&#xff1a;577. 员工奖金 题解&#xff1a; select r.name,b.bonus from Employee r left join Bonus b on r.empIdb.empId where b.bonus <1000 or b.bonus is nul…...

【正点原子STM32】RS485串行通信标准(串口基础协议 和 MODBUS协议、总线连接、通信电路、通信波形图、RS485相关HAL库驱动、RS485配置步骤、)

一、RS485介绍 二、RS485相关HAL库驱动介绍 三、RS485配置步骤 四、编程实战 五、总结 串口、 UART、TTL、RS232、RS422、RS485关系 串口、UART、TTL、RS232、RS422和RS485之间的关系可以如此理解&#xff1a; 串口&#xff1a;是一个广义术语&#xff0c;通常指的是采用串行通…...

从SPDY到HTTP/2:网络协议的革新与未来

从SPDY到HTTP/2&#xff1a;网络协议的革新与未来 在互联网的发展史上&#xff0c;协议的演进始终是推动用户体验提升的关键。从早期的HTTP/1.1到如今的HTTP/2&#xff0c;再到即将全面普及的HTTP/3&#xff0c;每一次变革都伴随着性能、安全性和效率的突破。今天&#xff0c;…...

在力扣刷题中触摸算法的温度

在代码的世界里&#xff0c;每一道力扣题目都是一扇通往未知的门。当我推开这些门&#xff0c;与内置求和函数、二进制位运算、辗转相减思想以及链表结构相遇时&#xff0c;才真正触摸到算法的温度 —— 那是一种理性与智慧交织的炽热&#xff0c;也是思维不断淬炼的滚烫。​ 最…...

外部访问可视化监控 Grafana (Windows版本)

Grafana 是一款通用&#xff0c;美观的&#xff0c;强大的可视化监控指标的展示工具。可以将不同的数据源数据以图形化的方式展示。它支持多种数据源&#xff0c;如 Prometheus 等&#xff0c;可以满足不同的需求。也可以通过插件和 API 进行扩展满足各种需求&#xff0c;…...

通用的防御框架,用于抵御(多模态)大型语言模型的越狱攻击

大家读完觉得有帮助记得关注&#xff01;&#xff01;&#xff01; 摘要 尽管&#xff08;多模态&#xff09;大型语言模型&#xff08;LLMs&#xff09;因其卓越的能力而受到广泛关注&#xff0c;但它们仍然容易受到越狱攻击。已经提出了各种防御方法来防御越狱攻击&#xff…...

聊聊JVM怎么调优?(实战总结)

JVM 核心配置与调优指南 一、堆内存与年轻代配置&#xff08;影响最大&#xff09; 堆内存大小&#xff1a; 在资源允许的前提下&#xff0c;堆内存应尽可能设置得更大。关键点&#xff1a; 必须将堆内存的最大值 (-Xmx) 和最小值 (-Xms) 设置为相同值。动态扩容会触发 Full G…...

新能源汽车电控系统的精准守护者PKDV5355高压差分探头

在新能源汽车的"心脏"——电控系统中&#xff0c;每一次电流的精准切换都关乎车辆的性能与安全。PRBTEK PKDV5355高压差分探头就像一位经验丰富的"汽车医生"&#xff0c;帮助工程师们精准捕捉IGBT模块的每一次"心跳"&#xff0c;确保电驱系统健康…...

C# 导出word 插入公式问题

最近遇到了一个问题&#xff0c;下载一个文档时需要下载word可编辑的公式。找了很久终于找到了一种解决办法。下面是以C#代码来实现在Word中插入公式的功能。 目录 一、引入dll程序集文件1、通过 NuGet 引入dll&#xff08;2种方法&#xff09;的方法&#xff1a;2、手动添加d…...

Mac安装配置InfluxDB,InfluxDB快速入门,Java集成InfluxDB

1. 与MySQL的比较 InfluxDBMySQL解释BucketDatabase数据库MeasurementTable表TagIndexed Column索引列FieldColumn普通列PointRow每行数据 2. 安装FluxDB brew update默认安装 2.x的版本 brew install influxdb查看influxdb版本 influxd version # InfluxDB 2.7.11 (git: …...

手撕Java+硅基流动实现MCP服务器教程

手撕Java硅基流动实现MCP服务器教程 一、MCP协议核心概念 MCP是什么 MCP 是 Anthropic (Claude) 主导发布的一个开放的、通用的、有共识的协议标准。 ● MCP 是一个标准协议&#xff0c;就像给 AI 大模型装了一个 “万能接口”&#xff0c;让 AI 模型能够与不同的数据源和工…...

EasyRTC嵌入式音视频通信SDK助力1v1实时音视频通话全场景应用

一、方案概述​ 在数字化通信需求日益增长的今天&#xff0c;EasyRTC作为一款全平台互通的实时视频通话方案&#xff0c;实现了设备与平台间的跨端连接。它支持微信小程序、APP、PC客户端等多端协同&#xff0c;开发者通过该方案可快速搭建1v1实时音视频通信系统&#xff0c;适…...

Prometheus学习之pushgateway和altermanager组件

[rootnode-exporter41 /usr/local/alertmanager-0.28.1.linux-amd64]# pwd /usr/local/alertmanager-0.28.1.linux-amd64[rootnode-exporter41 /usr/local/alertmanager-0.28.1.linux-amd64]# cat alertmanager.yml # 通用配置 global:resolve_timeout: 5msmtp_from: 914XXXXX…...

01 redis 的环境搭建

前言 这一系列文章主要包含的内容主要是 各种常用软件的调试环境的搭建 主要的目的是 搭建一个可打断点的一个调试环境 c 系列 主要是基于 clion 调试, java 系列主要是基于 idea 调试, js 系列主要是基于 webstorm 调试 需要有一定的 c, c, java, js 相关基础 基于的…...

《操作系统真相还原》——加载器

显存 将上一章的中断输出&#xff0c;变为显存输出 加载器 使用mbr引导程序从磁盘中加载loader程序。 MBR %include "boot.inc" SECTION MBR vstart0x7c00 mov ax,cs mov ds,axmov es,axmov ss,axmov fs,axmov sp,0x7c00mov ax,0xb800mov gs,ax;cl…...

电网即插即用介绍

一、统一设备信息模型与标准接口 实现即插即用功能的基础在于建立统一的设备信息模型。不同厂家生产的各类电网设备&#xff0c;其内部结构、通信协议、数据格式等往往千差万别。通过制定统一的设备信息模型&#xff0c;能够对设备的各种属性、功能以及接口进行标准化定义&…...

HJ25 数据分类处理【牛客网】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 HJ25 数据分类处理 一、题目描述 二、测试用例 三、解题思路 基本思路&#xff1a;   首先理解题目&#xff0c;题目要求对规则集先进行排序&#xff0c;然后去重&#xff0c;这一步我…...

spring-boot redis lua脚本实现滑动窗口限流

因为项目中没有集成redisson&#xff0c;但是又需要用到限流&#xff0c;所以简单的将redisson中限流的核心lua代码移植过来&#xff0c;并进行改造&#xff0c;因为公司版本的redis支持lua版本为5.1&#xff0c;针对于长字符串的数字&#xff0c;使用tonumber转换的时候会得到…...

USB MSC

主机&#xff08;如电脑&#xff09;识别USB MSC&#xff08;Mass Storage Class&#xff09;设备中的文件&#xff0c;本质上是通过多层协议协作实现的&#xff0c;涉及USB枚举、SCSI命令传输和文件系统解析三个核心环节。以下是详细机制&#xff1a; &#x1f50d; ​一、USB…...