springboot配置多个数据源(两种方式)

2023-11-01

在我们的实际业务中可能会遇到;在一个项目里面读取多个数据库的数据来进行展示,spring对同时配置多个数据源是支持的。

本文中将展示两种方法来实现这个功能。

springboot+mybatis

第一种方式:

在配置文件中配置多个数据源,然后通过配置类来获取数据源以及mapper相关的扫描配置

pom.xml

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/>
	</parent>
  <dependencies>
  			<!-- druid数据源驱动 -->
			<dependency>
			   <groupId>com.alibaba</groupId>
			   <artifactId>druid-spring-boot-starter</artifactId>
			   <version>1.1.0</version>
			</dependency>
  			<dependency>
	            <groupId>mysql</groupId>
	            <artifactId>mysql-connector-java</artifactId>
	        </dependency>
			<!--mybatis SpringBoot依赖 -->
			<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-tomcat</artifactId>
		    <scope>compile</scope>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
		
		<!-- aop依赖 -->
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		
		<!-- mybatis -->
		<dependency>
		    <groupId>org.mybatis.spring.boot</groupId>
		    <artifactId>mybatis-spring-boot-starter</artifactId>
		    <version>1.3.1</version>
		</dependency>
		
		<!-- 通用mapper -->
		<dependency>
		    <groupId>tk.mybatis</groupId>
		    <artifactId>mapper-spring-boot-starter</artifactId>
		    <version>1.1.5</version>
		</dependency>
			<!-- druid监控依赖 -->
			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>druid</artifactId>
				<version>1.0.28</version>
			</dependency>
  </dependencies>

application.yml


spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    
    url: jdbc:mysql://127.0.0.1:3306/test2?useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
    
    url2: jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=utf8
    username2: root
    password2: 123456

 DruidDBConfig 连接池相关配置

package com.xbz.common.config;
 
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
/**
 * Druid监控
 */
@SuppressWarnings("AlibabaRemoveCommentedCode")
@Configuration
public class DruidDBConfig {
    private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
 
    /**
     * 注册ServletRegistrationBean
     * @return
     */
    @Bean
    public ServletRegistrationBean druidServlet() {
        ServletRegistrationBean reg = new ServletRegistrationBean();
        reg.setServlet(new StatViewServlet());
        reg.addUrlMappings("/druid/*");
        reg.addInitParameter("allow", ""); //白名单
        return reg;
    }
 
    /**
     * 注册FilterRegistrationBean
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        filterRegistrationBean.addInitParameter("profileEnable", "true");
        filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
        filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
        filterRegistrationBean.addInitParameter("DruidWebStatFilter", "/*");
        return filterRegistrationBean;
    }
}

MasterDbConfig 注意读取数据库连接相关的键,以及扫描实体、mapper等

package com.xbz.common.config;
 
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
 
import javax.sql.DataSource;
import java.sql.SQLException;
 
 
@Configuration
@MapperScan(basePackages  = MasterDbConfig.PACKAGE , sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDbConfig {
    private Logger logger = LoggerFactory.getLogger(MasterDbConfig.class);
    // 精确到 master 目录,以便跟其他数据源隔离
    static final String PACKAGE = "com.xbz.**.dao.master";
    private static final String MAPPER_LOCATION = "classpath*:mapper/master/*.xml";
    private static final String DOMAIN_PACKAGE = "com.xbz.**.domain";
 
    @Value("${spring.datasource.url}")
    private String dbUrl;
 
    @Value("${spring.datasource.username}")
    private String username;
 
    @Value("${spring.datasource.password}")
    private String password;
 
    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;
 
 
    @Bean(name="masterDataSource")   //声明其为Bean实例
    @Primary  //在同样的DataSource中,首先使用被标注的DataSource
    public DataSource masterDataSource() {
        DruidDataSource datasource = new DruidDataSource();
 
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
 
        return datasource;
    }
 
    @Bean(name = "masterTransactionManager")
    @Primary
    public DataSourceTransactionManager masterTransactionManager() {
        return new DataSourceTransactionManager(masterDataSource());
    }
 
    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(masterDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(MasterDbConfig.MAPPER_LOCATION));
        sessionFactory.setTypeAliasesPackage(DOMAIN_PACKAGE);
        //mybatis 数据库字段与实体类属性驼峰映射配置
        sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
        return sessionFactory.getObject();
    }
}

ClusterDbConfig 

package com.xbz.common.config;
 
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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 javax.sql.DataSource;
import java.sql.SQLException;
 
/**
 * 从数据源配置
 * 若需要配置更多数据源 , 直接在yml中添加数据源配置再增加相应的新的数据源配置类即可
 */
@Configuration
@MapperScan(basePackages  = ClusterDbConfig.PACKAGE , sqlSessionFactoryRef = "clusterSqlSessionFactory")
public class ClusterDbConfig {
    private Logger logger = LoggerFactory.getLogger(ClusterDbConfig.class);
    // 精确到 cluster 目录,以便跟其他数据源隔离
    static final String PACKAGE = "com.xbz.**.dao.cluster";
    private static final String MAPPER_LOCATION = "classpath*:mapper/cluster/*.xml";
    private static final String DOMAIN_PACKAGE = "com.xbz.**.domain";
 
