Mybatis引出的一系列问题-spring多数据源配置

在日常开发中我们都是以单个数据库进行开发,在小型项目中是完全能够满足需求的。但是,当我们牵扯到像淘宝、京东这样的大型项目的时候,单个数据库就难以承受用户的CRUD操作。那么此时,我们就需要使用多个数据源进行读写分离的操作,这种方式也是目前一种流行的数据管理方式。

1 Spring Boot配置多数据源

在YAML文件中定义数据源所需的数据:

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedefault-datasource:username: rootpassword: rooturl: jdbc:mysql://localhost:3306/default?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.jdbc.Driverinspur-zs-datasource:username: rootpassword: rooturl: jdbc:mysql://localhost:3306/inspur-zs?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.jdbc.Driverdruid:initial-size: 5min-idle: 1max-active: 20profiles:active: devmybatis:mapper-locations: classpath:/mapper/*.xmltype-aliases-package: com.inspur.pojoconfiguration:mapUnderscoreToCamelCase: truelog-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl

定义多个数据源:

package com.inspur.spring.config.datasource;import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;/*** 数据源配置* ConfigurationProperties注解用于将YAML中指定的数据创建成指定的对象,* 但是,YAML中的数据必须要与对象对象中的属性同名,不然无法由Spring Boot完成赋值。** @author zhaoshuai-lc* @date 2023/07/11*/
@Configuration
public class DataSourceConfig {@Bean(name = "defaultDatasource")@ConfigurationProperties(prefix = "spring.datasource.default-datasource")public DataSource defaultDatasource() {return DruidDataSourceBuilder.create().build();}@Bean(name = "inspurZsDatasource")@ConfigurationProperties(prefix = "spring.datasource.inspur-zs-datasource")public DataSource inspurZsDatasource() {return DruidDataSourceBuilder.create().build();}
}

由于我们要定义多个数据源,所以在Spring Boot数据源自动配置类中就无法确定导入哪个数据源来完成初始化,所以我们就需要禁用掉Spring Boot的数据源自动配置类,然后使用我们自定义的数据源配置类来完成数据源的初始化与管理。

package com.inspur;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** WtMybatisStudyApplication* 由于我们要定义多个数据源,所以在Spring Boot数据源自动配置类中就无法确定导入哪个数据源来完成初始化,* 所以我们就需要禁用掉Spring Boot的数据源自动配置类,然后使用我们自定义的数据源配置类来完成数据源的初始化与管理。** @author zhaoshuai-lc* @date 2023/07/11*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableAspectJAutoProxy
public class WtMybatisStudyApplication {public static void main(String[] args) {SpringApplication.run(WtMybatisStudyApplication.class, args);}
}

1.1 指定数据源-实现DataSource接口

缺点:产生大量的代码冗余,在代码中存在硬编码。

package com.inspur.spring.config.datasource;import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;/*** 方式一* DynamicDataSource1* 实现DataSource接口我们本质上只使用了一个方法就是getConnection()这个无参的方法** @author zhaoshuai-lc* @date 2023/07/11*/
@Component
@Primary
public class DynamicDataSource1 implements DataSource {public static ThreadLocal<String> flag = new ThreadLocal<>();@Resourceprivate DataSource defaultDatasource;@Resourceprivate DataSource inspurZsDatasource;public DynamicDataSource1() {flag.set("defaultDatasource");}@Overridepublic Connection getConnection() throws SQLException {if (flag.get().equals("defaultDatasource")) {return defaultDatasource.getConnection();} else if (flag.get().equals("inspurZsDatasource")) {return inspurZsDatasource.getConnection();}return defaultDatasource.getConnection();}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}
}

实现DataSource接口我们本质上只使用了一个方法,就是getConnection()这个无参的方法,但是DataSource接口中所有的方法我们也都需要实现,只是不用写方法体而已,也就是存在了很多的 “废方法” 。
@Primary注解 == @Order(1),用于设置此类的注入顺序。

使用:

    @Overridepublic PageData<BsFactoryCalendar> selectByExample(BsFactoryCalendarExample example) {PageData<BsFactoryCalendar> pageData = new PageData<>();DynamicDataSource1.flag.set("default-datasource");List<BsFactoryCalendar> bsFactoryCalendars = bsFactoryCalendarMapper.selectByExample(example);PageInfo<BsFactoryCalendar> pageInfo = new PageInfo<>(bsFactoryCalendars);pageData.setRows(bsFactoryCalendars);pageData.setTotal(pageInfo.getTotal());return pageData;}

