SpringBoot 集成Mybatis Plus

一、为什么SpringBoot不推荐使用Mybatis

Spring Boot 不推荐使用 MyBatis,主要源于二者在设计理念、生态融合和开发风格上的差异。Spring Boot 强调“约定优于配置”,追求高效的开发体验和统一的框架风格。它通过自动配置和依赖注入,将复杂的基础设施工作隐藏在背后,让开发者可以专注于业务逻辑。而 MyBatis 更偏向于手动控制,强调 SQL 编写的灵活性与精确性,这种“显式配置”的风格在 Spring Boot 的体系中显得不够“Spring 化”。

在 Spring Boot 中,JPA(通常基于 Hibernate)得到了默认和深度的支持。它不仅提供了实体类到数据库表之间的自动映射能力,还能通过接口继承如 JpaRepository 来实现大部分常见的 CRUD 操作,几乎不需要写 SQL。这种面向对象的操作方式非常契合 Spring Boot 的开发理念。而 MyBatis 缺乏这样的统一接口标准,每一个查询都必须手动书写 Mapper 接口和 SQL 映射,导致代码重复多、维护成本高,不利于构建统一规范的架构。

此外,Spring Boot 的许多生态组件都是围绕 JPA 构建的。例如 Spring Data、Spring Data REST、Spring Security 等在与 JPA 协同工作时,可以自动识别实体类、权限注解和仓库接口,实现快速集成与配置。而 MyBatis 在这些方面往往需要额外的手工代码或第三方扩展来弥补功能差距,使得整个开发过程不够简洁和一致。

MyBatis 对复杂 SQL 的支持是它的优势,但也意味着它无法享受到像 JPA 那样的自动建表、字段同步、懒加载、级联操作等特性,这使得在开发初期或者需求频繁变化的项目中,使用 MyBatis 会显得繁琐与低效。同时,它的类型转换和对象关系映射能力相对较弱,复杂嵌套对象处理起来也需要手动配置,这与 Spring Boot 鼓励的自动化、低侵入、高复用的理念相悖。

因此,Spring Boot 并不是技术上无法使用 MyBatis,而是在它所倡导的开发模式中,MyBatis 显得不够“现代”,不够“自动”,也不够“统一”。在快速开发和规范统一的项目场景中,Spring Boot 更愿意推荐使用 JPA 或 Spring Data,只有在 SQL 控制要求高或性能调优需求明显的项目中,MyBatis 才是一个合适的选择。这也解释了为什么 Spring Boot 对 MyBatis 提供了官方 Starter,但始终没有像支持 JPA 那样将其设为默认或推荐选项。

二、Mybatis Plus 简介

MyBatis-Plus 是在 MyBatis 基础上进行增强的一个持久层框架,旨在简化 MyBatis 的开发过程,提高效率,降低重复代码。它并不改变 MyBatis 的核心理念,而是在其上层进行了封装,使开发者可以更方便地进行 CRUD 操作和复杂查询。MyBatis 本身需要手动编写 SQL 和 Mapper 接口,而 MyBatis-Plus 提供了丰富的自动化功能,如内置通用 Mapper、Service、分页插件、条件构造器等,从而大大减少了模板代码的数量。

通过集成 MyBatis-Plus,开发者可以仅通过继承 BaseMapper 接口,立即拥有一整套通用的数据库操作方法,如 selectById、insert、updateById、deleteById 等,避免了重复的 Mapper 方法定义。此外,它还支持强大的 Lambda 条件构造器,能用链式方式编写类型安全的查询条件,提升代码可读性和可维护性。MyBatis-Plus 还提供分页插件、乐观锁插件、逻辑删除、SQL 性能分析等实用功能,帮助开发者应对企业级应用中常见的持久层需求。