    @Value("${spring.datasource.url2}")
    private String dbUrl;
 
    @Value("${spring.datasource.username2}")
    private String username;
 
    @Value("${spring.datasource.password2}")
    private String password;
 
    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;
 
    
 
    @Bean(name="clusterDataSource")   //声明其为Bean实例
    public DataSource clusterDataSource() {
        DruidDataSource datasource = new DruidDataSource();
 
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        return datasource;
    }
 
    @Bean(name = "clusterTransactionManager")
    public DataSourceTransactionManager clusterTransactionManager() {
        return new DataSourceTransactionManager(clusterDataSource());
    }
 
    @Bean(name = "clusterSqlSessionFactory")
    public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("clusterDataSource") DataSource culsterDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(culsterDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(ClusterDbConfig.MAPPER_LOCATION));
        sessionFactory.setTypeAliasesPackage(DOMAIN_PACKAGE);
        //mybatis 数据库字段与实体类属性驼峰映射配置
        sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
        return sessionFactory.getObject();
    }
}

不同的数据源配置不佟的mapper扫描位置,然后需要哪一个数据源就注入哪一个mapper接口即可

这样获取的数据就是来自不同的数据源了,这种方法比较简单。

方法二:配置一个默认使用的数据源,然后定义多个其他的数据源,使用aop形成注解式选择数据源

# 默认数据源

spring:
  datasource:
    druid:
      # 数据库访问配置, 使用druid数据源 
      type: com.alibaba.druid.pool.DruidDataSource
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
      username: root
      password: 123456

# 其他数据源

custom:
  datasource:
    druid:
       type: com.alibaba.druid.pool.DruidDataSource
       names: fishlog,fishgame
       fishlog:
         driverClassName: com.mysql.jdbc.Driver
         url: jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=utf8
         username: root
         password: 123456
       fishgame:
         driverClassName: com.mysql.jdbc.Driver
         url: jdbc:mysql://127.0.0.1:3306/test2?useUnicode=true&characterEncoding=utf8
         username: root
         password: 123456

 添加jar包

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>${dynamic-ds.version}<ersion>
</dependency>

然后启动类中注入注解

注解类及参数value TargetDataSource 

package com.sysmg.common.config.datasoure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSource {
	String value();
}

 DynamicDataSource 

package com.sysmg.common.config.datasoure;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

	@Override
	protected Object determineCurrentLookupKey() {
		return DynamicDataSourceContextHolder.getDataSourceType();
	}

}

DynamicDataSourceAspect切面实现

