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

【springboot】 多数据源实现

文章目录

      • 1. 引言:多数据源的必要性和应用场景
        • **为什么需要多数据源?**
        • **应用场景**
      • 2. Spring Boot中的数据源配置
        • 2.1 默认数据源配置简介
        • 2.2 如何在Spring Boot中配置多个数据源
      • 3. 整合MyBatis与多数据源
        • **配置MyBatis使用多数据源**
        • **Mapper接口的数据源指定**
      • 4. 数据源的动态路由
        • 4.1 什么是数据源路由?
        • 4.2 实现一个简单的动态数据源路由
      • 5. 事务管理配置
        • **如何管理多数据源下的事务**
        • **配置全局事务和局部事务**
      • 6. 实战示例:完整的多数据源配置示例
        • 示例概述
        • **步骤 1: 添加依赖**
        • **步骤 2: 配置数据源**
        • **步骤 3: 配置数据源 Bean 和 MyBatis**
        • **步骤 4: 动态数据源路由**
        • **步骤 5: 配置和使用**
      • 7. 简化多数据源管理-**dynamic**
        • 功能和特点
        • 应用场景
          • 引入依赖
          • 配置多数据源
          • 使用 @DS 注解
            • 在方法上使用
            • 在类上使用
            • 注意事项

1. 引言:多数据源的必要性和应用场景

在现代软件开发中,随着业务的复杂性增加和数据量的急剧膨胀,一个应用可能需要同时访问多种数据库来满足不同的数据处理需求。例如,一个电子商务系统可能需要一个数据库来处理交易数据,另一个数据库来分析用户行为。这就是多数据源配置的必要性所在。

为什么需要多数据源?
  1. 业务逻辑分离:不同的数据库可以承载不同的业务模块,例如,订单处理和用户分析可以分别在不同的数据库中进行,使得业务更加清晰,同时提高系统的可维护性。
  2. 性能优化:通过分散请求到专门的数据库,可以避免单一数据库因请求过多而成为性能瓶颈,从而提高整个应用的性能。
  3. 数据安全和隔离:敏感数据可以单独存储在更加安全的数据库中,普通数据则可以在常规安全级别的数据库中处理,从而提高数据安全性。
  4. 技术多样性:不同的数据库技术(如关系型数据库和非关系型数据库)有其特定优势,多数据源配置允许在一个项目中利用各种数据库技术的优势。
应用场景
  1. 大数据分析与实时业务系统并行:在很多企业级应用中,通常需要将实时业务数据库和大数据分析数据库分开管理,以免复杂的数据分析操作影响到核心业务系统的性能。
  2. 微服务架构:在微服务架构中,各个微服务可能需要独立的数据库实例,以保持服务的自治性和解耦。
  3. 遗留系统整合:在新旧系统整合过程中,可能需要同时接入新旧系统的数据库,以保证数据的完整性和一致性。
  4. 跨地域数据处理:全球化业务可能需要在不同地域部署数据库,以减少数据访问延迟和符合地域数据法规。

通过这些场景,我们可以看出,多数据源的配置不仅是一种技术需求,更是业务发展和数据管理策略的一部分。

2. Spring Boot中的数据源配置

Spring Boot极大地简化了Java应用的数据库连接和操作。它通过自动配置支持快速启动和运行,但在处理多数据源时,需要进行一些额外的配置。以下是如何在Spring Boot中配置单个默认数据源以及如何扩展到多数据源的详细说明。

2.1 默认数据源配置简介

在Spring Boot中,配置一个默认的数据源非常简单。你只需要在application.propertiesapplication.yml文件中添加相关的数据库连接配置即可。Spring Boot使用这些属性自动配置数据源和JPA或JDBC模板。

示例 - application.properties配置:

spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=myuser
spring.datasource.password=mypass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

这些配置告诉Spring Boot如何连接到数据库,并使用哪个JDBC驱动。Spring Boot支持大多数主流数据库,并自动配置连接池(默认是HikariCP)。

2.2 如何在Spring Boot中配置多个数据源

配置多个数据源需要更多的手动设置。你需要定义每个数据源的配置,并确保Spring Boot能够正确地区分和管理它们。以下是配置多数据源的步骤:

步骤 1: 定义数据源配置

首先,你需要在配置文件中为每个数据源定义不同的前缀。例如:

# 主数据源
spring.datasource.primary.url=jdbc:mysql://localhost:3306/primary_db
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver# 辅助数据源
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/secondary_db
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver

步骤 2: 创建数据源配置类

你需要创建配置类来加载和区分这些数据源。每个数据源都应该有自己的配置类和@Bean定义。

