springboot結合mybatis使用多數據源的方式

? 背景? ? ??

????????最近有一個需求,有兩個庫需要做同步數據,一個Doris庫,一個mysql庫,兩邊的表結構一致,這里不能使用navicat等工具提供的數據傳輸之類的功能,只能使用代碼做同步,springboot配置多數據源的方式在這里有示例:CSDNicon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/132598605

?方式一:不同的庫對應不同的mapper

項目結構示例

?數據庫bank1配置

package com.example.springbootmybatisdiffdatasource.config;import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;/*** bank1配置* @Author wzw* @Date 2024/5/27 19:29* @Version 1.0* @Description todo*/
@Configuration
@MapperScan(basePackages = "com.example.springbootmybatisdiffdatasource.mapper.bank1",sqlSessionFactoryRef ="bank1SqlSessionFactory" )
public class Bank1Config {/*** 本地mysql的bank1庫的數據配置* @return*/@Bean@ConfigurationProperties(prefix = "spring.datasource.bank1")public DataSourceProperties bank1SourceProperties() {return new DataSourceProperties();}/*** 初始化數據源* @return*/@Bean("bank1DataSource")public DataSource bank1DataSource() {return bank1SourceProperties().initializeDataSourceBuilder().build();}/*** 創建session工廠* @param dataSource* @return org.apache.ibatis.session.SqlSessionFactory* @author: wzw* @date: 2024/5/27 19:37*/@Bean("bank1SqlSessionFactory")public SqlSessionFactory bank1SqlSessionFactory(@Qualifier("bank1DataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//設置數據源sqlSessionFactoryBean.setDataSource(dataSource);//設置mapper掃描路徑sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/bank1/*.xml"));return sqlSessionFactoryBean.getObject();}
}

數據庫bank2配置?

package com.example.springbootmybatisdiffdatasource.config;import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import javax.sql.DataSource;/*** bank2配置* @Author wzw* @Date 2024/5/27 19:38* @Version 1.0* @Description todo*/
@Configuration
@MapperScan(basePackages = "com.example.springbootmybatisdiffdatasource.mapper.bank2",sqlSessionFactoryRef ="bank2SqlSessionFactory" )
public class Bank2Config {/*** 本地mysql的bank1庫的數據配置* @return*/@Bean@ConfigurationProperties(prefix = "spring.datasource.bank2")public DataSourceProperties bank2SourceProperties() {return new DataSourceProperties();}/*** 初始化數據源* @return*/@Bean("bank2DataSource")public DataSource bank2DataSource() {return bank2SourceProperties().initializeDataSourceBuilder().build();}/*** 創建session工廠* @param dataSource* @return org.apache.ibatis.session.SqlSessionFactory* @author: wzw* @date: 2024/5/27 19:37*/@Bean("bank2SqlSessionFactory")public SqlSessionFactory bank2SqlSessionFactory(@Qualifier("bank2DataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//設置數據源sqlSessionFactoryBean.setDataSource(dataSource);//設置mapper掃描路徑sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/bank2/*.xml"));return sqlSessionFactoryBean.getObject();}
}

配置依賴數據庫配置

spring.application.name=springboot-mybatis-diffdatasource
server.port=8888

spring.datasource.bank1.url=jdbc:mysql://localhost:3306/bank1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.bank1.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.bank1.username=root
spring.datasource.bank1.password=123456

spring.datasource.bank2.url=jdbc:mysql://localhost:3306/bank2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.bank2.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.bank2.username=root
spring.datasource.bank2.password=123456

實體類?

package com.example.springbootmybatisdiffdatasource.entity;import lombok.Data;import java.sql.Timestamp;/*** 數據庫實體映射* @Author wzw* @Date 2024/5/27 19:44* @Version 1.0* @Description todo*/
@Data
public class DeDuplication {/*** 日志號*/private String txNo;/*** 創建時間*/private Timestamp createTime;}

bank1查詢接口

package com.example.springbootmybatisdiffdatasource.mapper.bank1;import com.example.springbootmybatisdiffdatasource.entity.DeDuplication;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** @Author wzw* @Date 2024/5/27 19:43* @Version 1.0* @Description todo*/
@Mapper
public interface DeDuplication1Mapper {/*** 查詢所有數據* @param * @return java.util.List<com.example.springbootmybatisdiffdatasource.entity.DeDuplication>* @author: wzw* @date: 2024/5/27 19:54*/List<DeDuplication> selectAll();
}