package com.sysmg.common.config.datasoure;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(-10) // 保证该AOP在@Transactional之前执行
@Component
public class DynamicDataSourceAspect {
	@Before("@annotation(targetDataSource)")
	public void changeDataSource(JoinPoint point, TargetDataSource targetDataSource) throws Throwable {
		String dsId = targetDataSource.value();
		if (!DynamicDataSourceContextHolder.containsDataSource(dsId)) {
			System.err.println("数据源[{}]不存在,使用默认数据源 > {}" + targetDataSource.value() + point.getSignature());
		} else {
			System.out.println("UseDataSource : {} > {}" + targetDataSource.value() + point.getSignature());
			DynamicDataSourceContextHolder.setDataSourceType(targetDataSource.value());
		}
	}

	@After("@annotation(targetDataSource)")
	public void restoreDataSource(JoinPoint point, TargetDataSource targetDataSource) {
		System.out.println("RevertDataSource : {} > {}"+targetDataSource.value()+point.getSignature());
		DynamicDataSourceContextHolder.clearDataSourceType();
	}
}

DynamicDataSourceContextHolder

package com.sysmg.common.config.datasoure;

import java.util.ArrayList;

import java.util.List;

public class DynamicDataSourceContextHolder {
	private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
	public static List<String> dataSourceIds = new ArrayList<String>();

	public static void setDataSourceType(String dataSourceType) {
		contextHolder.set(dataSourceType);
	}

	public static String getDataSourceType() {
		return contextHolder.get();
	}

	public static void clearDataSourceType() {
		contextHolder.remove();
	}

	public static boolean containsDataSource(String dataSourceId){
		return dataSourceIds.contains(dataSourceId);
	}
}

DynamicDataSourceRegister数据源注册类

package com.sysmg.common.config.datasoure;

import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

public class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {
	private static final Object DATASOURCE_TYPE_DEFAULT = "com.alibaba.druid.pool.DruidDataSource";
	private ConversionService conversionService = new DefaultConversionService();
	private PropertyValues dataSourcePropertyValues;
	private DataSource defaultDataSource;
	private Map<String, DataSource> customDataSources = new HashMap<String, DataSource>();

	@Override
	public void setEnvironment(Environment environment) {
		System.out.println("DynamicDataSourceRegister.setEnvironment()");
		initDefaultDataSource(environment);
		initCustomDataSources(environment);
	}

	private void initDefaultDataSource(Environment env) {
		RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, "spring.datasource.druid.");
		Map<String, Object> dsMap = new HashMap<String, Object>();
		dsMap.put("type", propertyResolver.getProperty("type"));
		dsMap.put("driverClassName", propertyResolver.getProperty("driverClassName"));
		dsMap.put("url", propertyResolver.getProperty("url"));
		dsMap.put("username", propertyResolver.getProperty("username"));
		dsMap.put("password", propertyResolver.getProperty("password"));
		defaultDataSource = buildDataSource(dsMap);
		dataBinder(defaultDataSource, env);
	}

	private void initCustomDataSources(Environment env) {
		RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, "custom.datasource.druid.");
		String dsPrefixs = propertyResolver.getProperty("names");
		for (String dsPrefix : dsPrefixs.split(",")) {// 多个数据源
			Map<String, Object> dsMap = propertyResolver.getSubProperties(dsPrefix + ".");
			DataSource ds = buildDataSource(dsMap);
			customDataSources.put(dsPrefix, ds);
			dataBinder(ds, env);
		}
	}

	@SuppressWarnings("unchecked")
	public DataSource buildDataSource(Map<String, Object> dsMap) {
		Object type = dsMap.get("type");
		if (type == null) {
			type = DATASOURCE_TYPE_DEFAULT;// 默认DataSource
		}
		Class<? extends DataSource> dataSourceType;
		try {
			dataSourceType = (Class<? extends DataSource>) Class.forName((String) type);
			String driverClassName = dsMap.get("driverClassName").toString();
			String url = dsMap.get("url").toString();
			String username = dsMap.get("username").toString();
			String password = dsMap.get("password").toString();
			DataSourceBuilder factory = DataSourceBuilder.create().driverClassName(driverClassName).url(url)
					.username(username).password(password).type(dataSourceType);
			return factory.build();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	private void dataBinder(DataSource dataSource, Environment env) {
		RelaxedDataBinder dataBinder = new RelaxedDataBinder(dataSource);
		dataBinder.setConversionService(conversionService);
		dataBinder.setIgnoreNestedProperties(false);// false
		dataBinder.setIgnoreInvalidFields(false);// false
		dataBinder.setIgnoreUnknownFields(true);// true
		if (dataSourcePropertyValues == null) {
			Map<String, Object> rpr = new RelaxedPropertyResolver(env, "spring.datasource").getSubProperties(".");
			Map<String, Object> values = new HashMap<>(rpr);
			values.remove("type");
			values.remove("driverClassName");
			values.remove("url");
			values.remove("username");
			values.remove("password");
			dataSourcePropertyValues = new MutablePropertyValues(values);
		}
		dataBinder.bind(dataSourcePropertyValues);
	}

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		System.out.println("DynamicDataSourceRegister.registerBeanDefinitions()");
		Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
		targetDataSources.put("dataSource", defaultDataSource);
		DynamicDataSourceContextHolder.dataSourceIds.add("dataSource");
		targetDataSources.putAll(customDataSources);
		for (String key : customDataSources.keySet()) {
			DynamicDataSourceContextHolder.dataSourceIds.add(key);
		}
		GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
		beanDefinition.setBeanClass(DynamicDataSource.class);
		beanDefinition.setSynthetic(true);
		MutablePropertyValues mpv = beanDefinition.getPropertyValues();
		mpv.addPropertyValue("defaultTargetDataSource", defaultDataSource);
		mpv.addPropertyValue("targetDataSources", targetDataSources);
		registry.registerBeanDefinition("dataSource", beanDefinition);
	}
}