虽然 MyBatis-Plus 不属于 Spring Boot 官方推荐的技术栈,但它却很好地弥补了 MyBatis 开发繁琐、重复代码多的问题,使得 MyBatis 在与 Spring Boot 集成时更加现代化和高效。对于那些既想保留 SQL 控制力,又不想从零开始构建 CRUD 接口的团队来说,MyBatis-Plus 是一个非常实用且易于上手的选择。它在不改变原有 MyBatis 使用方式的前提下,通过增强功能提升了开发体验,越来越多的企业项目也因此倾向于在 Spring Boot 中选择 MyBatis-Plus 作为持久层方案。

三、SpringBoot 集成 Mybatis Plus

1、准备 SpringBoot 项目

创建如上结构

2、导入依赖

<dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>

3、创建实体类

package com.goose.entity;import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;import java.util.Date;@Data
@AllArgsConstructor
// @Getter
// @Setter
// @ToString
@NoArgsConstructor
public class Teacher {private Integer id;private String name;private String gender;private String subject;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date hireDate;
}

4、创建好配置文件

application.yml

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.zaxxer.hikari.HikariDataSourceurl: jdbc:mysql://localhost:3306/springbootdemousername: rootpassword: 123456# 配置MyBatis日志
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

5、创建配置类

package com.goose.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

这个配置类为 MyBatis-Plus 启用分页功能,在执行分页查询时自动处理 LIMIT 语句等逻辑,无需手写 SQL 来分页。

6、创建mapper 接口

package com.goose.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.goose.entity.Teacher;
import org.springframework.stereotype.Repository;@Repository
public interface TeacherMapper extends BaseMapper<Teacher> {}

7、安装 lombok 插件

File——Settings——Plugins

搜索找到 lombok 插件,下载安装后,重启 IDE

 

Lombok 是一个 Java 编译器级别的工具库,它的作用是通过注解的方式,自动为 Java 类生成常见的样板代码,如 getter、setter、构造函数、toString、equals、hashCode 等,从而大幅度简化代码、提升开发效率、减少冗余。

具体来说,Lombok 插件的主要作用如下:

  • 简化 Getter/Setter 编写:使用 @Getter 和 @Setter 注解,可以自动为类的字段生成对应的 getter 和 setter 方法,无需手写。
  • 自动生成构造函数:@NoArgsConstructor、@AllArgsConstructor、@RequiredArgsConstructor 可以自动生成无参、全参和指定字段的构造函数。
  • 简化 toString/equals/hashCode 方法:使用 @ToString、@EqualsAndHashCode 注解后,不再需要手动重写这些方法。
  • 简化 Builder 模式编写:@Builder 可以自动实现链式调用构建对象的方式,适用于构造参数多的类。
  • 提供 Data 注解一站式生成常见方法:@Data 相当于同时加上 @Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor,是实体类开发中非常常用的注解。
  • 简化日志对象创建:@Slf4j、@Log4j 等注解可以自动为类生成对应类型的日志对象。

Lombok 插件的运行机制是在编译期通过注解处理器修改字节码,并不会在源码中直接生成方法,因此你看不到生成的 getter/setter,但它们确实存在于最终编译后的 class 文件中。Ctrl + F12 进行查看

由于它改写的是编译行为,所以在 IDEA 中使用时,必须安装 Lombok 插件并开启注解处理器,否则会出现提示找不到方法的错误。

8、创建数据库表

生成测试数据

9、编写测试类

简单的CRUD操作可以不用再自己编写SQL,直接调用BaseMapper 中的方法即可。

这里直接使用持久层进行注入,不涉及到页面的使用