bank2批量插入接口

package com.example.springbootmybatisdiffdatasource.mapper.bank2;import com.example.springbootmybatisdiffdatasource.entity.DeDuplication;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** @Author wzw* @Date 2024/5/27 19:43* @Version 1.0* @Description todo*/
@Mapper
public interface DeDuplication2Mapper {/*** 批量插入* @param list* @return java.lang.Integer* @author: wzw* @date: 2024/5/27 19:57*/Integer batchInsert(@Param("list") List<DeDuplication> list);
}

bank1庫示例表的xml

<?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.example.springbootmybatisdiffdatasource.mapper.bank1.DeDuplication1Mapper"><resultMap id="base" type="com.example.springbootmybatisdiffdatasource.entity.DeDuplication"><result column="tx_no" property="txNo"/><result column="create_time" property="createTime"/></resultMap><select id="selectAll" resultMap="base">select * from de_duplication</select></mapper>

bank2庫示例表的xml

<?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.example.springbootmybatisdiffdatasource.mapper.bank2.DeDuplication2Mapper"><insert id="batchInsert">insert into de_duplication(tx_no,create_time)values<foreach collection="list" item="a" separator=",">(#{a.txNo},#{a.createTime})</foreach></insert></mapper>

測試

package com.example.springbootmybatisdiffdatasource.test;import com.example.springbootmybatisdiffdatasource.entity.DeDuplication;
import com.example.springbootmybatisdiffdatasource.mapper.bank1.DeDuplication1Mapper;
import com.example.springbootmybatisdiffdatasource.mapper.bank2.DeDuplication2Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** 測試類* @Author wzw* @Date 2024/5/27 20:02* @Version 1.0* @Description todo*/
@RestController
public class TestController {@Autowiredprivate DeDuplication1Mapper deDuplication1Mapper;@Autowiredprivate DeDuplication2Mapper deDuplication2Mapper;@GetMapping("test")public void test(){List<DeDuplication> deDuplications = deDuplication1Mapper.selectAll();System.out.printf("個數:%d%n",deDuplications.size());deDuplication2Mapper.batchInsert(deDuplications);System.out.println("批量插入成功");}
}

bank1中的數據

bank2中目前是空的

運行測試方法

刷新bank2

至此方式一解決了不同庫數據同步問題,但是有個問題需要考慮 ,示例是寫一張表,如果寫入成百上千張表呢,mapper是不是要double,這里采用動態路由的方式切換數據源,如下

方式二:動態切換數據源(不同庫使用同一個mapper)

項目結構示例

動態數據源配置

package com.example.springbootmybatisdiffdatasource.twoway.config;import com.example.springbootmybatisdiffdatasource.twoway.constant.DataSourceEnum;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;/*** 同時配置bank1和bank2** @Author wzw* @Date 2024/5/28 10:28* @Version 1.0* @Description todo*/
@Configuration
//掃描mapper,兩個庫共用一個mapper,因為表結構是一致的
@MapperScan(basePackages = "com.example.springbootmybatisdiffdatasource.twoway.mapper")
public class DoubleDataSourceConfig {/*** 本地mysql的bank1庫的數據配置** @return*/@Bean@ConfigurationProperties(prefix = "spring.datasource.bank1")public DataSourceProperties bank1SourceProperties() {return new DataSourceProperties();}/*** bank1初始化** @return*/@Bean("bank1DataSource")public DataSource bank1DataSource() {return bank1SourceProperties().initializeDataSourceBuilder().build();}/*** bank2庫的數據配置** @return*/@Bean@ConfigurationProperties(prefix = "spring.datasource.bank2")public DataSourceProperties bank2SourceProperties() {return new DataSourceProperties();}/*** bank2初始化** @return*/@Bean("bank2DataSource")public DataSource bank2DataSource() {return bank2SourceProperties().initializeDataSourceBuilder().build();}/*** 配置動態數據源** @param bank1* @param bank2* @return com.example.springbootmybatisdiffdatasource.twoway.config.DynamicToggleDataSource* @author: wzw* @date: 2024/5/28 10:56*/@Bean("dynamicToggleDataSource")public DynamicToggleDataSource dynamicToggleDataSource(@Qualifier("bank1DataSource") DataSource bank1,@Qualifier("bank2DataSource") DataSource bank2) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceEnum.BANK1, bank1);targetDataSources.put(DataSourceEnum.BANK2, bank2);DynamicToggleDataSource dynamicDataSource = new DynamicToggleDataSource();//數據源集合dynamicDataSource.setTargetDataSources(targetDataSources);//默認查詢數據庫bank1dynamicDataSource.setDefaultTargetDataSource(bank1);return dynamicDataSource;}/*** 創建session工廠* @param dataSource* @return org.apache.ibatis.session.SqlSessionFactory* @author: wzw* @date: 2024/5/27 19:37*/@Bean("sqlSessionFactory")public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicToggleDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//設置數據源sqlSessionFactoryBean.setDataSource(dataSource);//設置mapper掃描路徑sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/twoway/*.xml"));return sqlSessionFactoryBean.getObject();}
}