@Configuration
public class DataSourceConfig {@Bean(name = "primaryDataSource")@Primary@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}
}

在这个配置中,@Primary注解标记了主数据源,这意味着如果有多个数据源可用,Spring Boot会默认使用标记为@Primary的数据源。

步骤 3: 配置JdbcTemplate或EntityManager

对于每个数据源,你可能需要配置一个JdbcTemplateEntityManager以便于操作数据库。

@Bean
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);
}@Bean
public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);
}

通过以上步骤,你可以在Spring Boot应用中配置并使用多个数据源。这种配置方式不仅可以满足复杂的业务需求,还可以帮助你更好地管理和维护不同的数据环境。

3. 整合MyBatis与多数据源

MyBatis 是一个流行的持久层框架,它支持定制化 SQL、存储过程以及高级映射。在 Spring Boot 应用中整合 MyBatis 用于多数据源管理,需要一些特定的配置来确保每个数据源正确地与对应的 SQL 映射和事务管理器绑定。

配置MyBatis使用多数据源

要配置 MyBatis 使用多个数据源,你需要定义每个数据源的 SqlSessionFactoryTransactionManager。这确保了 MyBatis 能够为每个数据库连接提供独立的会话和事务控制。

  1. 定义数据源:如之前所述,定义多个数据源。
  2. 创建 SqlSessionFactory:为每个数据源创建一个 SqlSessionFactory,这是 MyBatis 的核心组件,用于管理 MyBatis 的所有 SQL 操作。
  3. 配置 TransactionManager:为每个数据源配置一个事务管理器,确保事务的正确管理。
@Configuration
public class MyBatisConfig {@Bean@Primarypublic SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);return sessionFactory.getObject();}@Beanpublic SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);return sessionFactory.getObject();}@Bean@Primarypublic DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Beanpublic DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}
Mapper接口的数据源指定

在定义了不同的 SqlSessionFactory 后,需要指定每个 Mapper 接口或 XML 映射文件应该使用哪个数据源。这通常通过在 Mapper 接口上使用特定的注解或通过配置来实现。

  1. 使用@MapperScan注解指定数据源:可以在配置类中使用 @MapperScan 注解为不同的包指定不同的 SqlSessionFactory
