SpingBoot使用Mybatis-Plus操作多数据源,同时操作sqlserver和mysql

news2024/11/18 18:19:09

目录

需求场景

需求逻辑:

难点:

说明:

代码

pom.xml依赖只贴sqlserver的

文件目录

yml配置文件 

DataSource自定义注解

DataSourceAspect类文件

DruidConfig类

DruidProperties类

DynamicDataSource

DynamicDataSourceContextHolder

spring工具类

DataSourceType 

如何使用

 遇到的报错

问题一

问题二

问题三

问题四

 总结


需求场景

在学校或者自己练习的demo,基本都是配置一个数据源即可,基本都是使用MySQL,可是在工作中经常会出现很多不一样的场景和需求。

这里说一下我的需求:我需要从mysql数据库中通过一个字段去sqlserver数据库中读取数据,然后封装数据再录入到mysql中库中对应的表

需求逻辑:

  1. 首先需要查mysql的表,从表中获取字段
  2. 其次要用这个字段去sqlserver中查询我们想要的数据
  3. 最后解析数据封装,录入到mysql的另一个表中

难点:

  1. 如何配置多数据源
  2. 配置了多数据源如何动态的去查询数据

说明:

    尝试了很多方法,发现都不行,各种报错,在文章的后面会把我部署过程中的报错全部展现一下,方便大家排错,最后用的若依框架中的aop动态切换数据源的方式

后台手册 | RuoYi使用若依快速构建web应用程序http://doc.ruoyi.vip/ruoyi/document/htsc.html#%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90

代码

pom.xml依赖只贴sqlserver的

  <!-- SQL Server -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>9.2.1.jre15</version>
        </dependency>
        

文件目录

yml配置文件 

这里的数据源分为master 和 slave  如果你有三个四个五个数据源在这里都可以配置,只要在后面的config类配置中进行配置即可 

#dev环境 mysql 7.0
spring:
  application:
    name: data-spider
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    # 配置多数据源
    master:
      Url: jdbc:mysql://localhost:3306/库名?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
      username: root
      password: root
      #driver-class-name: com.mysql.cj.jdbc.Driver
    slave:
      enabled: true
      Url: jdbc:sqlserver://localhost:1433;DatabaseName=test
      username: sa
      password: 123456
      driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

    druid:
      inital-size: 10
      #最大连接数
      max-active: 50
      #最小连接数
      min-idle: 10
      #获取链接等待超时时间
      max-wait: 5000
      pool-prepared-statements: true #是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
      max-pool-prepared-statement-per-connection-size: 20
      validation-query: SELECT 1
      validation-query-timeout: 20000
      test-on-borrow: false  #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
      test-on-return: false #归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
      test-while-idle: true #建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
      time-between-eviction-runs-millis: 60000  #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      min-evictable-idle-time-millis: 300000  #一个连接在池中最小生存的时间,单位是毫秒
      max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位是毫秒
      #StatViewServlet配置。(因为暴露的监控信息比较敏感,支持密码加密和访问ip限定)
      web-stat-filter:
        enableed: true
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        #可以增加访问账号密码【去掉注释就可以】
        #login-username: admin
        #login-password: admin
      filter:
        stat:
          enabled: true
          # 慢SQL 记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true

DataSource自定义注解

通过注解的方式动态切换数据源,很灵活

package com.hhubrain.common.annotation;

import com.hhubrain.model.enums.DataSourceType;

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


/**
 * 自定义多数据源切换注解
 *
 * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
 *
 * @author 
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource
{
    /**
     * 切换数据源名称
     */
    public DataSourceType value() default DataSourceType.MASTER;
}

DataSourceAspect类文件

aop切面思想

package com.hhubrain.common.aop;

import java.util.Objects;

import com.hhubrain.common.annotation.DataSource;
import com.hhubrain.datasource.DynamicDataSourceContextHolder;
import com.hhubrain.utils.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 *
 * 多数据源处理
 * 
 * @author
 */
@Aspect
@Order(1)
@Component
public class DataSourceAspect
{
    protected Logger logger = LoggerFactory.getLogger(getClass());