package com.example.springbootmybatisdiffdatasource.twoway.config;import com.example.springbootmybatisdiffdatasource.twoway.constant.DataSourceEnum;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/*** 動態切換數據源,使用* @Author wzw* @Date 2024/5/28 10:35* @Version 1.0* @Description todo*/
public class DynamicToggleDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceType();}public static class DataSourceContextHolder {private static final ThreadLocal<DataSourceEnum> contextHolder = new ThreadLocal<>();public static void setDataSourceType(DataSourceEnum type) {contextHolder.set(type);}public static DataSourceEnum getDataSourceType() {return contextHolder.get();}public static void clearDataSourceType() {contextHolder.remove();}}
}

數據源枚舉

package com.example.springbootmybatisdiffdatasource.twoway.constant;import lombok.AllArgsConstructor;/*** 數據庫枚舉* @Author wzw* @Date 2024/5/28 10:39* @Version 1.0* @Description todo*/
@AllArgsConstructor
public enum DataSourceEnum {BANK1("mysql_bank1"),BANK2("mysql_bank2");private String dataSourceName;public String getDataSourceName() {return dataSourceName;}public void setDataSourceName(String dataSourceName) {this.dataSourceName = dataSourceName;}
}

表mapper

package com.example.springbootmybatisdiffdatasource.twoway.mapper;import com.example.springbootmybatisdiffdatasource.entity.DeDuplication;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** @Author wzw* @Date 2024/5/27 19:43* @Version 1.0* @Description todo*/
@Mapper
public interface DeDuplicationMapper {/*** 查詢所有數據* @param * @return java.util.List<com.example.springbootmybatisdiffdatasource.entity.DeDuplication>* @author: wzw* @date: 2024/5/27 19:54*/List<DeDuplication> selectAll();/*** 批量插入* @param list* @return java.lang.Integer* @author: wzw* @date: 2024/5/27 19:57*/Integer batchInsert(@Param("list") List<DeDuplication> list);
}

xml

<?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.example.springbootmybatisdiffdatasource.twoway.mapper.DeDuplicationMapper"><resultMap id="base" type="com.example.springbootmybatisdiffdatasource.entity.DeDuplication"><result column="tx_no" property="txNo"/><result column="create_time" property="createTime"/></resultMap><select id="selectAll" resultMap="base">select * from de_duplication</select><insert id="batchInsert">insert into de_duplication(tx_no,create_time)values<foreach collection="list" item="a" separator=",">(#{a.txNo},#{a.createTime})</foreach></insert></mapper>

測試