@Configuration
@MapperScan(basePackages = "com.example.primary.mapper", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfig {// Primary data source configuration
}@Configuration
@MapperScan(basePackages = "com.example.secondary.mapper", sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryDataSourceConfig {// Secondary data source configuration
}

通过这种方式,你可以确保每个数据源的 Mapper 接口只会与指定的 SqlSessionFactory 交互,从而实现真正意义上的数据源隔离。这样的配置使得管理大型项目中的多数据源更加灵活和高效。

4. 数据源的动态路由

在多数据源的环境中,动态数据源路由成为一种强大的策略,允许应用程序在运行时根据特定的逻辑或条件选择不同的数据库。这对于需要根据用户请求、事务特性或其他业务逻辑动态切换数据源的应用尤其有用。

4.1 什么是数据源路由?

数据源路由是一种机制,它根据一定的规则动态地决定数据库操作应该走哪个数据源。例如,在一个多租户系统中,每个租户可能有自己的数据库,系统需要根据当前用户的租户信息动态切换到相应的数据库。

4.2 实现一个简单的动态数据源路由

为了实现动态数据源路由,我们通常需要创建一个动态数据源路由器,这个路由器继承自AbstractRoutingDataSource,并重写determineCurrentLookupKey()方法来决定使用哪个数据源键。

以下是一个简单的实现示例:

1. 定义动态数据源类

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {// DynamicDataSourceContextHolder用于持有当前线程使用的数据源标识return DynamicDataSourceContextHolder.getDataSourceType();}
}

2. 配置动态数据源

在Spring配置文件中,你需要配置DynamicDataSource作为数据源,并指定实际的数据源映射。

@Configuration
public class DataSourceConfig {@Beanpublic DataSource dataSource() {DynamicDataSource dynamicDataSource = new DynamicDataSource();// 设置默认数据源dynamicDataSource.setDefaultTargetDataSource(primaryDataSource());// 配置多数据源Map<Object, Object> dataSourceMap = new HashMap<>();dataSourceMap.put("primary", primaryDataSource());dataSourceMap.put("secondary", secondaryDataSource());dynamicDataSource.setTargetDataSources(dataSourceMap);return dynamicDataSource;}@Beanpublic DataSource primaryDataSource() {return new HikariDataSource(); // 配置主数据源}@Beanpublic DataSource secondaryDataSource() {return new HikariDataSource(); // 配置次级数据源}
}

3. 使用@Transactional指定数据源

在服务或数据访问层,你可以通过指定@Transactional注解的value属性来选择特定的数据源。

@Service
public class UserService {@Transactional(value = "primaryTransactionManager")public void addUser(User user) {// 使用主数据源添加用户}@Transactional(value = "secondaryTransactionManager")public User findUser(String username) {// 使用次级数据源查找用户}
}

这样的设置允许应用在运行时根据业务需求灵活选择合适的数据源,从而实现更复杂的数据操作策略和更高的数据操作灵活性。

5. 事务管理配置

在处理多数据源时,事务管理变得尤为重要,因为不当的事务处理可能导致数据不一致和其他严重问题。在Spring Boot应用中,正确配置和管理多数据源下的事务是确保数据完整性和一致性的关键。

如何管理多数据源下的事务
  1. 局部事务

    • 局部事务是最简单的事务类型,它仅涉及单一数据源。在Spring Boot中,你可以为每个数据源配置一个事务管理器。然后,你可以在服务层使用@Transactional注解来指定使用哪个事务管理器。
    • 示例配置事务管理器:
      @Bean
      public DataSourceTransactionManager transactionManager1(DataSource dataSource1) {return new DataSourceTransactionManager(dataSource1);
      }@Bean
      public DataSourceTransactionManager transactionManager2(DataSource dataSource2) {return new DataSourceTransactionManager(dataSource2);
      }
      
    • 使用指定的事务管理器:
      @Transactional(transactionManager = "transactionManager1")
      public void someDataServiceMethod() {// 业务逻辑
      }
      
  2. 全局事务

    • 全局事务(也称为分布式事务)涉及多个数据源或服务。在Spring Boot中,可以使用JTA(Java Transaction API)来配置全局事务管理器,如Atomikos或Bitronix。
    • 配置全局事务管理器(使用Atomikos为例):
      @Bean(initMethod = "init", destroyMethod = "close")
      public UserTransactionManager atomikosTransactionManager() throws Throwable {UserTransactionManager userTransactionManager = new UserTransactionManager();userTransactionManager.setForceShutdown(false);return userTransactionManager;
      }@Bean
      public JtaTransactionManager transactionManager(UserTransactionManager userTransactionManager) {JtaTransactionManager transactionManager = new JtaTransactionManager();transactionManager.setTransactionManager(userTransactionManager);transactionManager.setUserTransaction(userTransactionManager);return transactionManager;
      }
      
    • 在服务层使用全局事务管理器:
      @Transactional
      public void someDataServiceMethod() {// 业务逻辑涉及多个数据源
      }
      
配置全局事务和局部事务

在配置事务管理时,你需要决定每个业务场景适合使用局部事务还是全局事务。局部事务简单且性能较好,适用于单一数据源操作。全局事务适用于需要跨多个数据库或服务的操作,但可能会带来更高的性能开销。

确保在配置和使用事务时,明确区分不同的事务管理器,特别是在使用@Transactional注解时指定正确的管理器,以避免事务管理混乱导致的数据问题。

6. 实战示例:完整的多数据源配置示例

在这个部分,我们将通过一个实际的示例来展示如何在Spring Boot应用中配置和使用多个数据源。这个示例将包括配置文件、数据源配置、MyBatis集成、以及动态数据源的实现。

示例概述

假设我们有一个应用需要同时访问两个数据库:一个是主数据库(用于日常业务操作),另一个是审计数据库(用于记录审计日志)。我们将使用MySQL作为数据库。

步骤 1: 添加依赖

首先,在pom.xml中添加必要的依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>
</dependencies>
步骤 2: 配置数据源

application.yml中配置两个数据源:

spring:datasource:primary:jdbc-url: jdbc:mysql://localhost:3306/business_dbusername: user1password: pass1driver-class-name: com.mysql.cj.jdbc.Driveraudit:jdbc-url: jdbc:mysql://localhost:3306/audit_dbusername: user2password: pass2driver-class-name: com.mysql.cj.jdbc.Driver
步骤 3: 配置数据源 Bean 和 MyBatis

在Spring配置类中配置两个数据源和对应的SqlSessionFactory

@Configuration
public class DataSourceConfig {@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "auditDataSource")@ConfigurationProperties(prefix = "spring.datasource.audit")public DataSource auditDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "primarySqlSessionFactory")public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);return sessionFactory.getObject();}@Bean(name = "auditSqlSessionFactory")public SqlSessionFactory auditSqlSessionFactory(@Qualifier("auditDataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);return sessionFactory.getObject();}
}
步骤 4: 动态数据源路由

实现一个简单的动态数据源路由可以通过扩展AbstractRoutingDataSource

public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContext.getCurrentDataSource();}
}

