SpringBoot筆記:SpringBoot 集成 Dataway 多數據源配置(二)

文章目錄

  • 前言
  • 核心代碼和配置
    • yml 配置
    • 注入多數據源
    • 常用Spi實現
    • swagger 配置
    • 自定義 Udf
    • 指定數據源進行查詢

前言

之前簡單介紹了一下 Dataway 使用,本文繼續介紹一下它的多數據源配置和使用。

核心代碼和配置

yml 配置

# springboot多環境配置
#端口,項目上下文
server:port: 8080servlet:context-path: /springboot-dataway# 全局服務編碼設置encoding:charset: utf-8enabled: trueforce: true# mysql 連接信息配置
spring:# mysql 數據庫連接信息,本地使用 mysql 服務版本為:8.0.28datasource:username: rootpassword: 6tojyh*A3eQ6url: jdbc:mysql://localhost:3306/dataway?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowPublicKeyRetrieval=truedriver-class-name: com.mysql.cj.jdbc.Driver# druid 數據連接池配置druid:initial-size: 3min-idle: 3max-active: 10max-wait: 6000# 配置druid監控頁aop-patterns: com.demo.* #監控springBeanstat-view-servlet: # 配置監控頁功能enabled: true # 默認開啟,這里顯示說明login-username: admin # 登錄名login-password: 6tojyh*A3eQ6 # 登錄密碼reset-enable: false # 禁用重置按鈕web-stat-filter: # 監控 webenabled: trueurl-pattern: /* # 監控所有exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'  #放行filter:stat: # 對上面 filters 里的 stat 的詳細配置slow-sql-millis: 1000 # 慢 sql 時間是毫秒單位的,執行時間 1 秒以上的為慢 SQLlog-slow-sql: true # 日志記錄enabled: truewall:enabled: trueconfig:drop-table-allow: false # 禁用刪除表的 sql# 除主數據源外,第1個數據源db1:username: rootpassword: 6tojyh*A3eQ6url: jdbc:mysql://localhost:3306/console?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowPublicKeyRetrieval=truedriver-class-name: com.mysql.cj.jdbc.Driver# 除主數據源外,第 2 個數據源db2:username: postgrespassword: UFWOd75qD7url: jdbc:postgresql://localhost:32770/postgres?binaryTransfer=false&forceBinary=false&reWriteBatchedInserts=truedriver-class-name: org.postgresql.Driver# mdataway 配置
# 是否啟用 Dataway 功能(必選:默認false)
HASOR_DATAQL_DATAWAY: true
# 開啟 ui 管理功能(注意生產環境必須要設置為 false,否則會造成嚴重的生產安全事故)
HASOR_DATAQL_DATAWAY_ADMIN: true
# dataway  API工作路徑(可選,默認:/api/)
HASOR_DATAQL_DATAWAY_API_URL: /api/
# dataway-ui 的工作路徑(可選,默認:/interface-ui/)
HASOR_DATAQL_DATAWAY_UI_URL: /interface-ui/
# SQL執行器方言設置(可選,建議設置)
HASOR_DATAQL_FX_PAGE_DIALECT: mysql
# 登陸認證方式在 basic 模式下的時候,配置的登陸賬號
HASOR_DATAQL_DATAWAY_AUTHORIZATION_USERNAME: admin
# 登陸認證方式在 basic 模式下的時候,配置的登陸密碼,默認密碼admin
HASOR_DATAQL_DATAWAY_AUTHORIZATION_PASSWORD: 6tojyh*A3eQ6# 日志輸出配置
logging:level:root: debugorg:springframework:security: WARNweb: ERROR# 設置自己的 com.demo.mapper 目錄 輸出sql日志com.demo.mapper: debugfile:path: ./logsname: './logs/springboot-dataway.log'pattern:file: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n'console: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n'

注入多數據源