    //这里的地址就是上面的DataSource注解的位置
    @Pointcut("@annotation(com.hhubrain.common.annotation.DataSource)"
            + "|| @within(com.hhubrain.common.annotation.DataSource)")
    public void dsPointCut()
    {

    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable
    {
        DataSource dataSource = getDataSource(point);

        if (StringUtils.isNotNull(dataSource))
        {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
        }

        try
        {
            return point.proceed();
        }
        finally
        {
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    /**
     * 获取需要切换的数据源
     */
    public DataSource getDataSource(ProceedingJoinPoint point)
    {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (Objects.nonNull(dataSource))
        {
            return dataSource;
        }

        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
}

DruidConfig类

  驱动自定义配置类,去获取不同的数据源做不同的事情

package com.hhubrain.common.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.sql.DataSource;

import com.hhubrain.datasource.DynamicDataSource;
import com.hhubrain.model.enums.DataSourceType;
import com.hhubrain.utils.SpringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;


/**
 * druid 配置多数据源
 * 
 * @author 
 */
@Configuration
public class DruidConfig
{
    //ConfigurationProperties 配置master数据源的前缀  看你的yml文件中的配置是否一致
    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource(DruidProperties druidProperties)
    {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    //ConditionalOnProperty这个注解的意思是 当配置文件中enabled这个值为true时才执行这个方法
    @Bean
    @ConfigurationProperties("spring.datasource.slave")
    @ConditionalOnProperty(prefix = "spring.datasource.slave", name = "enabled", havingValue = "true")
    public DataSource slaveDataSource(DruidProperties druidProperties)
    {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource)
    {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
        setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
        return new DynamicDataSource(masterDataSource, targetDataSources);
    }
    
    /**
     * 设置数据源
     * 
     * @param targetDataSources 备选数据源集合
     * @param sourceName 数据源名称
     * @param beanName bean名称
     */
    public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
    {
        try
        {
            DataSource dataSource = SpringUtils.getBean(beanName);
            targetDataSources.put(sourceName, dataSource);
        }
        catch (Exception e)
        {
        }
    }

    /**
     * 去除监控页面底部的广告
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
    public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
    {
        // 获取web监控页面的参数
        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
        // 提取common.js的配置路径
        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
        final String filePath = "support/http/resources/js/common.js";
        // 创建filter进行过滤
        Filter filter = new Filter()
        {
            @Override
            public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
            {
            }
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                    throws IOException, ServletException
            {
                chain.doFilter(request, response);
                // 重置缓冲区,响应头不会被重置
                response.resetBuffer();
                // 获取common.js
                String text = Utils.readFromResource(filePath);
                // 正则替换banner, 除去底部的广告信息
                text = text.replaceAll("<a.*?banner\"></a><br/>", "");
                text = text.replaceAll("powered.*?shrek.wang</a>", "");
                response.getWriter().write(text);
            }
            @Override
            public void destroy()
            {
            }
        };
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
}

DruidProperties类

属性配置类,针对yml文件中的配置获取

package com.hhubrain.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;

/**
 * druid 配置属性
 * 
 * @author 
 */
@Configuration
public class DruidProperties
{
    @Value("${spring.datasource.druid.inital-size}")
    private int initialSize;

    @Value("${spring.datasource.druid.min-idle}")
    private int minIdle;

    @Value("${spring.datasource.druid.max-active}")
    private int maxActive;

    @Value("${spring.datasource.druid.max-wait}")
    private int maxWait;

    @Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.druid.max-evictable-idle-time-millis}")
    private int maxEvictableIdleTimeMillis;

    @Value("${spring.datasource.druid.validation-query}")
    private String validationQuery;

    @Value("${spring.datasource.druid.test-while-idle}")
    private boolean testWhileIdle;

    @Value("${spring.datasource.druid.test-on-borrow}")
    private boolean testOnBorrow;

    @Value("${spring.datasource.druid.test-on-return}")
    private boolean testOnReturn;

    public DruidDataSource dataSource(DruidDataSource datasource)
    {
        /** 配置初始化大小、最小、最大 */
        datasource.setInitialSize(initialSize);
        datasource.setMaxActive(maxActive);
        datasource.setMinIdle(minIdle);

        /** 配置获取连接等待超时的时间 */
        datasource.setMaxWait(maxWait);

        /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

        /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);

        /**
         * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
         */
        datasource.setValidationQuery(validationQuery);
        /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */
        datasource.setTestWhileIdle(testWhileIdle);
        /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
        datasource.setTestOnBorrow(testOnBorrow);
        /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
        datasource.setTestOnReturn(testOnReturn);
        return datasource;
    }
}

DynamicDataSource

动态数据源

package com.hhubrain.datasource;

import java.util.Map;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 动态数据源
 * 
 * @author
 */
public class DynamicDataSource extends AbstractRoutingDataSource
{
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
    {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

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

DynamicDataSourceContextHolder

数据源切换处理

package com.hhubrain.datasource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 数据源切换处理
 * 
 * @author 
 */
public class DynamicDataSourceContextHolder
{
    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);

    /**
     * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
     *  所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
     */
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    /**
     * 设置数据源的变量
     */
    public static void setDataSourceType(String dsType)
    {
        log.info("切换到{}数据源", dsType);
        CONTEXT_HOLDER.set(dsType);
    }

    /**
     * 获得数据源的变量
     */
    public static String getDataSourceType()
    {
        return CONTEXT_HOLDER.get();
    }

    /**
     * 清空数据源变量
     */
    public static void clearDataSourceType()
    {
        CONTEXT_HOLDER.remove();
    }
}

spring工具类

方便在非spring管理环境中获取bean

package com.hhubrain.utils;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;


/**
 * spring工具类 方便在非spring管理环境中获取bean
 * 
 * @author
 */
@Component
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware 
{
    /** Spring应用上下文环境 */
    private static ConfigurableListableBeanFactory beanFactory;

    private static ApplicationContext applicationContext;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException 
    {
        SpringUtils.beanFactory = beanFactory;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 
    {
        SpringUtils.applicationContext = applicationContext;
    }

    /**
     * 获取对象
     *
     * @param name
     * @return Object 一个以所给名字注册的bean的实例
     * @throws BeansException
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) throws BeansException
    {
        return (T) beanFactory.getBean(name);
    }

    /**
     * 获取类型为requiredType的对象
     *
     * @param clz
     * @return
     * @throws BeansException
     *
     */
    public static <T> T getBean(Class<T> clz) throws BeansException
    {
        T result = (T) beanFactory.getBean(clz);
        return result;
    }

    /**
     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
     *
     * @param name
     * @return boolean
     */
    public static boolean containsBean(String name)
    {
        return beanFactory.containsBean(name);
    }

    /**
     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
     *
     * @param name
     * @return boolean
     * @throws NoSuchBeanDefinitionException
     *
     */
    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
    {
        return beanFactory.isSingleton(name);
    }

    /**
     * @param name
     * @return Class 注册对象的类型
     * @throws NoSuchBeanDefinitionException
     *
     */
    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
    {
        return beanFactory.getType(name);
    }

    /**
     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
     *
     * @param name
     * @return
     * @throws NoSuchBeanDefinitionException
     *
     */
    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
    {
        return beanFactory.getAliases(name);
    }

    /**
     * 获取aop代理对象
     * 
     * @param invoker
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T getAopProxy(T invoker)
    {
        return (T) AopContext.currentProxy();
    }

    /**
     * 获取当前的环境配置,无配置返回null
     *
     * @return 当前的环境配置
     */
    public static String[] getActiveProfiles()
    {
        return applicationContext.getEnvironment().getActiveProfiles();
    }

    /**
     * 获取当前的环境配置,当有多个环境配置时,只获取第一个
     *
     * @return 当前的环境配置
     */
    public static String getActiveProfile()
    {
        final String[] activeProfiles = getActiveProfiles();
        return StringUtils.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
    }
}

DataSourceType 

type的枚举类,差点忘了

package com.hhubrain.model.enums;

/**
 * 数据源
 *
 * @author 
 */
public enum DataSourceType
{
    /**
     * 主库
     */
    MASTER,

    /**
     * 从库
     */
    SLAVE,
    /**
     * 从库
     */
    TDENGINE
}

如何使用

在对应的service层或者mapper层类上面或者方法上添加@DataSource(value=type)注解即可

我这里是在定时器里写的,就直接在mapper的接口方法上加的

sqlserver  对应yml文件中salve中的数据源

 mysql  对应yml文件中master中的数据源

 遇到的报错

问题一

Failed to configure a Datasource: 'url' attribute is not specified and no embedded datasource could be configured.

 解决方法:

把jdbcUrl 改成url  不管是什么 都改成url即可

问题二

Failed to bind properties under 'spring.datasource.slave' to javax.sql.Datasource:

 解决方法:

问题三

Cavse: org.springframework.jdbc.CannotbetJdbcConnectionException: Failed to obtain JDBcConnection; nested exception is com.microsoft,sglserverjdbcSQLServerException: 通过端口 1433 连接到主机 Localhost的TCP/IP连接失败。

 解决方法:

右键点击"计算机"-->选择"管理"-->选择sqlserver配置管理-->重启服务

 

 

问题四

Failed to obtain JDBC Connection; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: 对象名 'DUAL' 无效。

 解决方法:

造成这个原因是配置mysql的时候需要validation-query:SELECT 1 FROM DUAL

但是sqlserver没有DUAL 造成报错,改成以下即可

 总结

问题千千万,唯有花时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/445028.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

03-java数组的使用

概念 数组就是存储数据长度固定的容器&#xff0c;存储多个数据的数据类型要一致。 数组的定义格式 // 第一种格式 // 数据类型[] 数组名 int[] arr; double[] arr; char[] arr;// 第二种格式 // 数据类型 数组名[] int arr[]; double arr[]; char arr[];数组…

记录解决Maven依赖冲突导致的NoSuchMethodError问题的过程

摘要 本文记录了解决 Maven 依赖冲突导致的 NoSuchMethodError 问题的过程。问题出现的原因是多个库包含了 Jackson 库&#xff0c;导致 Jackson 序列化与反序列化时出现 NoSuchMethodError 异常。通过查看依赖树&#xff0c;排除冲突库的方法&#xff0c;最终成功解决了该问题…

在职读研理论结合实践,社科院与杜兰大学金融管理硕士助你完成质的飞跃

我们知道&#xff0c;学习不能停留在理论层面&#xff0c;要用于实践才能真正的消化吸收。学习的目的在于运用&#xff0c;实践是检验学习成果的练兵场。社科院与杜兰大学金融管理硕士项目的课程中美授课教师在项目管理委员会的指导下&#xff0c;负责制订金融管理硕士教学方案…

【工程化】之5分钟发布一个Npm包

NPM是一个包管理器&#xff0c; 为js开发人员提供可以在项目中使用的模块&#xff0c;业界有很多流行的开源库&#xff0c;如Lodash&#xff0c;在我们内部也免不了通过对能力的封装打包&#xff0c;快速复用到其他地方去&#xff0c;使用NPM包很简单。您只需使用NPM安装包&…

SHELL中for循环和IF判断的使用

1。编写脚本for1.sh,使用for循环创建20账户&#xff0c;账户名前缀由用户从键盘输入&#xff0c;账户初始密码由用户输入&#xff0c;例如: test1、test2、test3、.....、 test10 2.编写脚本for2.sh,使用for循环,通过ping命令测试网段的主机连通性&#xff0c;网段前3段由用户输…

stable- diffusion新版本V2效果有提升吗?

之前版本是最初版本&#xff0c;不是V2&#xff0c;那么这里就新版本V2进行系列试验&#xff0c;如下&#xff0c;附代码及link 1、text2img from diffusers import StableDiffusionPipeline, DPMSolverMultistepSchedulermodel_id "stabilityai/stable-diffusion-2-1&…

在android项目上集成libyuv库以及使用libyuv库完成camera的缩放,旋转,翻转,裁剪操作

目录 一、下拉google官方的libyuv库代码 二、在android项目中集成libyuv库 1.环境配置 2.拷贝libyuv源码文件 ​编辑3.配置cmake libyuv相关的链接编译等 三、使用libyuv库 1.libyuv库完成camera的旋转 2.libyuv库实现翻转 3.libyuv库实现缩放 4.libyuv库实现裁剪 一…

九龙证券|多巨头竞相布局这个热门赛道,机构一致看好的概念股

华为高阶智能驾驭体系ADS 2.0版本发布。 早前&#xff0c;华为在2023华为智能轿车解决方案发布会上&#xff0c;发布了高阶智能驾驭体系 ADS 2.0。新体系将由 AITO 问界 M5 高阶智能驾驭版首发&#xff0c;并已适配阿维塔 11 全系列以及极狐阿尔法 S 全新 Hi 版等车型。 最近&…

JDBC(java数据库连接)—MySQL

文章目录 1.定义2.优势3.环境准备4.使用jdbc&#xff08;java程序操作数据库&#xff09;5.使用jdbc的操作步骤 1.定义 jdbc是一种用于执行SQL语句的java api&#xff0c;它是java中的数据库连接规范&#xff0c;为java开发人员操作数据库提供了一个标准的api&#xff0c;可以…

【Linux】系统文件接口

目录 一、C文件接口 1、fopen 2、fprintf 3、snprintf 二、系统文件IO 1、open 2、write 3、read 4、C文件接口与系统文件IO的关系 一、C文件接口 1、fopen FILE *fopen(const char *path, const char *mode); fopen 函数返回值类型为 FILE 。参数列表中&#xff0c…

优加DaaS背后,看见新的营销潮

DaaS、融合开放&#xff0c;这是京东云优加对外传递出来的两个最清晰的声音。前者对应的是能力和边界&#xff0c;后者对应的是态度和打法。两者结合&#xff0c;恰构成了京东云优加&#xff0c;或者说京东在营销侧的未来想象力。 作者|皮爷 出品|产业家 “今年我们有接近60%以…

第五章 工厂模式

文章目录 一、简单工厂模式1、传统方式实现披萨订购( 可以忽略)披萨父类 Pizza子类胡椒披萨 PepperPizza子类印度披萨 GreekPizza订购披萨 OrderPizza订购披萨的 客户端 PizzaStore运行结果传统的方式的优缺点&#xff0c;新增子类需要修改的地方牵扯太多传统方式的究极耦合 2、…

YOLOv8 更换骨干网络之 MobileNetV3

论文地址:https://arxiv.org/abs/1905.02244 代码地址:https://github.com/xiaolai-sqlai/mobilenetv3 我们展示了基于互补搜索技术和新颖架构设计相结合的下一代 MobileNets。MobileNetV3通过结合硬件感知网络架构搜索(NAS)和 NetAdapt算法对移动设计如何协同工作,利用互…

BswM模块之Ecu State Handling

文章目录 前言一、ESH是什么&#xff1f;二、基于BswM管理的ECU状态切换流程1.ECU启动2.ECU关闭 总结 前言 BswM – 基础软件模式管理模块&#xff0c; 它的职责是基于简单规则的BSW模块仲裁来自应用层sw - c或其他模块的模式请求&#xff0c;并根据仲裁结果进行相应的操作。 …

QT QPainter 绘制基本图形元件简介

1.基本图形元件 QPainter 提供了很多绘制基本图形的功能&#xff0c;包括点、直线、椭圆、矩形、曲线等&#xff0c;由这些基本的图形可以构成复杂的图形。QPainter 中提供的绘制基本图元的函数如下表所示。每个函数基本上都有多种参数形式&#xff0c;这里只列出函数名&#x…

Elastic Common Schema 和 OpenTelemetry — 无需供应商锁定即可获得更好的可观察性和安全性的途径

作者&#xff1a;Elastic 可观察性和安全团队 在 KubeCon Europe 上&#xff0c;宣布 Elastic Common Schema (ECS) 已被 OpenTelemetry (OTel) 接受作为对该项目的贡献。 目标是将 ECS 和 OpenTelemetry 的语义约定 (SemConv) 融合到一个由 OpenTelemetry 维护的开放模式中。 …

LearnOpenGL-模型加载

1.配置Assimp库。 下载Assimp&#xff0c;解压后得到 assimp-master 文件。在文件中新建一个 build 文件。使用 Cmake 生成工程文件保存在 build 中&#xff0c;从这里下载CMake&#xff0c;下载最新的即可。 打开CMake&#xff0c;选择需要源文件目录和目标目录。修改成适配…

机器学习平台、自研DPU、资源并池,火山引擎发布多云、AI基础设施与增长法宝

1、每十家大模型企业&#xff0c;七家在火山引擎云上。 2、火山引擎大模型训练云平台&#xff0c;支持万卡训练&#xff0c;集群性能提升3倍 3、火山引擎新一代自研DPU&#xff0c;实现计算、存储、网络的全组件卸载&#xff0c;释放更多资源给业务负载。 4、火山引擎与字节国内…

数据库管理软件dbeaver-ce 下载安装并离线配置

文章目录 前言数据库管理软件dbeaver-ce 下载安装并离线配置1. 概述2. 下载3. 安装4. 离线配置驱动jar包5. 链接mysql 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天…

谷歌aab包手机怎么安装教程

一、概述 bundletool是一种底层工具&#xff0c;可供 Android Studio、Android Gradle 插件和 Google Play 用于构建 Android App Bundle 文件并将 app bundle 转换为部署到设备的各种 APK。您也可以将 bundletool作为一种命令行工具&#xff0c;用于自行构建 app bundle 和重新…