这里的DataSourceContext是一个管理数据源键(比如线程本地变量)的工具类,它决定了当前线程应该使用哪个数据源。

步骤 5: 配置和使用

最后,你需要在业务逻辑中根据需要切换数据源。这通常是通过在服务层方法上使用注解或直接调用DataSourceContext来设置数据源。

这个示例提供了多数据源配置的基本框架,你可以根据实际需求调整和扩展,例如添加事务管理器配置、优化连接池设置等。

7. 简化多数据源管理-dynamic

dynamic-datasource-spring-boot-starter 是一个用于 Spring Boot 应用的数据源管理框架。它不仅是一个简单的组件,而是一个完整的解决方案,旨在简化多数据源的配置和管理。这个框架提供了在运行时动态切换数据源的能力,这对于需要连接到多个数据库的应用程序来说非常有用,特别是在需要实现读写分离或连接到不同类型数据库的场景中。

功能和特点

dynamic-datasource-spring-boot-starter 的主要功能和特点包括:

  1. 简化多数据源配置:通过在 Spring Boot 应用的配置文件中声明多个数据源,使得配置变得简单直观。
  2. 动态数据源切换:提供了基于方法或类的注解(如 @DS),允许开发者轻松指定哪个数据源应该被用于特定的操作。
  3. 灵活的数据源路由:支持基于业务逻辑动态选择数据源,例如根据用户的请求参数或其他逻辑来切换数据源。
  4. 支持主从复制:非常适合实现数据库的读写分离,提高数据库操作的效率和性能。
  5. 与 Spring 生态系统的集成:与 Spring Boot 和 Spring Data JPA 等其他 Spring 组件良好集成,使得它可以无缝地与现有的 Spring 应用协同工作。
应用场景
  • 读写分离:在需要处理大量读操作和相对较少的写操作的应用中,可以将读操作指向从数据库,而写操作指向主数据库。
  • 性能和可用性:通过分散请求到多个数据源,可以提高应用的响应时间和整体性能。
  • 数据隔离:在多租户系统中,每个租户可能需要独立的数据库。使用 dynamic-datasource-spring-boot-starter 可以轻松管理每个租户的数据源。

总之,dynamic-datasource-spring-boot-starter 是一个功能强大的多数据源管理框架,非常适用于需要高度灵活性和强大数据源管理功能的复杂应用程序。它通过简化配置和增加运行时数据源切换的能力,极大地提高了开发效率和应用性能。

引入依赖

首先,确保你的 Spring Boot 项目中已经添加了 dynamic-datasource-spring-boot-starter 的依赖。如果还没有添加,可以在 pom.xml 中加入以下依赖:

<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>版本</version>
</dependency>

版本根据实际项目的依赖版本选择

配置多数据源

application.ymlapplication.properties 文件中配置多个数据源。例如,使用 YAML 格式配置如下:

spring:datasource:dynamic:primary: master # 设置主数据源datasource:master:url: jdbc:mysql://localhost:3306/master_dbusername: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driverslave:url: jdbc:mysql://localhost:3306/slave_dbusername: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver
使用 @DS 注解

@DS 是一个用于多数据源分离的注解,提供了在同一个应用中同时使用多个数据源的能力。这个注解属于 dynamic-datasource-spring-boot-starter 库,用于在 Spring Boot 应用中动态管理多个数据源。下面是关于如何使用 @DS 注解的一些基本信息和示例。