package com.demo.config;import com.alibaba.druid.pool.DruidDataSource;
import com.demo.chain.*;
import net.hasor.core.ApiBinder;
import net.hasor.core.DimModule;
import net.hasor.core.TypeSupplier;
import net.hasor.dataql.Finder;
import net.hasor.dataql.QueryApiBinder;
import net.hasor.dataql.fx.db.FxSqlCheckChainSpi;
import net.hasor.dataway.spi.LoginPerformChainSpi;
import net.hasor.dataway.spi.LoginTokenChainSpi;
import net.hasor.dataway.spi.PreExecuteChainSpi;
import net.hasor.dataway.spi.ResultProcessChainSpi;
import net.hasor.db.JdbcModule;
import net.hasor.db.Level;
import net.hasor.spring.SpringModule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.sql.DataSource;/*** @Classname DatawayModule* @Description 將Hasor模塊注入spring,并注入數據源* @Date 2023/7/28 11:43* @Created by Leo825*/
@DimModule  // Hasor 中的標簽,表明是一個Hasor的model
@Component  // Spring 中的標簽,表明是一個組件
public class DatawayModule implements SpringModule,TypeSupplier {// 默認數據源@Autowiredprivate DataSource dataSource;// 數據源1的配置信息@Value("${spring.datasource.db1.url}")private String jdbcUrl1;@Value("${spring.datasource.db1.driver-class-name}")private String driver1;@Value("${spring.datasource.db1.username}")private String username1;@Value("${spring.datasource.db1.password}")private String password1;// 數據源2的配置信息@Value("${spring.datasource.db2.url}")private String jdbcUrl2;@Value("${spring.datasource.db2.driver-class-name}")private String driver2;@Value("${spring.datasource.db2.username}")private String username2;@Value("${spring.datasource.db2.password}")private String password2;@Resourceprivate ApplicationContext applicationContext;@Overridepublic <T> T get(Class<? extends T> targetType) {return applicationContext.getBean(targetType);}@Overridepublic <T> boolean test(Class<? extends T> targetType) {return applicationContext.getBeanNamesForType(targetType).length > 0;}@Overridepublic void loadModule(ApiBinder apiBinder) throws Throwable {// .DataSource form Spring boot into HasorapiBinder.installModule(new JdbcModule(Level.Full, this.dataSource));// 注入數據源apiBinder.installModule(new JdbcModule(Level.Full, this.dataSource));apiBinder.installModule(new JdbcModule(Level.Full, "dataSource1", getDataSource(jdbcUrl1, driver1, username1, password1)));apiBinder.installModule(new JdbcModule(Level.Full, "dataSource2", getDataSource(jdbcUrl2, driver2, username2, password2)));// 打印sql日志apiBinder.bindSpiListener(FxSqlCheckChainSpi.class, FxSqlCheckChain.getInstance());// 數據權限參數apiBinder.bindSpiListener(PreExecuteChainSpi.class, PreExecuteChain.getInstance());// 返回結果apiBinder.bindSpiListener(ResultProcessChainSpi.class, ResultProcessChain.getInstance());
//        // 登錄過濾
//        apiBinder.bindSpiListener(LoginPerformChainSpi.class, LoginPerformChain.getInstance());// 登錄 token 過濾
//        apiBinder.bindSpiListener(LoginTokenChainSpi.class, LoginTokenChain.getInstance());// udf/udfSource/import 指令 的類型創建委托給 springQueryApiBinder queryBinder = apiBinder.tryCast(QueryApiBinder.class);queryBinder.bindFinder(Finder.TYPE_SUPPLIER.apply(this));}/*** 注入數據源** @param* @param driver* @param username* @param password* @return*/private DruidDataSource getDataSource(String jdbcUrl, String driver, String username, String password) {DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl(jdbcUrl);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setDriverClassName(driver);// 用來檢測連接是否有效dataSource.setValidationQuery("SELECT 1");// 借用連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能dataSource.setTestOnBorrow(false);// 歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能dataSource.setTestOnReturn(false);// 連接空閑時檢測,如果連接空閑時間大于timeBetweenEvictionRunsMillis指定的毫秒,// 執行validationQuery指定的SQL來檢測連接是否有效// 如果檢測失敗,則連接將被從池中去除dataSource.setTestWhileIdle(true);dataSource.setTimeBetweenEvictionRunsMillis(60000);//1分鐘dataSource.setMaxActive(20);dataSource.setInitialSize(5);return dataSource;}
}

常用Spi實現

FxSqlCheckChainSpi,這里主要用來打印 sql