1.2 指定数据源-继承AbstrictRoutingDataSource类

减少了代码的冗余,但是还是会存在硬编码。

package com.inspur.spring.config.datasource;import cn.hutool.core.map.MapUtil;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Map;/*** DynamicDataSource2* AbstrictRoutingDataSource的本质就是利用一个Map将数据源存储起来,然后通过Key来得到Value来修改数据源。** @author zhaoshuai-lc* @date 2023/07/11*/@Component
@Primary
public class DynamicDataSource2 extends AbstractRoutingDataSource {public static ThreadLocal<String> flag = new ThreadLocal<>();@Resourceprivate DataSource defaultDatasource;@Resourceprivate DataSource inspurZsDatasource;public DynamicDataSource2() {flag.set("defaultDatasource");}@Overrideprotected Object determineCurrentLookupKey() {return flag.get();}@Overridepublic void afterPropertiesSet() {Map<Object, Object> targetDataSource = MapUtil.newConcurrentHashMap();// 将第一个数据源设置为默认的数据源super.setDefaultTargetDataSource(defaultDatasource);targetDataSource.put("defaultDatasource", defaultDatasource);targetDataSource.put("inspurZsDatasource", inspurZsDatasource);super.setTargetDataSources(targetDataSource);super.afterPropertiesSet();}
}

AbstrictRoutingDataSource的本质就是利用一个Map将数据源存储起来,然后通过Key来得到Value来修改数据源。

使用:

    @Overridepublic PageData<BsFactoryCalendar> selectByExample(BsFactoryCalendarExample example) {PageData<BsFactoryCalendar> pageData = new PageData<>();DynamicDataSource2.flag.set("default-datasource");List<BsFactoryCalendar> bsFactoryCalendars = bsFactoryCalendarMapper.selectByExample(example);PageInfo<BsFactoryCalendar> pageInfo = new PageInfo<>(bsFactoryCalendars);pageData.setRows(bsFactoryCalendars);pageData.setTotal(pageInfo.getTotal());return pageData;}

1.3 指定数据源-使用Spring AOP + 自定义注解的形式

Spring AOP + 自定义注解的形式是一种推荐的写法,减少代码的冗余且不存在硬编码。此方法适合对指定功能操作指定数据库的模式。

导入依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

开启AOP支持:

package com.inspur;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableAspectJAutoProxy
public class WtMybatisStudyApplication {public static void main(String[] args) {SpringApplication.run(WtMybatisStudyApplication.class, args);}}

定义枚举来表示数据源的标识:

package com.inspur.spring.config.datasource.enums;public enum DataSourceType {DEFAULT_DATASOURCE,INSPURZS_DATASOURCE,
}

继承AbstractRoutingDataSource类:

package com.inspur.spring.config.datasource;import cn.hutool.core.map.MapUtil;
import com.inspur.spring.config.datasource.enums.DataSourceType;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Map;@Primary
@Component
public class DynamicDataSource3 extends AbstractRoutingDataSource {public static ThreadLocal<String> flag = new ThreadLocal<>();@Resourceprivate DataSource defaultDatasource;@Resourceprivate DataSource inspurZsDatasource;public DynamicDataSource3() {flag.set(DataSourceType.DEFAULT_DATASOURCE.name());}@Overrideprotected Object determineCurrentLookupKey() {return flag.get();}@Overridepublic void afterPropertiesSet() {Map<Object, Object> targetDataSource = MapUtil.newConcurrentHashMap();// 将第一个数据源设置为默认的数据源super.setDefaultTargetDataSource(defaultDatasource);targetDataSource.put(DataSourceType.DEFAULT_DATASOURCE.name(), defaultDatasource);targetDataSource.put(DataSourceType.INSPURZS_DATASOURCE.name(), inspurZsDatasource);super.setTargetDataSources(targetDataSource);super.afterPropertiesSet();}
}

自定义注解:

package com.inspur.spring.config.datasource.annotation;import com.inspur.spring.config.datasource.enums.DataSourceType;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.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSource {DataSourceType value() default DataSourceType.DEFAULT_DATASOURCE;
}

定义注解的实现类:

package com.inspur.spring.config.datasource.annotation;import com.inspur.spring.config.datasource.DynamicDataSource3;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;/*** TargetDataSourceAspect** @author zhaoshuai-lc* @date 2023/07/11*/
@Component
@Aspect
@Slf4j
public class TargetDataSourceAspect {@Before("@within(com.inspur.spring.config.datasource.annotation.TargetDataSource) || " +"@annotation(com.inspur.spring.config.datasource.annotation.TargetDataSource)")public void beforeNoticeUpdateDataSource(JoinPoint joinPoint) {TargetDataSource annotation = null;Class<? extends Object> target = joinPoint.getTarget().getClass();if (target.isAnnotationPresent(TargetDataSource.class)) {// 判断类上是否标注着注解annotation = target.getAnnotation(TargetDataSource.class);log.info("类: {}, 标注了注解@TargetDataSource", target);} else {Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();if (method.isAnnotationPresent(TargetDataSource.class)) {// 判断方法上是否标注着注解,如果类和方法上都没有标注,则报错annotation = method.getAnnotation(TargetDataSource.class);log.info("方法: {}, 标注了注解@TargetDataSource", method);} else {log.error("注解@TargetDataSource只能用于类或者方法上, error: {} {}", target, method);throw new RuntimeException("注解@TargetDataSource使用错误");}}// 切换数据源DynamicDataSource3.flag.set(annotation.value().name());}
}

使用:

package com.inspur.spring.service;import com.github.pagehelper.PageInfo;
import com.inspur.spring.common.interfaceResult.PageData;
import com.inspur.spring.config.datasource.annotation.TargetDataSource;
import com.inspur.spring.config.datasource.enums.DataSourceType;
import com.inspur.spring.dao.BsFactoryCalendarMapper;
import com.inspur.spring.pojo.BsFactoryCalendar;
import com.inspur.spring.pojo.BsFactoryCalendarExample;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.util.List;@Service
@TargetDataSource(value = DataSourceType.DEFAULT_DATASOURCE) // 方式三 多数据源设置
public class BsFactoryCalendarServiceImpl implements BsFactoryCalendarService {@Resourceprivate BsFactoryCalendarMapper bsFactoryCalendarMapper;@Override@Transactionalpublic PageData<BsFactoryCalendar> selectByExample(BsFactoryCalendarExample example) {PageData<BsFactoryCalendar> pageData = new PageData<>();List<BsFactoryCalendar> bsFactoryCalendars = bsFactoryCalendarMapper.selectByExample(example);PageInfo<BsFactoryCalendar> pageInfo = new PageInfo<>(bsFactoryCalendars);pageData.setRows(bsFactoryCalendars);pageData.setTotal(pageInfo.getTotal());return pageData;}
}

1.4 通过SqlSessionFactory指定的数据源来操作指定目录的XML文件

使用此方法则不会与上面所述的类有任何关系,本方法会重新定义类。本方法也是一种推荐的方法,适用于对指定数据库的操作,也就是适合读写分离。不会存在代码冗余和存在硬编码。

在这里插入图片描述

配置YAML文件:

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedefault-datasource:username: rootpassword: rootjdbc-url: jdbc:mysql://localhost:3306/default?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.jdbc.Driverinspur-zs-datasource:username: rootpassword: rootjdbc-url: jdbc:mysql://localhost:3306/inspur-zs?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.jdbc.Drivermain:allow-bean-definition-overriding : truedruid:initial-size: 5min-idle: 1max-active: 20profiles:active: devmybatis:mapper-locations: classpath:/mapper/*.xmltype-aliases-package: com.inspur.pojoconfiguration:mapUnderscoreToCamelCase: truelog-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl

针对Mapper层通过SqlSessionFactory指定数据源来操作:

package com.inspur.spring.config.datasource;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.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;@Configuration
@MapperScan(basePackages = "com.inspur.spring.dao.defaultzs", sqlSessionFactoryRef = "DefaultSqlSessionFactory")
public class DefaultDatasourceConfig {@Primary@Bean(name = "DefaultDatasource")@ConfigurationProperties(prefix = "spring.datasource.default-datasource")public DataSource getDateSource1() {return DataSourceBuilder.create().build();}@Primary@Bean(name = "DefaultSqlSessionFactory")public SqlSessionFactory sqlSessionFactory(@Qualifier("DefaultDatasource") DataSource datasource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(datasource);// 设置mybatis的xml所在位置bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/defaultzs/*.xml"));return bean.getObject();}@Bean("DefaultSqlSessionTemplate")@Primarypublic SqlSessionTemplate sqlSessionTemplate(@Qualifier("DefaultSqlSessionFactory") SqlSessionFactory factory) {return new SqlSessionTemplate(factory);}@Beanpublic PlatformTransactionManager transactionManager(@Qualifier("DefaultDatasource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}
package com.inspur.spring.config.datasource;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.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;@Configuration
@MapperScan(basePackages = "com.inspur.spring.dao.inspurzs", sqlSessionFactoryRef = "InspurZsSqlSessionFactory")
public class InspurZsDatasourceConfig {@Primary@Bean(value = "InspurZsDatasource")@ConfigurationProperties(prefix = "spring.datasource.inspur-zs-datasource")public DataSource getDateSource1() {return DataSourceBuilder.create().build();}@Primary@Bean(value = "InspurZsSqlSessionFactory")public SqlSessionFactory sqlSessionFactory(@Qualifier("InspurZsDatasource") DataSource datasource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(datasource);// 设置mybatis的xml所在位置bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/inspurzs/*.xml"));return bean.getObject();}@Bean(value = "InspurZsSqlSessionTemplate")@Primarypublic SqlSessionTemplate sqlSessionTemplate(@Qualifier("InspurZsSqlSessionFactory") SqlSessionFactory factory) {return new SqlSessionTemplate(factory);}@Beanpublic PlatformTransactionManager transactionManager(@Qualifier("InspurZsDatasource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}

@MapperScan注解中的basePackages指向的是指定的Dao层。
@MapperScan注解中sqlSessionFactoryRef 用来指定使用某个SqlSessionFactory来操作数据源。

 bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/inspurzs/*.xml"));

使用此种方法不会存在任何代码的冗余以及硬编码的存在,但是需要分层明确。唯一的不足就是添加一个数据源就需要重新写一个类,而这个类中的代码大部分又是相同的。

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

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

相关文章

系统中出现大量不可中断进程和僵尸进程怎么办?

进程状态 通过top命令&#xff0c;我们可以看到进程的状态(S列) toptop - 19:27:57 up 365 days, 25 min, 0 users, load average: 0.06, 0.05, 0.01 Tasks: 134 total, 1 running, 90 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.3 us, 0.5 sy, 0.0 ni, 99.2 id, …

Qt中ffmpeg API存储和显示摄像头视频

Qt中ffmpeg API存储和显示摄像头视频的功能需要之前写的视频ffmpegAPI的视频播放的流程。 代码源码位置&#xff1a;https://download.csdn.net/download/qq_43812868/88157743?spm1001.2014.3001.5503 一、存储和显示摄像头的视频的流程 这是读取打开视频文件的流程&#x…

【c++】内存管理

C/C内存管理 C/C内存分布 一个简单题 先试试看吧&#xff0c;答案在文章末尾给出 选择题&#xff1a; 选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区) globalVar在哪里&#xff1f;____ staticGlobalVar在哪里&#xff1f;____ staticVar在哪里&#xff1f;____ localVar在…

Docker容器

目录 1.docker简介 docker的优点&#xff1a; docker的应用&#xff1a; 2.docker的基本概念 1.镜像&#xff1a; 2.容器&#xff1a; 3.仓库 3.docker的安装部署&#xff08;yum&#xff09; 4.docker的基础命令 镜像操作&#xff1a; 容器操作&#xff1a; 进入容器…

【C++】开源:Eigen3矩阵与线性代数库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Eigen3矩阵与线性代数库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…

problem(3):python IDE和python解释器

为什么写这篇文章呢&#xff1f;遇到了下面的问题&#xff0c;相同的解释器&#xff0c;如果运行angr库的代码&#xff0c;会出现 这样的情况&#xff0c;但是用spyder IDE 会显示正常&#xff0c;很奇怪 应该就是IDE的原因 IDE的循环导入问题 检查IDE配置&#xff1a; 如果可…

一百四十四、Kettle——Linux上安装的kettle8.2连接MySQL数据库

一、目的 在Linux上安装好kettle&#xff0c;然后用kettle连接MySQL数据库 注意&#xff1a;kettle版本是8.2 二、实施步骤 &#xff08;一&#xff09;到kettle安装目录下启动Linux的kettle服务 # cd /opt/install/data-integration/ # ./spoon.sh &#xff08;二&#x…

SpringBoot搭建WebSocket初始化

1.java后端的maven添加websocket依赖 <!-- websocket依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>2.实例化ServerEndpointExport…

linux安装Java11,maven,docker,mysql,rabbitmq,nacos,redis,es一条龙服务

1 安装jdk11 # 第一步&#xff1a;上传或下载安装包 cd /usr/local jdk-11.0.9_linux-x64_bin.tar.gz# 第二步&#xff1a;解压安装包 tar -xzvf jdk-11.0.9_linux-x64_bin.tar.gz# 第三步&#xff1a;修改环境变量 vim /etc/profile#在末尾加入 JAVA_HOME/usr/local/jdk-11.…

踩坑(5)整合kafka 报错 java.net.UnknownHostException: 不知道这样的主机

java.net.UnknownHostException: 不知道这样的主机。 (5c0c3c629db9)at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) ~[na:na]at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:933) ~[na:na]at java.ba…

uniapp封装request请求

在基础文件里面创建一个api文件 在创建两个 js文件 http.js 里面封装 request 请求 let baseUrl https://white.51.toponet.cn; //基地址 export const request (options {}) > {//异步封装接口&#xff0c;使用Promise处理异步请求return new Promise((resolve, reject…

MySQL备份还原

mysql> create database school; mysql> use school; /* 1.创建student和score表 */ --创建student表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR…

typescript基础之关键字type

TypeScript的type是一个关键字&#xff0c;用来定义一个类型别名https://www.typescripttutorial.net/typescript-tutorial/typescript-types/。类型别名可以给一个已有的类型起一个新的名字&#xff0c;或者组合多个类型成为一个新的类型。例如&#xff1a; // 给string类型起…

React Antd 实现表格合计功能

思路&#xff1a;首先拿到 表格数组对象&#xff0c;然后写一个工具类&#xff0c;然后向数组对象最后插入一条数据&#xff0c;这条数据的字段时根据表格数组里合计算出来的。 代码如下&#xff0c;需根据各自业务稍作改动&#xff1a; <Table dataSource{tableData}column…

时间复杂度为O(nlogn)的两种排序算法

1.归并排序 归并排序的核心思想&#xff1a;如果要排序一个数组&#xff0c;我们先把数组从中间分成前后两部分&#xff0c;然后对前后两部分分别排序&#xff0c;再将排好序的两部分合并在一起&#xff0c;这样整个数组就都有序了。 归并排序使用的就是分治思想。分治&#x…

第2章 HTML中的JavaScript

引言 将JavaScript引入网页&#xff0c;首先要解决它与网页的主导语言HTML的关系问题 script元素 将JavaScript插入HTML的主要方法是使用script元素&#xff0c;script有8个可选属性 async&#xff1a;表示异步加载js文件内容&#xff0c;他们之间的顺序不一定按照html顺序ch…

IDEA强大的VisualGC插件

前言 开发阶段实时监测&#xff0c;自己的JVM信息&#xff0c;实时可视化 Hotspot JVM 垃圾回收监控工具, 支持查看本地和远程JVM进程, 支持G1 and ZGC算法。 插件安装 在线安装 IntelliJ IDEA 可通过在线安装的方式&#xff0c;安装插件 JDK VisualGC&#xff0c;安装步骤: …

DAY02_Spring第三方资源配置管理Spring容器Spring注解开发Spring整合Mybatis和Junit

目录 一 第三方资源配置管理1 管理DataSource连接池对象问题导入1.1 管理Druid连接池1.2 管理c3p0连接池 2 加载properties属性文件问题导入2.1 基本用法2.2 配置不加载系统属性2.3 加载properties文件写法 二 Spring容器1 Spring核心容器介绍问题导入1.1 创建容器1.2 获取bean…

JVM 类文件结构(class文件)

JVM 本文链接&#xff1a;https://blog.csdn.net/feather_wch/article/details/132116849 类文件结构 1、class文件的组成 无符号数&#xff1a;基本数据类型 u1 u2 u3 u4 描述 数字字符串索引引用 表&#xff1a;复合数据类型&#xff0c;无符号数 表组&#xff0c; _inf…

阿里云平台WoSignSSL证书应用案例

沃通CA与阿里云达成合作并在阿里云平台上线WoSign品牌SSL证书。自上线以来&#xff0c;WoSignSSL证书成为阿里云“数字证书管理服务”热销证书产品&#xff0c;获得阿里云平台客户认可&#xff0c;助力阿里云平台政府、金融、教育、供应链、游戏等各类行业客户实现网站系统数据…