在方法上使用
import com.baomidou.dynamic.datasource.annotation.DS;@Service
public class SomeService {@DS("master")public void writeToMaster() {// 这里的操作会使用配置中的 master 数据源}@DS("slave")public void readFromSlave() {// 这里的操作会使用配置中的 slave 数据源}
}
在类上使用

如果一个类中的所有方法都应该使用同一个数据源,可以将 @DS 注解放在类级别:

import com.baomidou.dynamic.datasource.annotation.DS;@DS("slave")
@Service
public class ReadOnlyService {// 所有方法都将使用 slave 数据源public void queryData() {// ...}
}
注意事项
  • 确保数据源的键(如 masterslave)与你在配置文件中定义的名称相匹配。
  • 使用 @DS 注解时,动态数据源会在方法调用前切换到指定的数据源,并在方法执行完毕后切换回原来的数据源。
  • 考虑事务管理的策略,特别是在使用多数据源时,可能需要配置多个事务管理器。

通过这种方式,@DS 注解为处理多数据源提供了一个非常灵活和强大的机制,使得在同一个应用中根据业务需要选择不同的数据源变得简单和直接。

相关文章:

【springboot】 多数据源实现

文章目录 1. 引言&#xff1a;多数据源的必要性和应用场景**为什么需要多数据源&#xff1f;****应用场景** 2. Spring Boot中的数据源配置2.1 默认数据源配置简介2.2 如何在Spring Boot中配置多个数据源 3. 整合MyBatis与多数据源**配置MyBatis使用多数据源****Mapper接口的数…...

Zephyr 入门-设备树与设备驱动模型

学习链接&#xff1a;https://www.bilibili.com/video/BV1L94y1F7qS/?spm_id_from333.337.search-card.all.click&vd_source031c58084cf824f3b16987292f60ed3c 讲解清晰&#xff0c;逻辑清楚。 1. 设备树概述&#xff08;语法&#xff0c;如何配置硬件&#xff0c;c代码如…...

css实现圆周运动效果

在CSS中可以通过 keyframes 动画 和 transform 属性实现元素的圆周运动。以下是一个示例代码&#xff1a; 示例代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content…...

乐鑫科技嵌入式面试题及参考答案(3万字长文)

嵌入式开发为什么用 C 语言,而不用 C++ 语言? 在嵌入式开发中,C 语言被广泛使用而 C++ 相对少用有以下一些原因。 首先,C 语言具有更高的效率。嵌入式系统通常资源受限,包括处理器速度、内存容量等。C 语言的代码生成效率高,能够生成紧凑的机器码,占用较少的内存空间和处…...

这就是IoC容器

IoC(Inversion of Control,控制反转),也叫依赖注入(Dependency Injection),是一种决定容器如何装配组件的模式。使用 Spring 来实现 IoC,意味着将设计好的对象交给 Spring 容器控制,而不是直接在对象内部控制。控制反转不能很好地描述这个模式,依赖注入却能更好地描述…...

KVM OVS双网卡配置trunk模式

一、宿主机配置 1. 确保必要的软件包已安装 确保宿主机上已安装 Open vSwitch 和 VLAN 工具。如果尚未安装&#xff0c;可以使用以下命令进行安装&#xff1a; yum install openvswitch-switch vlan 2. 配置现有 OVS 桥接 br0 假设已有一个 OVS 桥接接口 br0&#xff0c;并…...

氢能源车和电动车,谁将成为未来?

很多人都觉得氢能源是未来的终极绿色能源&#xff0c;因为氢气燃烧后只产生水&#xff0c;听起来是不是很环保&#xff1f;但这只是从化学能的角度来看。实际上&#xff0c;氢能源汽车还有很多问题需要解决。氢气的制作成本高得吓人 目前&#xff0c;制作氢气最理想的方法是电…...

CTF-PWN: WEB_and_PWN [第一届“吾杯”网络安全技能大赛 Calculator] 赛后学习(不会)

附件 calculate.html <!DOCTYPE html> <html lang"en"> <head><!-- 设置字符编码为 UTF-8&#xff0c;支持多语言字符集 --><meta charset"UTF-8"><!-- 设置响应式视图&#xff0c;确保页面在不同设备上自适应显示 --&…...

解决Jupyter Notebook无法转化为Pdf的问题(基于Typora非常实用)

笔者在完成各项作业和做笔记时&#xff0c;经常用到jupyter notebook&#xff1b;其因为可以同时运行python并提供格式化的数字公式的输入方式&#xff0c;得到了广大用户的喜爱。 当我们想要将.ipynb文件导出为pdf时&#xff0c;有两种常用方法。 1.Ctrlp 2.通过File ->…...

矩阵转置        ‌‍‎‏

矩阵转置 C语言代码C 语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输入一个n行m列的矩阵A&#xff0c;输出它的转置 A T A^T AT。 输入 第一行包含两个整数n和m&#xff0c;表示矩阵A的行数和列数。…...

【阅读笔记】Three ways ChatGPT helps me in my academic writing

Three ways ChatGPT helps me in my academic writing 论文地址 关于GPT进行润色的文章&#xff0c;摘取了里面的提示词做个记录。 1. Polishing academic writing&#xff08;学术润色&#xff09; 模板&#xff1a;I’m writing a paper on [topic] for a leading [discip…...

python学习笔记15 python中的类

上一篇我们介绍了python中的库 &#xff0c;学习了一些常见的内置库。详细内容可点击–>python学习笔记14 python中的库&#xff0c;常见的内置库&#xff08;random、hashlib、json、时间、os&#xff09; 这一篇我们来看一下python中的类 创建一个类 class 类的名称():de…...

3D数字化革新,探索博物馆的正确打开新方式!

3D数字化的发展&#xff0c;让博物馆也焕发新机&#xff0c;比如江苏省的“云上博物”&#xff0c;汇聚江苏全省博物馆展陈资源&#xff0c;采取线上展示和线下体验两种方式进行呈现的数字展览项目。在线上&#xff0c;用户可以通过H5或小程序进入“云上博物”数字展览空间&…...

金融数学在股市交易中的具体应用

### 1. 风险管理 - **VaR&#xff08;在险价值&#xff09;**: VaR是衡量投资组合潜在损失的指标。例如&#xff0c;如果一个投资组合的VaR为100万元&#xff0c;置信水平为95%&#xff0c;这意味着在未来的一个交易日内&#xff0c;有95%的可能性该投资组合的损失不会超过100…...

Springboot注解

什么是Spring Boot 注解 Spring Boot 注解是 Spring Boot 框架中的核心部分&#xff0c;它们用于简化配置和执行特定的编程任务。这些注解通常分为几个类别&#xff0c;包括用于 MVC 层的类注解、依赖注入注解、Web 开发常用注解、Spring Boot 常用注解、面向切面编程&#xf…...

CSS3 布局样式及其应用

深入探讨 CSS3 布局样式及其应用 引言 在现代网页设计中&#xff0c;CSS&#xff08;层叠样式表&#xff09;不仅是设计视觉样式的工具&#xff0c;也是布局的核心技术。CSS3引入了新的布局模型&#xff0c;其中Flexbox与Grid布局在满足复杂布局需求方面表现尤为出色。本文将…...

工业机器视觉-基于深度学习的水表表盘读数识别

字轮数字识别、指针读数识别&#xff08;角度换算&#xff09;、根据指针角度进行读数修正、根据最高位指针(x0.1)读数对字轮数字进行修正、得到最终读数。 基于深度学习的目标检测技术和OpenCV图像处理技术&#xff0c;可识别所有类型的表盘机械读数。...

kafka admin client 如何计算kafka发送速度

文章目录 方法 1&#xff1a;使用 AdminClient 获取消息数量示例代码&#xff1a;计算 Kafka 生产速度代码解释&#xff1a;解释&#xff1a;结果示例&#xff1a;方法 2&#xff1a;使用 Kafka JMX 监控JMX 指标&#xff1a; 总结&#xff1a; 要使用 Kafka Admin Client 来计…...

Ubuntu20.04 配置虚拟显示器和切回物理显示器

1、安装软件&#xff0c;用中软安装虚拟显示器软件 sudo apt-get install xserver-xorg-core-hwe-18.04 sudo apt-get install xserver-xorg-video-dummy2、添加配置文件 进入 /usr/share/X11/xorg.conf.d/ 文件夹下创建xorg.conf文件 # 创建xorg.conf文件 touch xorg.conf …...

【解决pycharm下site-packages文件标记为红色的问题】

怎么解决pycharm下site-packages文件标记为红色的问题 这是一个pycharm无法识别本地site-packages问题答案解释器设置路径如下&#xff1a; 这是一个pycharm无法识别本地site-packages问题 最近正在搭建一个python3requestsunittestHTMLTestRunner接口测试框架&#xff0c;发现…...

力扣-图论-2【算法学习day.52】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…...

项目-02-数学学院后台项目开发过程中的问题总结

目录 一、后台&#xff08;pc端&#xff0c;vue2&#xff09;1. dialog对话框被黑色蒙层盖住2. 将前端表格导出为word文档3. 在线查看、下载 .docx、.doc、.pdf文档 一、后台&#xff08;pc端&#xff0c;vue2&#xff09; 1. dialog对话框被黑色蒙层盖住 问题&#xff1a; d…...

数据结构-排序

目录 一、冒泡排序 二、选择排序 三、插入排序 四、希尔排序 五、堆排 六、快速排序 1、hoare&#xff1a; 2、挖坑法&#xff1a; 3、前后指针法&#xff1a; 4、快排非递归 七、归并排序 1、递归写法&#xff1a; 2、非递归写法&#xff1a; 八、计数排序 九、排…...

神经网络中常见的激活函数Sigmoid、Tanh和ReLU

激活函数在神经网络中起着至关重要的作用&#xff0c;它们决定了神经元的输出是否应该被激活以及如何非线性地转换输入信号。不同的激活函数适用于不同的场景&#xff0c;选择合适的激活函数可以显著影响模型的性能和训练效率。以下是三种常见的激活函数&#xff1a;Sigmoid、T…...

[报错] Error: PostCSS plugin autoprefixer requires PostCSS 8 问题解决办法

报错&#xff1a;Error: PostCSS plugin autoprefixer requires PostCSS 8 原因&#xff1a;autoprefixer版本过高 解决方案&#xff1a; 降低autoprefixer版本 执行&#xff1a;npm i postcss-loader autoprefixer8.0.0 参考&#xff1a; Error: PostCSS plugin autoprefix…...

多线程---创建及方法

*线程创建的方式&#xff1a; 1.继承Thread类&#xff0c;重写run方法。 2.实现Runnable接口&#xff0c;重写run方法。 实际这两个run方法都重写的是Runnable中的run方法 简化方法&#xff1a; 1.匿名内部类创建Thread 子类对象 Thread thread new Thread(){Overridepub…...

C++设计模式之单例模式

动机 在软件系统中&#xff0c;经常有一些特殊的类&#xff0c;必须保证它们在系统中只存在一个实例&#xff0c;才能确保它们的逻辑正确性&#xff0c;以及良好的效率。 如何绕过常规的构造器&#xff0c;提供一种机制来保证一个类只有一个实例&#xff1f; 这应该是类设计…...

给你一个整数n, 判断它是否是素数。注意1不是素数。:JAVA

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 给你一个整数n, 判断它是否是素数。注意1不是素数。 输入描述: 第一行输入一个整数T,表示需要判断的数的个数接下来T行每行一个整数n,表示需要判断的数。1<n<1e5,1<T<…...

Java项目实战II基于微信小程序的电子竞技信息交流平台的设计与实现(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着互联网技术的飞速发展…...

temu登录接口逆向分析(含Py纯算)

文章目录 1. 写在前面2. 接口分析3. 算法还原 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…...

Java ArrayList 详解

Java ArrayList 详解 ArrayList 是 Java 集合框架&#xff08;Collection Framework&#xff09;中最常用的类之一&#xff0c;是一种基于动态数组的数据结构&#xff0c;属于 List 接口的实现类。它允许存储重复的元素&#xff0c;有序&#xff0c;支持随机访问&#xff0c;且…...

CTF之密码学(仓颉编码)

一、仓颉码&#xff08;用于建立中文索引&#xff09; 定义与目标&#xff1a; 仓颉码是为了建立中文的索引观念而设计的一种编码方式。其主要目标是方便对中文资料或程式进行索引功能的处理。 工作原理&#xff1a; 仓颉码的索引以ASCII的字符码为基准&#xff0c;但在内部会转…...

OpenCV的圆形检测‌HoughCircles

HoughCircles 函数是 OpenCV 库中用于在灰度图像中检测圆的函数,它基于霍夫变换(Hough Transform)的一种变体——梯度霍夫变换(HOUGH_GRADIENT)函数原型如下: void HoughCircles( InputArray image, OutputArray circles,int method, double dp, double minDist,double …...

Latex 英文双栏排版时,摘要和引言之间的距离

目标&#xff1a;解决这个间隔 打开“cas-common.sty" 搜索“\NewDocumentCommand \dashrule" 本来是两个 m m 变成 m m m然后是增加下面这个代码&#xff0c;其他地方不动 \skip_vertical:n {#4} 搜索”MaketitleBox“和“LongMaketitleBox ” 本来的代码应该…...

AD学习笔记·空白工程的创建

编写不易&#xff0c;禁止搬运&#xff0c;仅供学习&#xff0c;感谢理解 序言 本文参考B站&#xff0c;凡亿教育&#xff0c;连接放在最后。 创建工程文件 在使用AD这个软件的电路板设计中&#xff0c;有很多的地方跟嘉立创eda还是有不一样的地方&#xff0c;其中一个地方就…...

非球面加工领域的佼佼者:倚光科技

在光学领域&#xff0c;非球面加工技术宛如一颗璀璨的明珠&#xff0c;以其独特的优势和广泛的应用&#xff0c;引领着光学元件制造的新潮流。 非球面透镜&#xff0c;其表面曲率半径从中心到边缘是变化的&#xff0c;这使得它在光学系统中具有诸多显著优势。首先&#xff0c;…...

Git分布式版本控制工具 Git基本概念、Git工作流程、Git常用命令、Git远程仓库、IDEA操作Git

目录 ​​​​​​ 1.Git基本概念 1.1 概述 1.1.1 开发中的实际场景 1.1.2 版本控制器的方式 1.1.2.1 集中式版本控制工具(SVN) 1.1.2.2 分布式版本控制工具(Git) 2.概述git工作流程 3.Git常用命令 3.1 Git环境配置 3.1.1 下载与安装 3.1.2 基本配置 3.1.3 为常用指令配置别名&…...

Spring 容器管理 Bean

Bean是什么 Bean 是指 Java 中的可重用软件组件,容器会根据提供的元数据来创建和管理这些 Bean,也包括它们之间的依赖关系。Spring 容器对 Bean 并没有太多的要求,无须实现特定接口或依赖特定库,只要是最普通的 Java 对象即可,这类对象也被称为 POJO(Plain Old Java Obj…...

Spring 容器 详解

Spring 容器详解 Spring 容器 是 Spring 框架的核心组件之一&#xff0c;它负责创建和管理应用程序中的 Bean&#xff08;对象&#xff09;以及处理它们之间的依赖关系。容器通过控制反转&#xff08;IoC&#xff09;和依赖注入&#xff08;DI&#xff09;实现对象的生命周期管…...

ubuntu环境下安装electron环境,并快速打包

1.配置镜像源 关闭防火墙&#xff0c;命令&#xff1a;sudo ufw disable 1.1配置国内镜像源&#xff1a; vim /etc/apt/source.list deb https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiversedeb-src https://mirrors.aliyun.com/ubuntu/ jammy main…...

Yeeco成长型一体化数智赋能平台:科技矩阵重塑企业数字生态

随着科技的飞速发展&#xff0c;我们正在步入一个被称为“数智化时代”的新时代。在这个时代中&#xff0c;数据处理和分析的能力被提升到一个前所未有的高度&#xff0c;而这种变化背后的重要推动力量就是各种新兴的技术趋势。 为了在激烈的市场竞争中脱颖而出&#xff0c;Yee…...

DP、CP、Mn是什么?有什么关系?双径节齿轮又是什么?

有一些刚刚接触齿轮的小伙伴们&#xff0c;经常听到和齿轮相关的是Mn这个代号&#xff0c;有时候拿到图纸会碰到DP和CP的图纸&#xff0c;今天就简单数一数他们三个的关系&#xff1a; 径节DP 齿轮的节距定义为两个相邻齿轮齿上两个相同点之间的距离。在理想情况下&#xff0c…...

Python 中的生成器是什么?

生成器&#xff08;Generator&#xff09;是Python中一种特殊的迭代器&#xff0c;它允许你逐步生成一系列值&#xff0c;而不是一次性创建整个列表或集合。 这在处理大型数据集或流式数据时特别有用&#xff0c;因为你可以逐个处理元素&#xff0c;而不需要将所有元素加载到内…...

如何参加华为欧拉考试?

华为欧拉考试主要针对的是华为欧拉&#xff08;EulerOS/openEuler&#xff09;操作系统的认证考试&#xff0c;这一认证体系旨在培养和认证具备基于欧拉操作系统进行企业级应用运行基础环境搭建、管理和调测能力的工程师以及云计算架构师。以下是对华为欧拉考试的详细介绍&…...

基于STM32设计的智能家居控制系统(华为云IOT)_275

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】国内外研究现状【6】摘要1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 参考文献1.6 系统框架图1.7 系统原理图1.8 实物图1.9…...

2024年第七届传智杯程序设计挑战赛第一场初赛题解

文章目录 2024年第七届传智杯程序设计挑战赛初赛第一场A-吃糖果(B组、C组)B-汤姆和杰瑞(A组、C组)C-游游的重组偶数(A组、B组、C组)D-开心还是难过(B组、C组)E-小欧的平面连线(A组、B组、C组)F-小红的四子棋(A组、B组、C组)G-小红的数组操作(A组、B组)H-游游的不相邻取数(A组) …...

iOS视图控制器的生命周期及各阶段的作用

iOS视图控制器&#xff08;UIViewController&#xff09;的生命周期是指从它被创建到最终被销毁的过程中所经历的一系列阶段。每个阶段都有其特定的作用和执行时机&#xff0c;这些阶段和作用对于开发高效、稳定的iOS应用至关重要。以下是iOS视图控制器的生命周期及其各个阶段的…...

stm32上电不能启动什么原因

STM32上电不能启动可能由多种原因造成,以下是一些常见的原因及解决方法: 一、软件原因 程序错误: 程序可能存在死循环、堆栈溢出、指针指向不允许的内存空间等问题。 解决方法:使用调试工具进行调试,检查程序流程,定位并修复错误。 时钟问题: 时钟切换失败或外部时钟源…...

【后端面试总结】golang channel深入理解

在Go语言中&#xff0c;Channel是一种用于在goroutine之间进行通信和同步的重要机制。它提供了一种安全、类型安全的方式来传递数据&#xff0c;使得并发编程变得更加直观和简单。本文将详细介绍Golang中Channel的基本概念、创建与关闭、发送与接收操作&#xff0c;以及相关的使…...

lobeChat安装

一、安装Node.js version > v18.17.0 二、下载 cd F:\AITOOLS\LobeChat git clone https://github.com/lobehub/lobe-chat.git &#xff08;下载要是失败就手动下&#xff1a;https://codeload.github.com/lobehub/lobe-chat/zip/refs/heads/main&#xff09; npm install …...