package com.demo.chain;import lombok.extern.slf4j.Slf4j;
import net.hasor.dataql.fx.db.FxSqlCheckChainSpi;
import net.hasor.utils.StringUtils;/*** @Classname FxSqlCheckChain* @Description 打印sql* @Date 2023/8/3 20:35* @Created by Leo825*/
@Slf4j
public class FxSqlCheckChain implements FxSqlCheckChainSpi {public static FxSqlCheckChain getInstance() {return new FxSqlCheckChain();}@Overridepublic int doCheck(FxSqlInfo fxSqlInfo) throws Throwable {String sourceName = fxSqlInfo.getSourceName();if (StringUtils.isNotEmpty(sourceName)) {log.info("【dataway】dataSource ==>:{}", sourceName);}log.info("【dataway】sql ==>:{}", fxSqlInfo.getQueryString().trim());log.info("【dataway】params ==>: {}", fxSqlInfo.getQueryParams());// 如果存在后續,那么繼續執行檢查,否則使用 EXIT 常量控制退出后續的檢查。return FxSqlCheckChainSpi.NEXT;}
}

PreExecuteChainSpi,這里主要是在接口執行前進行一些權限參數控制

package com.demo.chain;import lombok.extern.slf4j.Slf4j;
import net.hasor.dataway.spi.ApiInfo;
import net.hasor.dataway.spi.PreExecuteChainSpi;
import net.hasor.utils.future.BasicFuture;
import org.apache.commons.collections4.MapUtils;import java.util.HashMap;
import java.util.Map;/*** @Classname PreExecuteChain* @Description 接口執行前* @Date 2023/8/3 20:37* @Created by Leo825*/
@Slf4j
public class PreExecuteChain implements PreExecuteChainSpi {public static PreExecuteChain getInstance() {return new PreExecuteChain();}/*** sql 直接前* @param apiInfo* @param basicFuture*/@Overridepublic void preExecute(ApiInfo apiInfo, BasicFuture<Object> basicFuture) {Map<String, Object> parameter = apiInfo.getParameterMap();// 注入用戶權限參數parameter.putAll(MapUtils.emptyIfNull(loginUserAuthParams()));}/*** 獲取登錄用戶權限參數* @return*/private Map<String, Object> loginUserAuthParams () {Map<String, Object> authParams = new HashMap<>();// todo 注入登錄用戶 權限參數return authParams;}
}

ResultProcessChainSpi,主要是返回值進行一些封裝

package com.demo.chain;
import com.demo.common.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import net.hasor.dataway.spi.ApiInfo;
import net.hasor.dataway.spi.ResultProcessChainSpi;
/*** @Classname ReturnProcessChain* @Description 兼* 容 4.1.5之前 dataway版本 dataway 執行結果處理, 讓 structure 配置僅使用于   dataway頁面調試使用* @Date 2023/8/3 20:47* @Created by Leo825*/
@Slf4j
public class ResultProcessChain implements ResultProcessChainSpi {public static ResultProcessChain getInstance() {return new ResultProcessChain();}/*** 對返回結果進行處理* @param formPre* @param apiInfo* @param result* @return*/@Overridepublic Object callAfter(boolean formPre, ApiInfo apiInfo, Object result) {// apiInfo.isPerform() 為 true 表示,API 調用是從 UI 界面發起的。if (apiInfo.isPerform() || apiInfo.getParameterMap().containsKey("SELF_CALL")) {return result;}apiInfo.getOptionMap().put("resultStructure", false);return AjaxResult.success(result);}/*** 異常* @param formPre* @param apiInfo* @param e* @return*/@Overridepublic Object callError(boolean formPre, ApiInfo apiInfo, Throwable e) {if (apiInfo.isPerform()) {return ResultProcessChainSpi.super.callError(formPre, apiInfo, e);}apiInfo.getOptionMap().put("resultStructure", false);return AjaxResult.error( "系統繁忙");}
}

swagger 配置

package com.demo.config;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;import java.util.ArrayList;
import java.util.List;/*** swagger配置*/
@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider {@Overridepublic List<SwaggerResource> get() {List<SwaggerResource> resources = new ArrayList<>();resources.add(swaggerResource("應用接口", "/v2/api-docs", "1.0"));resources.add(swaggerResource("Dataway接口", "/interface-ui/api/docs/swagger2.json", "1.0"));return resources;}private SwaggerResource swaggerResource(String name, String location, String version) {SwaggerResource swaggerResource = new SwaggerResource();swaggerResource.setName(name);swaggerResource.setLocation(location);swaggerResource.setSwaggerVersion(version);return swaggerResource;}
}

將 Dataway 里面的接口發布到 swagger里面

package com.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** swagger配置*/
@EnableSwagger2
@Configuration()
public class SwaggerConfig {@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2)//.apiInfo(apiInfo())//.select()//.apis(RequestHandlerSelectors.basePackage("com.demo"))//.paths(PathSelectors.any())//.build();}private ApiInfo apiInfo() {return new ApiInfoBuilder()//.title("Spring Boot中使用Swagger2構建RESTful APIs")//.description("參考手冊:https://www.hasor.net/doc/display/dataql/")//.termsOfServiceUrl("https://www.hasor.net/doc/display/dataql/")//.contact("zyc@hasor.net").version("1.0")//.build();}
}

自定義 Udf

可以使用自定義udf,并且在管理頁面可以直接訪問

package com.demo.udf;import com.demo.config.SpringContextUtil;
import com.demo.service.MyUdfService;
import lombok.extern.slf4j.Slf4j;
import net.hasor.dataql.DimUdf;
import net.hasor.dataql.Hints;
import net.hasor.dataql.Udf;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** 自定義 udf,需要在 DatawayModule 添加以下配置代碼,否則會出現注入為 null 問題* // udf/udfSource/import 指令 的類型創建委托給 spring* QueryApiBinder queryBinder = apiBinder.tryCast(QueryApiBinder.class);* queryBinder.bindFinder(Finder.TYPE_SUPPLIER.apply(this));*/
@Slf4j
@DimUdf("myNameUdf")
@Service
public class MyNameUdf implements Udf {@Resourceprivate MyUdfService myUdfService;@Overridepublic Object call(Hints readOnly, Object... params) {log.info("獲取當前服務信息: " + myUdfService.myName());return "張三";}
}

web管理頁面調用方式如下:

import 'com.demo.udf.MyNameUdf' as myNameUdf;
return myNameUdf();

示意圖1

據官方文檔說可以通過 import ‘bean’ 方式引入,但是嘗試了沒有成功。

指定數據源進行查詢

主要通過 FRAGMENT_SQL_DATA_SOURCE 來指定數據源:

// springboot 整合Dataway 多數據源配置。使用示例:
hint FRAGMENT_SQL_DATA_SOURCE = "dataSource2";
var query = @@sql()<%select * from subjects
%>
return query()

測試2

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36709.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36709.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36709.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript應用:五子棋游戲實戰開發

&#x1f3c6;作者簡介&#xff0c;黑夜開發者&#xff0c;全棧領域新星創作者?&#xff0c;CSDN博客專家&#xff0c;阿里云社區專家博主&#xff0c;2023年6月csdn上海賽道top4。 &#x1f3c6;數年電商行業從業經驗&#xff0c;歷任核心研發工程師&#xff0c;項目技術負責…

面試熱題(螺旋矩陣)

給你一個 m 行 n 列的矩陣 matrix &#xff0c;請按照 順時針螺旋順序 &#xff0c;返回矩陣中的所有元素 一看到這個大家有沒有想到 就是一個螺旋形狀&#xff0c;那這道題我們應該怎么解決&#xff1f; 我們先來仔細的看&#xff0c;它這種螺旋形狀的遍歷是先【右-下-左-上】…

Docker中Tomcat部署步驟

第一次訪問沒有東西。

為什么我不推薦任何人用C語言作為編程啟蒙第一課?

前言 寫了20多年的代碼&#xff0c;之前做過阿里的高級架構師&#xff0c;在技術這條路上跌跌撞撞了很多&#xff0c;我今天分享一些我個人的自學方法給各位。為什么我會說&#xff1a;不推薦任何人用C語言作為編程啟蒙第一課&#xff1f; 這里有很多同學要站出來說了&#x…

實現CP指令

一、文件的打開創建 #include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags); flags: O_RDONLY 只讀 O_WRONLY 只寫 O_RDWR 可讀可寫 int open(const char *pathname, int flags, mode_t mode); 如果 …

VsCode美化 - VsCode自定義 - VsCode自定義背景圖

VsCode美化 - VsCode自定義 - VsCode自定義背景圖&#xff1a;添加二次元老婆圖到VsCode 前言 作為一個二刺螈&#xff0c;VsCode用久了&#xff0c;總覺得少了些什么。是啊&#xff0c;高效的代碼生產工具中怎么能沒有老婆呢&#xff1f; 那就安裝一個VsCode插件把老婆添加…

章節7:Burp Intruder模塊

章節7&#xff1a;Burp Intruder模塊 參考資料 https://portswigger.net/burp/documentation/desktop/tools/intruder 01 Intruder模塊作用與原理 原理 http://xxx.xx.com/bbs/index.php?namewuyanzu&mottogo 對請求參數進行修改&#xff0c;分析響應內容&#xff0…

Linux 內核第一版 (v0.01) 開源代碼解讀

探索Linux v0.01的內部結構&#xff0c;Linux內核經常被認為是一個龐大的開源軟件。在撰寫本文時&#xff0c;最新版本是v6.5-rc5&#xff0c;包含36M行代碼。不用說&#xff0c;Linux是幾十年來許多貢獻者辛勤工作的成果。 Linux 內核首個開源版本 (v0.01) 的體積非常小&…

四、Dubbo擴展點加載機制

四、Dubbo擴展點加載機制 4.1 加載機制概述 Dubbo良好的擴展性與框架中針對不同場景使用合適設計模式、加載機制密不可分 Dubbo幾乎所有功能組件都是基于擴展機制&#xff08;SPI&#xff09;實現的 Dubbo SPI 沒有直接使用 Java SPI&#xff0c;在它思想上進行改進&#xff…

競賽項目 深度學習的視頻多目標跟蹤實現

文章目錄 1 前言2 先上成果3 多目標跟蹤的兩種方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟蹤過程4.1 存在的問題4.2 基于軌跡預測的跟蹤方式 5 訓練代碼6 最后 1 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 基于深度學習的視頻多目標跟蹤實現 …

全網最牛,Appium自動化測試框架-關鍵字驅動+數據驅動實戰(二)

目錄&#xff1a;導讀 前言一、Python編程入門到精通二、接口自動化項目實戰三、Web自動化項目實戰四、App自動化項目實戰五、一線大廠簡歷六、測試開發DevOps體系七、常用自動化測試工具八、JMeter性能測試九、總結&#xff08;尾部小驚喜&#xff09; 前言 util 包 util 包…

數據可視化工具LightningChart .NET正式發布v10.5.1——擁有全新的3D新功能

LightningChart.NET完全由GPU加速&#xff0c;并且性能經過優化&#xff0c;可用于實時顯示海量數據-超過10億個數據點。 LightningChart包括廣泛的2D&#xff0c;高級3D&#xff0c;Polar&#xff0c;Smith&#xff0c;3D餅/甜甜圈&#xff0c;地理地圖和GIS圖表以及適用于科學…

網絡安全專業術語英文縮寫對照表

因在閱讀文獻過程中經常遇到各種專業縮寫&#xff0c;所以把各種縮寫總結了一下。 因能力有限&#xff0c;錯誤在所難免&#xff0c;歡迎進行糾錯與補充&#xff1a;https://github.com/piaolin/CSAbbr 滲透相關 縮寫全稱解釋備注XSSCross Site Script Attack跨站腳本攻擊為…

ResNet創新點總結

ResNet&#xff08;Residual Networks&#xff09;是深度學習中的一個重要架構&#xff0c;其創新點主要體現在解決了深層神經網絡訓練中的梯度消失和梯度爆炸問題&#xff0c;從而使得可以構建更深的神經網絡。以下是 ResNet 的創新點總結&#xff1a; ??1. 殘差連接&#x…

nlohmann json:通過items遍歷object/array

//官方的例子 #include <iostream> #include <nlohmann/json.hpp>using json = nlohmann::json;int main() {// create JSON valuesjson j_object = {{"one", 1}, {"two", 2}};json j_array = {1, 2, 4, 8, 16};// example for an objectfor (…

java畢業設計-智慧食堂管理系統-內容快覽

首頁 智慧食堂管理系統是一種可以提高食堂運營效率的管理系統。它將前端代碼使用Vue實現&#xff0c;后端使用Spring Boot實現。這個系統的目的是簡化食堂管理&#xff0c;提高食堂服務質量。在現代快節奏的生活中&#xff0c;人們對餐飲服務提出了更高的要求&#xff0c;食堂管…

Flink-間隔聯結

間隔聯結只支持事件時間間隔聯結如果遇到遲到數據&#xff0c;則會關聯不上&#xff0c;比如來了一個5秒的數據&#xff0c;它可以關聯前2秒的數據&#xff0c;后3秒的數據&#xff0c;就是可以關聯3秒到8秒的數據&#xff0c;然后又來了一個6秒的數據&#xff0c;可以關聯4秒到…

Docker安裝elasticsearch分布式搜索

文章目錄 ??安裝elasticsearch??1.部署單點es&#x1f338;1.1.創建網絡&#x1f338;1.2.下載鏡像&#x1f338;1.3.運行 ??2.部署kibana&#x1f338;2.1.部署&#x1f338;2.2.DevTools ??3.安裝IK分詞器&#x1f338;3.1.在線安裝ik插件&#xff08;較慢&#xff0…

Rx.NET in Action 中文介紹 前言及序言

Rx 處理器目錄 (Catalog of Rx operators) 目標可選方式Rx 處理器(Operator)創建 Observable Creating Observables直接創建 By explicit logicCreate Defer根據范圍創建 By specificationRangeRepeatGenerateTimerInterval Return使用預設 Predefined primitivesThrow …

答疑:Arduino IDE配置其他開發板下載速度慢

基于案例&#xff1a;Linux環境Arduino IDE中配置ATOM S3 通常&#xff0c;網絡問題較多&#xff0c;可以使用一些技巧。 https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json 沒有配置&#xff0c;不支持M5Stack&#xff08;ESP32&…