这里使用的时候把需要使用的表名注入,如果是默认的数据源,则不需要加这个注解,具体的springboot自定义注解的建立,可参考springboot自定义日志注解_江流。的博客-CSDN博客,这里的mapper文件和实体扫描可以跟默认的数据源配置相同即可

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot配置多个数据源(两种方式) 的相关文章

随机推荐

  • springboot 2.0多模块标准父类pom文件,别再问问什么找不到主类了,照着个写就行

    标准如下
  • ECharts动态加载数据绘制折线图

    Echarts动态加载数据绘制折线图 ECharts 引入ECharts 步骤 连接数据接口 动态加载图表 动态加载数据 整体代码 折线图绘制 总结 绘制多个图表的方法 ECharts 纯Javascript的图表库 支持各种图表的绘制 下
  • 区块链(肖臻笔记)

    区块链的技术与应用 比特币 密码学基础 比特币的数据结构 共识协议和系统实现 挖矿算法和难度调整 比特币的脚本 软分叉和硬分叉 匿名和隐私保护 以太坊 概述 基于账户的分布式账本 数据结构 状态树 交易树 收据树 ghost协议 挖矿 me
  • 初识EMC元器件(四)——共模电感选型及应用

    通过上一篇文章 共模电感的参数解读 已经对共模电感的参数有了初步的认识 那么本章将结合电路应用 一 共模电感选型步骤 共模电感滤波应用选型步骤 确定电路性质 电气参数 滤波频段 电感参数 主要需要考虑的参数有 电感感量 额定电流 额定电压
  • 前端基础2——CSS样式

    文章目录 一 使用方式 1 1 内联方式 1 2 内部方式 1 3 外部导入方式 推荐 二 选择器类型 2 1 元素选择器 2 2 ID选择器 2 3 类选择器 2 4 派生选择器 三 常用属性 3 1 内边距和外边距 3 2 文本 3 3
  • 转置卷积/逆卷积

    转置卷积作用 上采样 原理 卷积过程 step1 滑动窗口非常低效 我选择等效矩阵 相应位置相乘再相加 得到输出feature map step2 展平 得到矩阵i step3 把每一个等效矩阵展平为列向量 得到矩阵c step4 矩阵i和
  • vue中粘贴板clipboard的使用方法

    安装clipboard npm install clipboard save 在模板文件中引入 import Clipboard from clipboard 具体使用 这里我用的表格
  • 开发遇到问题全记录【增量】

    1 MyEclipse内部启动tomcat jar包冲突 在
  • 计算机文化基础-计算思维

    文章目录 计算思维 计算思维基础 计算思维定义 计算思维本质 计算思维特征 计算思维的基本问题 计算思维的基本方法 计算思维的应用 计算思维 关于计算机的说法很多 但就计算机科学来讲 计算机科学家在用计算机解决问题时形成的特有思维方式和解决
  • 三、对象与类

    1 面向对象程序设计概述 面向对象 OOP 是由对象组成的 每个对象包含对用户公开的特定功能部分和隐藏的实现部分 在OOP中 不必关心对象的具体实现 只要能满足用户的需求即可 类与对象概述 类 是构造对象的模板或蓝图 由类构造对象的过程称为
  • 什么是IoT数字孪生?

    数字孪生是资产或系统的实时虚拟模型 它使用来自连接的物联网传感器的数据来创建数字表示 数字孪生允许您从任何地方实时监控设备 资产或流程 数字孪生用于多种目的 例如分析性能 监控问题或在实施之前运行测试 从物联网数字孪生中获得的见解使用户能够
  • curl get post传参说明

    一 get请求 方式一 多个参数间用 连接 curl http 127 0 0 1 8080 api send type 1 mobile 13111111111 apikey sdfsdfdfs code 1234 方式二 url用单引号
  • 【云计算与大数据技术】虚拟化简介及虚拟化的分类讲解(图文解释 超详细)

    一 虚拟化简介 1 什么是虚拟化 虚拟化是指计算机元件在虚拟的基础上而不是在真实的 独立的物理硬件基础上运行 这种以优化资源 简化软件的重新配置过程为目的的解决方案就是虚拟化技术 虚拟化架构就是在一个物理硬件机器上同时运行多个不同应用的独立
  • sklearn-多元线性回归

    sklearn 多元线性回归 和简单线性回归使用单一解释变量和单一系数不同 多元线性回归使用任意数量的解释变量 每个解释变量对应一个系数 用于线性回归的模型也可以被表示为向量计法 多元线性回归 Y X Y是一个由训练实例响应变量组成的列向量
  • centOS7 重启后,连不上网(网卡不见了,ifcfg-ens33文件不存在)

    问题 ifconfig查询的时候 只有lo网卡 但是ifconfig a查询的时候却有ens33网卡 ls etc syconfig network scripts 查找所有网卡配置信息文件的时候 没有ifcfg ens33网卡配置文件 解
  • Python连接influxdb2.x

    Python连接influxdb2 x 一 调研 1 1 influxdb pypi 1 2 influxdb client pypi 二 连接 2 1 对象源码 2 2 连接实例 三 问题汇总 3 1 token非永久化问题结果 一 调研
  • 人工智能技术与现代应用

    人工智能的定义 人工智能 ArtificialIntelligence AI 学科从1956年正式提出 目前已取得长足的发展 成为一门广泛的交叉和前沿科学 总的说来 人工智能的目的就是让计算机这台机器能够像人一样思考 如果希望做出一台能够思
  • Vue 学习笔记

    Vue js 库 把一些常用的功能封装成一个个函数或者对象 并放到一个JS文件里 目的是为简化原生JS的操作 他是一个封装好的框架 框架 一套架构 提供一套整体解决方案 他能完全搞定整个项目开发 并且很轻松就能解决复杂的问题 vue的特征
  • 华硕天选笔记本电脑能上网但浏览器打不开

    系列文章目录 文章目录 系列文章目录 前言 二 第二种方法 1 打开设置 2 选择更改适配器选项 三 第三种方法 重置网络 1 设置 2 重置网络 前言 华硕天选笔记本电脑能上网但浏览器打不开 网上的方法 1 点击 开始 选择 控制面板 2
  • springboot配置多个数据源(两种方式)

    在我们的实际业务中可能会遇到 在一个项目里面读取多个数据库的数据来进行展示 spring对同时配置多个数据源是支持的 本文中将展示两种方法来实现这个功能 springboot mybatis 第一种方式 在配置文件中配置多个数据源 然后通过