package com.goose;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.goose.entity.Teacher;
import com.goose.mapper.TeacherMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.text.SimpleDateFormat;
import java.util.*;@SpringBootTest
class MybatisDemo1ApplicationTests {@Autowiredpublic TeacherMapper teacherMapper;@Testpublic void findAll() {teacherMapper.selectList(null).forEach(System.out::println);}/* 插入实体对象*/@Testpublic void insert() {Date now = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");simpleDateFormat.format(now);Teacher teacher = new Teacher();teacher.setName("李华");teacher.setGender("male");teacher.setSubject("化学");teacher.setHireDate(now);teacherMapper.insert(teacher);}/* 根据主键id删除一条数据*/@Testpublic void deleteById() {teacherMapper.deleteById(16);}/* 传入实体数据,根据实体中的数据进行删除*/@Testpublic void deleteById_Entity() {Teacher teacher = new Teacher();teacher.setId(18);teacherMapper.deleteById(teacher);}@Testpublic void deleteByMap() {// string放列名,Object放想要删除该列中满足某条件Map<String, Object> map = new HashMap<>();// 这里使用name作为条件map.put("name", "Ivy Ma");map.put("gender", "female");// 删除所有name 为 Ivy Ma 的教师// 可以多行删除,但是不会操作具有外键约束的内容// DELETE FROM teacher WHERE gender = ? AND name = ?teacherMapper.deleteByMap(map);}@Testpublic void delete() {QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();// eq应该是等于的,le应该是小于,ge应该是大于// teacherQueryWrapper.eq("name","Queena");// DELETE FROM teacher WHERE (name = ?)// teacherMapper.delete(teacherQueryWrapper);teacherQueryWrapper.eq("name", "Queena");teacherQueryWrapper.eq("subject", "Biology");// DELETE FROM teacher WHERE (name = ? AND subject = ?)teacherMapper.delete(teacherQueryWrapper);}@Testpublic void deleteBathIds() {List<Integer> list = new ArrayList<>();list.add(14);list.add(22);list.add(6);list.add(18);// ==>  Preparing: DELETE FROM teacher WHERE id IN ( ? , ? , ? , ? )// ==> Parameters: 14(Integer), 22(Integer), 6(Integer), 18(Integer)teacherMapper.deleteBatchIds(list);}@Testpublic void update() {Teacher teacher = new Teacher();teacher.setId(21);teacher.setSubject("English");teacher.setGender("male");// 传入的对象需要主键// ==>  Preparing: UPDATE teacher SET gender=?, subject=? WHERE id=?// ==> Parameters: male(String), English(String), 21(Integer)teacherMapper.updateById(teacher);}@Testpublic void updateBy() {QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();teacherQueryWrapper.eq("subject", "English");Teacher teacher = new Teacher();teacher.setGender("female");// ==>  Preparing: UPDATE teacher SET gender=? WHERE (subject = ?)// ==> Parameters: female(String), English(String)teacherMapper.update(teacher, teacherQueryWrapper);}@Testpublic void selectById() {Teacher teacher = teacherMapper.selectById(32);// ==>  Preparing: SELECT id,name,gender,subject,hire_date FROM teacher WHERE id=?// ==> Parameters: 32(Integer)System.out.println(teacher);}@Testpublic void selectBatchIds() {List<Integer> list = new ArrayList<>();list.add(34);list.add(42);list.add(26);list.add(38);// ==>  Preparing: SELECT id,name,gender,subject,hire_date FROM teacher WHERE id IN ( ? , ? , ? , ? )// ==> Parameters: 34(Integer), 42(Integer), 26(Integer), 38(Integer)List<Teacher> teachers = teacherMapper.selectBatchIds(list);System.out.println(teachers);}@Testpublic void selectByMap(){Map<String, Object> map = new HashMap<>();map.put("gender","male");map.put("subject","Chemistry");// ==>  Preparing: SELECT id,name,gender,subject,hire_date FROM teacher WHERE gender = ? AND subject = ?// ==> Parameters: male(String), Chemistry(String)List<Teacher> teachers = teacherMapper.selectByMap(map);System.out.println(teachers);}@Testpublic void selectOne(){QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();teacherQueryWrapper.eq("name","Jason");// 只能查一条数据,数据多于一条,抛出错误,查询条件比较严格Teacher teacher = teacherMapper.selectOne(teacherQueryWrapper);System.out.println(teacher);}@Testpublic void exist(){QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();teacherQueryWrapper.eq("subject","Chemistry");// ==>  Preparing: SELECT COUNT( * ) FROM teacher WHERE (subject = ?)boolean exists = teacherMapper.exists(teacherQueryWrapper);System.out.println(exists);}@Testpublic void selectCount(){QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();teacherQueryWrapper.eq("gender","female");// ==>  Preparing: SELECT COUNT( * ) FROM teacher WHERE (gender = ?)// ==> Parameters: female(String)Long aLong = teacherMapper.selectCount(teacherQueryWrapper);System.out.println(aLong);}@Testpublic void selectList(){QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();teacherQueryWrapper.eq("gender","female");// ==>  Preparing: SELECT id,name,gender,subject,hire_date FROM teacher WHERE (gender = ?)// ==> Parameters: female(String)List<Teacher> teachers = teacherMapper.selectList(teacherQueryWrapper);System.out.println(teachers);}@Testpublic void selectMaps(){QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();teacherQueryWrapper.eq("gender","female");// ==>  Preparing: SELECT id,name,gender,subject,hire_date FROM teacher WHERE (gender = ?)// ==> Parameters: female(String)List<Map<String, Object>> maps = teacherMapper.selectMaps(teacherQueryWrapper);// 把每个Teacher对象拆开了,拆成单独的map对象System.out.println(maps);}@Testpublic void selectObjs(){QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();teacherQueryWrapper.eq("gender","female");// ==>  Preparing: SELECT id,name,gender,subject,hire_date FROM teacher WHERE (gender = ?)// ==> Parameters: female(String)List<Object> objects = teacherMapper.selectObjs(teacherQueryWrapper);// [1, 3, 4, 5, 7, 9, 11, 13, 15, 19, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, 38, 39, 41, 43, 45, 47, 49]// 只返回第一个字段的值System.out.println(objects);}@Testpublic void testSelectPage() {// 创建分页对象:第1页,每页5条记录Page<Teacher> page = new Page<>(1, 5);// 构造查询条件:只查 gender = 'female'QueryWrapper<Teacher> wrapper = new QueryWrapper<>();wrapper.eq("gender", "female");// 执行分页查询Page<Teacher> resultPage = teacherMapper.selectPage(page, wrapper);// 打印分页结果System.out.println("总记录数: " + resultPage.getTotal());System.out.println("总页数: " + resultPage.getPages());System.out.println("当前页数据:");resultPage.getRecords().forEach(System.out::println);}@Testpublic void testSelectMapsPage() {// 分页参数Page<Map<String, Object>> page = new Page<>(1, 5);// 查询条件:查 subject = 'Math'QueryWrapper<Teacher> wrapper = new QueryWrapper<>();wrapper.eq("subject", "Math");// 分页查询返回 Map 列表Page<Map<String, Object>> resultPage = teacherMapper.selectMapsPage(page, wrapper);// 打印结果System.out.println("总记录数: " + resultPage.getTotal());System.out.println("总页数: " + resultPage.getPages());System.out.println("当前页 Map 数据:");resultPage.getRecords().forEach(System.out::println);}
}

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

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

相关文章

PI 思维升级 PI设计的典范转移:从阻抗思维到谐振控制

们先来回想一件事&#xff0c;根据欧姆定律&#xff0c;阻抗是不是越低越好&#xff1f; 代表即使有很大的瞬时电流&#xff0c;瞬间的电压降也不会超过某个极限&#xff01;理论上是&#xff01; 可是这其实忽略了两个关键的要素&#xff1a;PDN阻抗有谐振&#xff1a;谐振代表…

如何制定企业级服务器安全策略(Security Policy)

制定一套**企业级服务器安全策略&#xff08;Security Policy&#xff09;**对于保护服务器资源、数据安全和业务连续性至关重要。以下是制定安全策略的详细指南&#xff0c;包括安全策略的核心要素、实施步骤和具体措施&#xff0c;帮助企业构建全面的服务器安全防护体系。1. …

n1 armbian docker compose 部署aipan mysql

apt update apt install docker-compose-plugin -y #安装docker compose docker compose version Docker Compose version v2.38.2 sudo mkdir -p /sda1/data/mysql/conf.d sudo chown -R 999:999 /sda1/data/mysql # MySQL 用户 UID 通常为 999 cat docker-compose.yml vers…

RAG情境化分段向量模型voyage-context-3,聚焦分段细节,融入全局文档上下文

最近看到一个有意思的工作&#xff0c;原文来自&#xff1a; https://blog.voyageai.com/2025/07/23/voyage-context-3/?utm_sourceTWITTER&utm_mediumORGANIC_SOCIAL voyage-context-3&#xff1a;聚焦分段细节&#xff0c;融入全局文档上下文 概要&#xff1a; Voyage A…

计算机体系结构中的中断服务程序ISR是什么?

计算机体系结构中的中断服务程序ISR是什么&#xff1f; 在计算机体系结构中&#xff0c;中断服务程序&#xff08;Interrupt Service Routine, ISR&#xff09; 是操作系统或硬件直接调用的关键代码模块&#xff0c;用于响应来自硬件设备、软件异常或系统事件的中断信号。其核心…

开源项目XBuilder前端框架

spx-gui/ 配置文件package.json 项目依赖和脚本配置vite.config.ts Vite构建工具配置tsconfig.json TS项目配置主文件tsconfig.app.json 应用程序的TS配置tsconfig.node.json Node.js环境的TS配置index.html 应用入口HTML文件src/ 源码目录main.ts 应用入口文件&#xff0c;初始…

0723 单项链表

Part 1.完成单向链表&#xff0c;并完成下面功能1.单链表节点创建链表是物理空间上不连续的一个结构&#xff0c;需要创建一个next作为指向下一个节点的指针&#xff0c;所以需要建立一个结构体包含数据域&#xff0c;next指针域&#xff0c;记录长度的数据域。因为长度只有头节…

基于 ASP.NET Web 应用程序(.NET Framework)的花店系统

1.1功能模块实现1.1.1整体结构界面由两部分组成&#xff1a;左侧导航栏、右侧内容展示区。使用了 Bootstrap 5 的样式库&#xff0c;并结合了 ASP.NET MVC 的 Html.ActionLink 和 Razor 条件判断语句来动态生成菜单项。1.1.2导航栏功能模块导航栏基础结构导航栏基础结构使用 Bo…

C++ Qt6 CMake qml文件启动方式说明

在Qt6之后,Qt程序默认使用CMake进行构建,当然也可以使用qmake, 本篇博客介绍Qt6.8之前和Qt6.8版本中QtQuick程序的启动方式。 在QtQuick程序main.cpp里qml的文件启动分为两种:(1)直接加载qml文件,(2)加载qml模块,下面分别介绍这两种启动方式。 方式1:直接启动qml文…

字符串 “asdasjkfkasgfgshaahsfaf” 经过哈夫曼编码之后存储比特数是多少?

要计算字符串 “asdasjkfkasgfgshaahsfaf” 经过哈夫曼编码后的存储比特数&#xff0c;需按以下步骤进行&#xff1a;步骤 1&#xff1a;统计字符出现频率先统计字符串中每个字符的出现次数&#xff1a;a&#xff1a;出现 6 次s&#xff1a;出现 6 次d&#xff1a;出现 1 次j&a…

什么是游戏盾(高防版)?

随着网络游戏产业的快速发展&#xff0c;游戏服务器的安全问题日益受到关注。DDoS攻击、CC攻击等网络威胁常常导致游戏卡顿、断线甚至服务器宕机&#xff0c;严重影响玩家体验。游戏盾&#xff08;高防版&#xff09;是一种专为游戏业务设计的网络安全防护服务&#xff0c;集成…

openGauss数据库在CentOS 7 中的单机部署与配置

部署 版本选择 通过openGuass官网下载地址 &#xff0c;我们可以看到它支持x86_64与Aarch64两种平台&#xff0c;又分成openEuler 22、openEuler 20、Centos 7以及Docker 版本。 进入CentOS 7标签&#xff0c;看到又分成企业版、轻量版、极简版与分布式镜像版。 本文只讨论…

HTTP响应状态码详解

HTTP 响应状态码&#xff08;HTTP Status Code&#xff09;是服务器在响应客户端请求时返回的 3 位数字代码&#xff0c;用于表示请求的处理状态。以下是常见的 HTTP 状态码及其含义&#xff1a; 1xx&#xff08;信息性状态码&#xff09; 表示请求已被接收&#xff0c;需要继…

Pytorch中register_buffer和torch.nn.Parameter的异同

说下register_buffer和Parameter的异同 相同点方面描述追踪都会被加入 state_dict&#xff08;模型保存时会保存下来&#xff09;。与 Module 的绑定都会随着模型移动到 cuda / cpu / float() 等而自动迁移。都是 nn.Module 的一部分都可以通过模块属性访问&#xff0c;如 self…

吉吉巳资源整站源码完整打包,适用于搭建资源聚合/整合类站点,全网独家,拿来就用

想要搭建一个资源整合站点&#xff0c;如影视聚合类站点、资讯聚合类站点、图集聚合类站点等&#xff0c;需要花费大量的时间来查找合适的系统或源码。然后要去测试&#xff0c;修复bug&#xff0c;一直到能够正常的运营使用&#xff0c;花费的时间绝对不短&#xff0c;今天分享…

嵌入式学习的第三十五天-进程间通信-HTTP

TCP/IP协议模型&#xff1a;应用层&#xff1a;HTTP;传输层&#xff1a;TCP UDP;网络层&#xff1a;IPv4 IPv6网络接口层一、HTTP协议1. 万维网WWW(World Wide Web) 世界范围内的&#xff0c;联机式的信息储藏所。 万维网解决了获取互联网上的数据时需要解决的以下问题&#x…

es 和 lucene 的区别

1. Lucene 是“发动机”&#xff0c;ES 是“整车”Lucene&#xff1a;只是一个 Java 库&#xff0c;提供倒排索引、分词、打分等底层能力。你必须自己写代码处理索引创建、更新、删除、分片、分布式、故障恢复、API 封装等所有逻辑。Elasticsearch&#xff1a;基于 Lucene 的分…

AS32S601 系列 MCU芯片GPIO Sink/Source 能力测试方法

一、引言随着电子技术的飞速发展&#xff0c;微控制器&#xff08;MCU&#xff09;在工业控制、汽车电子、商业航天等众多领域得到了广泛应用。国科安芯推出的AS32S601 系列 MCU 以其卓越的性能和可靠性&#xff0c;成为了众多设计工程师的首选之一。为了确保其在实际应用中的稳…

JAVA-08(2025.07.24学习记录)

面向对象类package com.mm;public class Person {/*** 名词-属性*/String name;int age;double height;/*** 动词-方法*/public void sleep(String add) {System.out.println("我在" add "睡觉");}public String introduce() {return "我的名字是&q…

地下隧道管廊结构健康监测系统 测点的布设及设备选型

隧道监测背景 隧道所处地下环境复杂&#xff0c;在施工过程中会面临围堰变形、拱顶沉降、净空收敛、初衬应力变化、土体塌方等多种危险情况。在隧道营运过程中&#xff0c;也会受到材料退化、地震、人为破坏等因素影响&#xff0c;引发隧道主体结构的劣化和损坏&#xff0c;若不…