package com.example.springbootmybatisdiffdatasource.test;import com.example.springbootmybatisdiffdatasource.entity.DeDuplication;
import com.example.springbootmybatisdiffdatasource.twoway.config.DynamicToggleDataSource;
import com.example.springbootmybatisdiffdatasource.twoway.constant.DataSourceEnum;
import com.example.springbootmybatisdiffdatasource.twoway.mapper.DeDuplicationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;/*** 測試類* @Author wzw* @Date 2024/5/27 20:02* @Version 1.0* @Description todo*/
@RestController
public class TestController {@Autowiredprivate DeDuplicationMapper deDuplicationMapper;@GetMapping("test")public void test(){List<DeDuplication> deDuplications = deDuplicationMapper.selectAll();System.out.printf("個數:%d%n",deDuplications.size());//  切換數據源DynamicToggleDataSource.DataSourceContextHolder.setDataSourceType(DataSourceEnum.BANK2);deDuplicationMapper.batchInsert(deDuplications);System.out.println("批量插入成功");}
}

測試結果跟上面一致,但是還會有一個問題:動態切換數據源在表很多的前提下還是會增大系統開銷,浪費系統資源

方式三:使用SqlSessionTemplate指向不同的數據源(也是使用同一個mapper)

項目結構示例

動態數據源配置

package com.example.springbootmybatisdiffdatasource.threeway.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;/*** bank1配置* @Author wzw* @Date 2024/5/27 19:29* @Version 1.0* @Description todo*/
@Configuration
@MapperScan(basePackages = "com.example.springbootmybatisdiffdatasource.threeway.mapper",sqlSessionTemplateRef ="bank1SqlSessionTemplate" )
public class Bank1Config {/*** 本地mysql的bank1庫的數據配置* @return*/@Bean@ConfigurationProperties(prefix = "spring.datasource.bank1")public DataSourceProperties bank1SourceProperties() {return new DataSourceProperties();}/*** 初始化數據源* @return*/@Bean("bank1DataSource")public DataSource bank1DataSource() {return bank1SourceProperties().initializeDataSourceBuilder().build();}/*** 創建session工廠* @param dataSource* @return org.apache.ibatis.session.SqlSessionFactory* @author: wzw* @date: 2024/5/27 19:37*/@Bean("bank1SqlSessionFactory")public SqlSessionFactory bank1SqlSessionFactory(@Qualifier("bank1DataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//設置數據源sqlSessionFactoryBean.setDataSource(dataSource);//設置mapper掃描路徑sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/threeway/*.xml"));return sqlSessionFactoryBean.getObject();}/*** bank1的事務管理器* @param dataSource* @return org.springframework.transaction.PlatformTransactionManager* @author: wzw* @date: 2024/5/28 11:55*/@Bean(name = "bank1TransactionManager")public PlatformTransactionManager bank1TransactionManager(@Qualifier("bank1DataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}/*** bank1的sql模板* @param sqlSessionFactory* @return org.mybatis.spring.SqlSessionTemplate* @author: wzw* @date: 2024/5/28 11:55*/@Bean(name = "bank1SqlSessionTemplate")public SqlSessionTemplate bank1SqlSessionTemplate(@Qualifier("bank1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}
}
package com.example.springbootmybatisdiffdatasource.threeway.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;/*** bank2配置* @Author wzw* @Date 2024/5/27 19:38* @Version 1.0* @Description todo*/
@Configuration
@MapperScan(basePackages = "com.example.springbootmybatisdiffdatasource.threeway.mapper",sqlSessionTemplateRef ="bank2SqlSessionTemplate" )
public class Bank2Config {/*** 本地mysql的bank2庫的數據配置* @return*/@Bean@ConfigurationProperties(prefix = "spring.datasource.bank2")public DataSourceProperties bank2SourceProperties() {return new DataSourceProperties();}/*** 初始化數據源* @return*/@Bean("bank2DataSource")public DataSource bank2DataSource() {return bank2SourceProperties().initializeDataSourceBuilder().build();}/*** 創建session工廠* @param dataSource* @return org.apache.ibatis.session.SqlSessionFactory* @author: wzw* @date: 2024/5/27 19:37*/@Bean("bank2SqlSessionFactory")public SqlSessionFactory bank2SqlSessionFactory(@Qualifier("bank2DataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//設置數據源sqlSessionFactoryBean.setDataSource(dataSource);//設置mapper掃描路徑sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/threeway/*.xml"));return sqlSessionFactoryBean.getObject();}/*** bank2的事務管理器* @param dataSource* @return org.springframework.transaction.PlatformTransactionManager* @author: wzw* @date: 2024/5/28 11:55*/@Bean(name = "bank2TransactionManager")public PlatformTransactionManager bank2TransactionManager(@Qualifier("bank2DataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}/*** bank1的sql模板* @param sqlSessionFactory* @return org.mybatis.spring.SqlSessionTemplate* @author: wzw* @date: 2024/5/28 11:55*/@Bean(name = "bank2SqlSessionTemplate")public SqlSessionTemplate bank2SqlSessionTemplate(@Qualifier("bank2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}
}

?

表mapper、xml和上面一樣

測試

package com.example.springbootmybatisdiffdatasource.test;import com.example.springbootmybatisdiffdatasource.entity.DeDuplication;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;/*** 測試類* @Author wzw* @Date 2024/5/27 20:02* @Version 1.0* @Description todo*/
@RestController
public class TestController {@Autowired@Qualifier("bank1SqlSessionTemplate")private SqlSessionTemplate bank1Template;@Autowired@Qualifier("bank2SqlSessionTemplate")private SqlSessionTemplate bank2Template;@GetMapping("test")public void test(){List<DeDuplication> deDuplications =bank1Template.selectList("com.example.springbootmybatisdiffdatasource.threeway.mapper.DeDuplicationMapper.selectAll");System.out.printf("個數:%d%n",deDuplications.size());bank2Template.insert("com.example.springbootmybatisdiffdatasource.threeway.mapper.DeDuplicationMapper.batchInsert",deDuplications);System.out.println("批量插入成功");}
}

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

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

相關文章

如何設置手機的DNS

DNS 服務器 IP 地址 蘋果 華為 小米 OPPO VIVO DNS 服務器 IP 地址 中國大陸部分地區會被運營商屏蔽網絡導致無法訪問&#xff0c;可修改手機DNS解決。 推薦 阿里的DNS (223.5.5.5&#xff09;或 114 (114.114.114.114和114.114.115.115) 更多公開DNS參考&#xff1a; 蘋果…

ESP32-C3模組上實現藍牙BLE配網功能(1)

本文內容參考&#xff1a; 《ESP32-C3 物聯網工程開發實戰》 樂鑫科技 藍牙的名字由來是怎樣的&#xff1f;為什么不叫它“白牙”&#xff1f; 特此致謝&#xff01; 一、藍牙知識基礎 1. 什么是藍牙&#xff1f; &#xff08;1&#xff09;簡介 藍牙技術是一種無線數據和…

【緩存】OS層面緩存設計機制

操作系統的緩存設計機制是計算機體系結構中的一個重要組成部分&#xff0c;旨在提高系統的性能&#xff0c;特別是通過減少對慢速存儲設備&#xff08;如硬盤&#xff09;的訪問次數來加速數據的讀取和寫入。 以下是一些常見的操作系統緩存設計機制&#xff1a; CPU緩存&…

web學習筆記(六十一)

目錄 如何使用公共組件來編寫頁面 如何使用公共組件來編寫頁面 1.導入公共組件nav.vue import Catenav from "/components/nav.vue"; 2.在頁面插入子組件 如果使用了setup語法糖此時就可以直接在頁面插入 <Catenav ></Catenav>標簽&#xff0c; …

.NET 快速重構概要1

1.封裝集合 在某些場景中,向類的使用者隱藏類中的完整集合是一個很好的做法,比如對集合的 add/remove 操作中包 含其他的相關邏輯時。因此,以可迭代但不直接在集合上進行操作的方式來暴露集合,是個不錯的主意。 public class Order { private int _orderTotal; private Li…

Camunda BPM架構

Camunda BPM既可以單獨作為流程引擎服務存在,也能嵌入到其他java應用中。Camunda BPM的核心流程引擎是一個輕量級的模塊,可以被Spring管理或者加入到自定義的編程模型中,并且支持線程模型。 1,流程引擎架構 流程引擎由多個組件構成,如下所示: API服務 API服務,允許ja…

邏輯回歸分類算法

文章目錄 算法推導 線性回歸解決連續值的回歸預測&#xff1b;而邏輯回歸解決離散值的分類預測&#xff1b; 算法推導 邏輯回歸可以看作是兩部分&#xff0c;以0、1分類問題說明&#xff1b; 線性回歸部分 對于一個樣本 x i x_i xi?&#xff0c;有n個特征 x i ( 1 ) x_i^{(1)…

蒙自源兒童餐新品上市,引領健康美味新潮流

隨著夏日的熱烈與兒童節的歡樂氛圍到來&#xff0c;蒙自源品牌隆重推出兒童餐新品&#xff0c;以“快樂不分大小&#xff0c;誰還不是個寶寶”為主題&#xff0c;為廣大消費者帶來一場健康與美味的盛宴。新品上市活動將于5月25日舉行&#xff0c;蒙自源將以其獨特的產品魅力和創…

install

目錄 1、 install 1.1、 //creates form with validation 1.2、 onStepChanging: function (event, currentIndex, newIndex) { 1.3、 onFinishing: function (event, currentIndex) { 1.4、 //init inst

最新 HUAWEI DevEco Studio 調試技巧

最新 HUAWEI DevEco Studio 調試技巧 前言 在我們使用 HUAWEI DevEco Studio 編輯器開發鴻蒙應用時&#xff0c;免不了要對我們的應用程序進行代碼調試。我們根據實際情況&#xff0c;一般會用到以下三種方式進行代碼調試。 肉眼調試法注釋排錯調試法控制臺輸出法彈出提示法斷…

【算法實戰】每日一題:將某個序列中內的每個元素都設為相同的值的最短次數(差分數組解法,附概念理解以及實戰操作)

題目 將某個序列中內的每個元素都設為相同的值的最短次數 1.差分數組&#xff08;后面的減去前面的值存儲的位置可以理解為中間&#xff09; 差分數組用于處理序列中的區間更新和查詢問題。它存儲序列中相鄰元素之間的差值&#xff0c;而不是直接存儲每個元素的值 怎么對某…

STM32 入門教程(江科大教材)#筆記2

3-4按鍵控制LED /** LED.c**/ #include "stm32f10x.h" // Device headervoid LED_Init(void) {/*開啟時鐘*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開啟GPIOA的時鐘/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_I…

關系數據庫:關系運算

文章目錄 關系運算并&#xff08;Union&#xff09;差&#xff08;Difference&#xff09;交&#xff08;Intersection&#xff09;笛卡爾積&#xff08;Extended Cartesian Product&#xff09;投影&#xff08;projection&#xff09;選擇&#xff08;Selection&#xff09;除…

微信小程序中應用van-calendar時加載時間過長,以及設置min-data無效的問題解決

一、我們微信小程序中應用van-calendar時&#xff0c;如果沒有設置min-data&#xff0c;那么頁面的加載時間會非常長&#xff0c;所以&#xff0c;一定一定要配置min-data&#xff1b; 二、vue中min-data的寫法是:min-data“new Date(2023, 0, 1)”&#xff0c;而在小程序中的寫…

docker使用docker logs命令查看容器日志的幾種方式

以下是如何使用docker logs命令的基本示例&#xff1a; docker logs [容器ID或名稱]如果想要實時查看日志&#xff0c;可以加上-f參數&#xff0c;這樣日志就會像使用tail -f命令一樣實時輸出。 docker logs -f [容器ID或名稱]如果只想查看最近幾行的日志&#xff0c;可以使用…

讓表單引擎插上AI的翅膀-記馳騁表單引擎加入AI升級

讓表單引擎插上AI的翅膀 隨著科技的飛速發展&#xff0c;人工智能&#xff08;AI&#xff09;已經逐漸滲透到我們工作和生活的每一個角落。在數字化辦公領域&#xff0c;表單引擎作為數據處理和流程自動化的重要工具&#xff0c;也迎來了與AI技術深度融合的新機遇。讓表單引擎…

Java對象的比較——equals方法,Comparable接口,Comparator接口

Java對象的比較——equals方法&#xff0c;Comparable接口&#xff0c;Comparator接口 1. equals方法2. Comparable接口3. Comparator接口 1. equals方法 在判斷兩個整數是否相同時&#xff0c;我們可以使用以下方式&#xff1a; System.out.println(1 2); System.out.printl…

安防綜合管理系統EasyCVR平臺GA/T1400視圖庫:基于XML的消息體格式

GA/T 1400標準的應用范圍廣泛&#xff0c;涵蓋了公安系統的視頻圖像信息應用系統&#xff0c;如警務綜合平臺、治安防控系統、交通管理系統等。在視頻監控系統中&#xff0c;GA/T 1400公安視圖庫的對接是實現視頻圖像信息傳輸、處理和管理的重要環節。 以視頻匯聚EasyCVR視頻監…

【SpringBoot】怎么在一個大的SpringBoot項目中創建多個小的SpringBoot項目,從而形成子父依賴

父子項目工程創建 步驟 先創建父項目 具體操作步驟請看本文章&#xff1a;使用maven工程創建spring boot項目 創建子項目 file- project structure module–new module 剩下步驟請看創建父工程時的操作使用maven工程創建spring boot項目 應用 確認即可 之后創建啟動類…

ARM32開發——LED驅動開發

&#x1f3ac; 秋野醬&#xff1a;《個人主頁》 &#x1f525; 個人專欄:《Java專欄》《Python專欄》 ??心若有所向往,何懼道阻且長 文章目錄 需求介紹現實問題需求分析測試案例構建BSP驅動構建業務實現 需求介紹 開發版中有4個燈&#xff0c;現在需要用4個燈顯示充電情況&a…