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.mzph.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;简介 蓝牙技术是一种无线数据和…

Camunda BPM架构

Camunda BPM既可以单独作为流程引擎服务存在,也能嵌入到其他java应用中。Camunda BPM的核心流程引擎是一个轻量级的模块,可以被Spring管理或者加入到自定义的编程模型中,并且支持线程模型。 1,流程引擎架构 流程引擎由多个组件构成,如下所示: API服务 API服务,允许ja…

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

随着夏日的热烈与儿童节的欢乐氛围到来&#xff0c;蒙自源品牌隆重推出儿童餐新品&#xff0c;以“快乐不分大小&#xff0c;谁还不是个宝宝”为主题&#xff0c;为广大消费者带来一场健康与美味的盛宴。新品上市活动将于5月25日举行&#xff0c;蒙自源将以其独特的产品魅力和创…

最新 HUAWEI DevEco Studio 调试技巧

最新 HUAWEI DevEco Studio 调试技巧 前言 在我们使用 HUAWEI DevEco Studio 编辑器开发鸿蒙应用时&#xff0c;免不了要对我们的应用程序进行代码调试。我们根据实际情况&#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;除…

让表单引擎插上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…

618大促有哪些好物是最值得入手的的?请收下这份618必买好物清单!

最近聊的最多的话题就是618&#xff0c;年中购物大狂欢马上来了&#xff01;&#xff01;今天整理了一下之前购买的好物&#xff0c;发现相比之前的价格真的是太划算了&#xff0c;赶紧分享出来给大家&#xff0c;趁着这个大促赶紧多存入手~ 推荐1、南卡Neo 2——不伤耳黑科技…

SPHINX的输出文档格式

SPHINX的输出文档格式 SPHINX的输出文档格式更多信息 SPHINX的输出文档格式 用rst编写&#xff0c;然后用sphinx-build进行编译&#xff0c;还是效果相当不错地&#xff0c;只要掌握了格式&#xff0c;可以一次编译&#xff0c;多种格式输出&#xff0c;主要是用的可能是html和…

记一次netty客户端的开发

背景 近日要开发一个tcp客户端程序去对接上游厂商的数据源&#xff0c;决定使用netty去处理&#xff0c;由于很久没有开发过netty了&#xff0c;顺便学习记录下 netty搭建 考虑到我们需要多个client去对接server服务&#xff0c;所以我们定义一个公共的AbstractNettyClient父…

LabVIEW与Arm控制器之间的通讯

LabVIEW是一个强大的图形化编程环境&#xff0c;广泛应用于自动化控制、数据采集和测试测量等领域。而Arm控制器则是嵌入式系统中常用的处理器架构&#xff0c;广泛用于各种控制和计算任务。将LabVIEW与Arm控制器进行通讯控制&#xff0c;可以结合二者的优势&#xff0c;实现高…

WordPress plugin MStore API SQL注入漏洞复现(CVE-2023-3077)

0x01 产品简介 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 0x02 漏洞概述 WordPress plugin MStore API 3.9.8 版本之前存在S…

Linux 深入讲解自动化构建工具

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Linux一系列的文章&#xff08;质量分均在93分…

配置arduino和ESP8266

首先准备好arduino 的IDE和ESP8266的驱动以及板子 1.安装驱动&#xff0c;双击x64的版本驱动&#xff0c;安装好以后&#xff0c;在资源管理器检查端口&#xff0c;比如下下图出现的COM4就是esp8266所使用的端口 2.安装好arduino最好不要在路径中存在中文符号&#xff0c;打开…

水滴式粉碎机:多功能饲料粉碎设备

饲料粉碎机是一种专门用于将各种饲料原料进行粉碎处理的机械设备。无论是玉米、小麦等谷物&#xff0c;还是豆粕、鱼粉等动物性原料&#xff0c;甚至是一些粗纤维含量较高的秸秆、牧草等&#xff0c;都可以经过饲料粉碎机的处理&#xff0c;变成适合畜禽消化吸收的精细饲料。这…