开发环境:JDK1.8+SpringBoot2.1.4.RELEASE+Oracle

这里我们假设要使用两个数据源分别为:master和slave。

  • pom.xml 依赖包
org.springframework.bootspring-boot-starterorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-data-jpacom.github.norauiojdbc712.1.0.2org.apache.commonscommons-lang3org.mybatis.spring.bootmybatis-spring-boot-starter1.1.1
  • application.yml配置
server:  port: 50000 ---spring:  jpa:     hibernate:        ddlAuto: update    openInView: true    showSql: false    databasePlatform: org.hibernate.dialect.Oracle10gDialect---# 第一个数据源      master:   datasource:    driverClassName: oracle.jdbc.driver.OracleDriver    url: jdbc:oracle:thin:@localhost:1521/orcl    username: t0    password: t0    type: com.zaxxer.hikari.HikariDataSource    hikari:      minimumIdle: 10      maximumPoolSize: 200      autoCommit: true      idleTimeout: 30000      poolName: MasterDatabookHikariCP      maxLifetime: 1800000      connectionTimeout: 30000      connectionTestQuery: SELECT 1 FROM DUAL# 第二个数据源      slave:  datasource:    driverClassName: oracle.jdbc.driver.OracleDriver    url: jdbc:oracle:thin:@localhost:1521/orcl    username: t1    password: t1    type: com.zaxxer.hikari.HikariDataSource    hikari:      minimumIdle: 10      maximumPoolSize: 200      autoCommit: true      idleTimeout: 30000      poolName: SlaveDatabookHikariCP      maxLifetime: 1800000      connectionTimeout: 30000      connectionTestQuery: SELECT 1 FROM DUAL      ---# mybatis 配置,分表对应到不同的包中        master:  mybatis:    config-location: classpath:/MyBatis-conf.xml    type-aliases-package: com.pack.domain #master数据源对应的包    mapper-locations:    - classpath:/com/pack/mapper/oracle/*.xml #master数据源对应mapper文件slave:  mybatis:    config-location: classpath:/MyBatis-conf.xml    type-aliases-package: com.pack.slave.domain #slave数据源对应的包    mapper-locations:    - classpath:/com/pack/slave/mapper/oracle/*.xml    #slave数据源对应mapper文件---# jpa相关的配置master:  jpa:    repos: com.pack.base.repository #master数据源对应的包配置    domain: com.pack.domain #master对应的实体包slave:  jpa:    repos: com.pack.slave.repository #salve数据源对应的包配置    domain: com.pack.slave.domain  #slave对应的实体包

以上就是两个数据源对应相关的配置了,大家注意看里面的注释。接下来我们看mabatis和jpa对应的类相关的配置了,都是固定的配置。

  • 数据源属性配置对应的java类配置

BaseProperties类

public class BaseDataSourceProperties implements BeanClassLoaderAware, InitializingBean {private ClassLoader classLoader;/** * Name of the datasource. Default to "testdb" when using an embedded database. */private String name;/** * Whether to generate a random datasource name. */private boolean generateUniqueName;/** * Fully qualified name of the connection pool implementation to use. By default, it * is auto-detected from the classpath. */private Class extends DataSource> type;/** * Fully qualified name of the JDBC driver. Auto-detected based on the URL by default. */private String driverClassName;/** * JDBC URL of the database. */private String url;/** * Login username of the database. */private String username;/** * Login password of the database. */private String password;/** * JNDI location of the datasource. Class, url, username & password are ignored when * set. */private String jndiName;/** * Initialize the datasource with available DDL and DML scripts. */private DataSourceInitializationMode initializationMode = DataSourceInitializationMode.EMBEDDED;/** * Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or * data-${platform}.sql). */private String platform = "all";/** * Schema (DDL) script resource references. */private List schema;/** * Username of the database to execute DDL scripts (if different). */private String schemaUsername;/** * Password of the database to execute DDL scripts (if different). */private String schemaPassword;/** * Data (DML) script resource references. */private List data;/** * Username of the database to execute DML scripts (if different). */private String dataUsername;/** * Password of the database to execute DML scripts (if different). */private String dataPassword;/** * Whether to stop if an error occurs while initializing the database. */private boolean continueOnError = false;/** * Statement separator in SQL initialization scripts. */private String separator = ";";/** * SQL scripts encoding. */private Charset sqlScriptEncoding;private EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection.NONE;private Xa xa = new Xa();private String uniqueName;@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {this.classLoader = classLoader;}@Overridepublic void afterPropertiesSet() throws Exception {this.embeddedDatabaseConnection = EmbeddedDatabaseConnection.get(this.classLoader);}/** * Initialize a {@link DataSourceBuilder} with the state of this instance. * @return a {@link DataSourceBuilder} initialized with the customizations defined on * this instance */public DataSourceBuilder> initializeDataSourceBuilder() {return DataSourceBuilder.create(getClassLoader()).type(getType()).driverClassName(determineDriverClassName()).url(determineUrl()).username(determineUsername()).password(determinePassword());}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public boolean isGenerateUniqueName() {return this.generateUniqueName;}public void setGenerateUniqueName(boolean generateUniqueName) {this.generateUniqueName = generateUniqueName;}public Class extends DataSource> getType() {return this.type;}public void setType(Class extends DataSource> type) {this.type = type;}/** * Return the configured driver or {@code null} if none was configured. * @return the configured driver * @see #determineDriverClassName() */public String getDriverClassName() {return this.driverClassName;}public void setDriverClassName(String driverClassName) {this.driverClassName = driverClassName;}/** * Determine the driver to use based on this configuration and the environment. * @return the driver to use * @since 1.4.0 */public String determineDriverClassName() {if (StringUtils.hasText(this.driverClassName)) {Assert.state(driverClassIsLoadable(),() -> "Cannot load driver class: " + this.driverClassName);return this.driverClassName;}String driverClassName = null;if (StringUtils.hasText(this.url)) {driverClassName = DatabaseDriver.fromJdbcUrl(this.url).getDriverClassName();}if (!StringUtils.hasText(driverClassName)) {driverClassName = this.embeddedDatabaseConnection.getDriverClassName();}if (!StringUtils.hasText(driverClassName)) {throw new DataSourceBeanCreationException("Failed to determine a suitable driver class", this,this.embeddedDatabaseConnection);}return driverClassName;}private boolean driverClassIsLoadable() {try {ClassUtils.forName(this.driverClassName, null);return true;}catch (UnsupportedClassVersionError ex) {// Driver library has been compiled with a later JDK, propagate errorthrow ex;}catch (Throwable ex) {return false;}}/** * Return the configured url or {@code null} if none was configured. * @return the configured url * @see #determineUrl() */public String getUrl() {return this.url;}public void setUrl(String url) {this.url = url;}/** * Determine the url to use based on this configuration and the environment. * @return the url to use * @since 1.4.0 */public String determineUrl() {if (StringUtils.hasText(this.url)) {return this.url;}String databaseName = determineDatabaseName();String url = (databaseName != null)? this.embeddedDatabaseConnection.getUrl(databaseName) : null;if (!StringUtils.hasText(url)) {throw new DataSourceBeanCreationException("Failed to determine suitable jdbc url", this,this.embeddedDatabaseConnection);}return url;}/** * Determine the name to used based on this configuration. * @return the database name to use or {@code null} * @since 2.0.0 */public String determineDatabaseName() {if (this.generateUniqueName) {if (this.uniqueName == null) {this.uniqueName = UUID.randomUUID().toString();}return this.uniqueName;}if (StringUtils.hasLength(this.name)) {return this.name;}if (this.embeddedDatabaseConnection != EmbeddedDatabaseConnection.NONE) {return "testdb";}return null;}/** * Return the configured username or {@code null} if none was configured. * @return the configured username * @see #determineUsername() */public String getUsername() {return this.username;}public void setUsername(String username) {this.username = username;}/** * Determine the username to use based on this configuration and the environment. * @return the username to use * @since 1.4.0 */public String determineUsername() {if (StringUtils.hasText(this.username)) {return this.username;}if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName())) {return "sa";}return null;}/** * Return the configured password or {@code null} if none was configured. * @return the configured password * @see #determinePassword() */public String getPassword() {return this.password;}public void setPassword(String password) {this.password = password;}/** * Determine the password to use based on this configuration and the environment. * @return the password to use * @since 1.4.0 */public String determinePassword() {if (StringUtils.hasText(this.password)) {return this.password;}if (EmbeddedDatabaseConnection.isEmbedded(determineDriverClassName())) {return "";}return null;}public String getJndiName() {return this.jndiName;}/** * Allows the DataSource to be managed by the container and obtained via JNDI. The * {@code URL}, {@code driverClassName}, {@code username} and {@code password} fields * will be ignored when using JNDI lookups. * @param jndiName the JNDI name */public void setJndiName(String jndiName) {this.jndiName = jndiName;}public DataSourceInitializationMode getInitializationMode() {return this.initializationMode;}public void setInitializationMode(DataSourceInitializationMode initializationMode) {this.initializationMode = initializationMode;}public String getPlatform() {return this.platform;}public void setPlatform(String platform) {this.platform = platform;}public List getSchema() {return this.schema;}public void setSchema(List schema) {this.schema = schema;}public String getSchemaUsername() {return this.schemaUsername;}public void setSchemaUsername(String schemaUsername) {this.schemaUsername = schemaUsername;}public String getSchemaPassword() {return this.schemaPassword;}public void setSchemaPassword(String schemaPassword) {this.schemaPassword = schemaPassword;}public List getData() {return this.data;}public void setData(List data) {this.data = data;}public String getDataUsername() {return this.dataUsername;}public void setDataUsername(String dataUsername) {this.dataUsername = dataUsername;}public String getDataPassword() {return this.dataPassword;}public void setDataPassword(String dataPassword) {this.dataPassword = dataPassword;}public boolean isContinueOnError() {return this.continueOnError;}public void setContinueOnError(boolean continueOnError) {this.continueOnError = continueOnError;}public String getSeparator() {return this.separator;}public void setSeparator(String separator) {this.separator = separator;}public Charset getSqlScriptEncoding() {return this.sqlScriptEncoding;}public void setSqlScriptEncoding(Charset sqlScriptEncoding) {this.sqlScriptEncoding = sqlScriptEncoding;}public ClassLoader getClassLoader() {return this.classLoader;}public Xa getXa() {return this.xa;}public void setXa(Xa xa) {this.xa = xa;}/** * XA Specific datasource settings. */public static class Xa {/** * XA datasource fully qualified name. */private String dataSourceClassName;/** * Properties to pass to the XA data source. */private Map properties = new LinkedHashMap<>();public String getDataSourceClassName() {return this.dataSourceClassName;}public void setDataSourceClassName(String dataSourceClassName) {this.dataSourceClassName = dataSourceClassName;}public Map getProperties() {return this.properties;}public void setProperties(Map properties) {this.properties = properties;}}static class DataSourceBeanCreationException extends BeanCreationException {/** *  */private static final long serialVersionUID = 1L;private final BaseDataSourceProperties properties;private final EmbeddedDatabaseConnection connection;DataSourceBeanCreationException(String message, BaseDataSourceProperties properties,EmbeddedDatabaseConnection connection) {super(message);this.properties = properties;this.connection = connection;}public BaseDataSourceProperties getProperties() {return this.properties;}public EmbeddedDatabaseConnection getConnection() {return this.connection;}}}

mybatis对应的base属性文件

public class BaseMybatisProperties {/** * Config file path. */private String configLocation;/** * Location of mybatis mapper files. */private String[] mapperLocations;/** * Package to scan domain objects. */private String typeAliasesPackage;/** * Package to scan handlers. */private String typeHandlersPackage;/** * Check the config file exists. */private boolean checkConfigLocation = false;/** * Execution mode for {@link org.mybatis.spring.SqlSessionTemplate}. */private ExecutorType executorType;/** * A Configuration object for customize default settings. If * {@link #configLocation} is specified, this property is not used. */private Configuration configuration;/** * @since 1.1.0 * @return */public String getConfigLocation() {return this.configLocation;}/** * @since 1.1.0 * @return */public void setConfigLocation(String configLocation) {this.configLocation = configLocation;}@Deprecatedpublic String getConfig() {return this.configLocation;}@Deprecatedpublic void setConfig(String config) {this.configLocation = config;}public String[] getMapperLocations() {return this.mapperLocations;}public void setMapperLocations(String[] mapperLocations) {this.mapperLocations = mapperLocations;}public String getTypeHandlersPackage() {return this.typeHandlersPackage;}public void setTypeHandlersPackage(String typeHandlersPackage) {this.typeHandlersPackage = typeHandlersPackage;}public String getTypeAliasesPackage() {return this.typeAliasesPackage;}public void setTypeAliasesPackage(String typeAliasesPackage) {this.typeAliasesPackage = typeAliasesPackage;}public boolean isCheckConfigLocation() {return this.checkConfigLocation;}public void setCheckConfigLocation(boolean checkConfigLocation) {this.checkConfigLocation = checkConfigLocation;}public ExecutorType getExecutorType() {return this.executorType;}public void setExecutorType(ExecutorType executorType) {this.executorType = executorType;}public Configuration getConfiguration() {return configuration;}public void setConfiguration(Configuration configuration) {this.configuration = configuration;}public Resource[] resolveMapperLocations() {List resources = new ArrayList();if (this.mapperLocations != null) {for (String mapperLocation : this.mapperLocations) {Resource[] mappers;try {mappers = new PathMatchingResourcePatternResolver().getResources(mapperLocation);resources.addAll(Arrays.asList(mappers));} catch (IOException e) {}}}Resource[] mapperLocations = new Resource[resources.size()];mapperLocations = resources.toArray(mapperLocations);return mapperLocations;}}

因为我们使用的是Hikari数据源,所以这里我是直接copy默认系统Hikari的属性文件。

也就是这个文件:org.springframework.boot.autoconfigure.jdbc.DataSourceProperties 为啥我不直接继承这个类而是在自己的项目中新建这么一个类,是因为我发现这个类有这个注解

@ConfigurationProperties(prefix = "spring.datasource")

怕的是它的这个注解会覆盖我接下来两个类的注解(我主要是懒得测试,所以直接copy一份无所谓了)。

接下来看看具体master和slave两个数据源的属性文件:

  • Properties(jpa和mybatis)文件
@Component@ConfigurationProperties(prefix = "master.datasource")public class MasterDataSourceProperties extends BaseDataSourceProperties {}
@Component@ConfigurationProperties(prefix = "slave.datasource")public class SlaveDataSourceProperties extends BaseDataSourceProperties {}
@Component@ConfigurationProperties(prefix = "master.mybatis")public class MasterMybatisProperties extends BaseMybatisProperties {}
@Component@ConfigurationProperties(prefix = "slave.mybatis")public class SlaveMybatisProperties extends BaseMybatisProperties {}

接下来是数据源的配置了。

  • 数据源配置类
@Configurationpublic class HikariDataSourceConfig {@Bean@Primarypublic HikariDataSource masterDataSource(MasterDataSourceProperties properties) {HikariDataSource dataSource = createDataSource(properties,HikariDataSource.class);if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}@Beanpublic HikariDataSource slaveDataSource(SlaveDataSourceProperties properties) {HikariDataSource dataSource = createDataSource(properties,HikariDataSource.class);if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}@SuppressWarnings("unchecked")protected static  T createDataSource(BaseDataSourceProperties properties,Class extends DataSource> type) {return (T) properties.initializeDataSourceBuilder().type(type).build();}}

因为我们配置的是多个数据源所有其中一个数据源必须加入这个注解@Primary

接下来是jpa的EntityManagerFactory工厂的配置了

  • EntityManagerFactory配置
public class EntityManagerFactoryConfig {@Configuration@EnableJpaRepositories(basePackages = {"${master.jpa.repos}" }, entityManagerFactoryRef = "masterEntityManagerFactory", transactionManagerRef = "masterJPATransactionManager")static class MasterEntityManagerFactory {@Resource(name = "masterDataSource")private DataSource masterDataSource;@Value("${master.jpa.domain}")private String masterDomainPkg;@Bean@Primarypublic LocalContainerEntityManagerFactoryBean masterEntityManagerFactory(EntityManagerFactoryBuilder builder) {Map properties = new HashMap<>();properties.put("hibernate.hbm2ddl.auto", "update");properties.put("hibernate.id.new_generator_mappings", true);properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName()) ;return builder.dataSource(masterDataSource).packages(masterDomainPkg).persistenceUnit("master").properties(properties).build();}@Bean@Primarypublic PlatformTransactionManager masterJPATransactionManager(EntityManagerFactoryBuilder builder) {JpaTransactionManager tm = new JpaTransactionManager(masterEntityManagerFactory(builder).getObject());return tm;}}@Configuration@EnableJpaRepositories(basePackages = {"${slave.jpa.repos}" }, entityManagerFactoryRef = "slaveEntityManagerFactory", transactionManagerRef = "slaveJPATransactionManager")@ConditionalOnProperty(name = "multiple.ds.enabled", havingValue = "true")static class SlaveEntityManagerFactory {@Resource(name = "slaveDataSource")private DataSource slaveDataSource;@Value("${slave.jpa.domain}")private String slaveDomainPkg;@Beanpublic LocalContainerEntityManagerFactoryBean slaveEntityManagerFactory(EntityManagerFactoryBuilder builder) {Map properties = new HashMap<>();properties.put("hibernate.hbm2ddl.auto", "update");properties.put("hibernate.id.new_generator_mappings", true);properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName()) ;return builder.dataSource(slaveDataSource).packages(slaveDomainPkg).persistenceUnit("slave").properties(properties).build();}@Beanpublic PlatformTransactionManager slaveJPATransactionManager(EntityManagerFactoryBuilder builder) {JpaTransactionManager tm = new JpaTransactionManager(slaveEntityManagerFactory(builder).getObject());return tm;}}}
  • mybatis SqlSessionFactory工厂配置
public class SqlSessionFactoryConfig {@Configurationstatic class MasterSqlSessionFactory {@Resourceprivate MasterMybatisProperties properties;@Autowired(required = false)private Interceptor[] interceptors;@Autowiredprivate ResourceLoader resourceLoader = new DefaultResourceLoader();@Autowired(required = false)private DatabaseIdProvider databaseIdProvider;@Beanpublic SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean factory = new SqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setVfs(SpringBootVFS.class);if (StringUtils.hasText(this.properties.getConfigLocation())) {factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));}factory.setConfiguration(properties.getConfiguration());if (!ObjectUtils.isEmpty(this.interceptors)) {factory.setPlugins(this.interceptors);}if (this.databaseIdProvider != null) {factory.setDatabaseIdProvider(this.databaseIdProvider);}if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());}if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());}if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {factory.setMapperLocations(this.properties.resolveMapperLocations());}return factory.getObject();}@Bean    public DataSourceTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {        return new DataSourceTransactionManager(dataSource);    }@Beanpublic SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory")SqlSessionFactory sqlSessionFactory) {ExecutorType executorType = this.properties.getExecutorType();if (executorType != null) {return new SqlSessionTemplate(sqlSessionFactory, executorType);} else {return new SqlSessionTemplate(sqlSessionFactory);}}}@Configuration@ConditionalOnProperty(name = "multiple.ds.enabled", havingValue = "true")static class SlaveSqlSessionFactory {@Resourceprivate SlaveMybatisProperties properties;@Autowired(required = false)private Interceptor[] interceptors;@Autowiredprivate ResourceLoader resourceLoader = new DefaultResourceLoader();@Autowired(required = false)private DatabaseIdProvider databaseIdProvider;@Beanpublic SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean factory = new SqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setVfs(SpringBootVFS.class);if (StringUtils.hasText(this.properties.getConfigLocation())) {factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));}factory.setConfiguration(properties.getConfiguration());if (!ObjectUtils.isEmpty(this.interceptors)) {factory.setPlugins(this.interceptors);}if (this.databaseIdProvider != null) {factory.setDatabaseIdProvider(this.databaseIdProvider);}if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());}if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());}if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {factory.setMapperLocations(this.properties.resolveMapperLocations());}return factory.getObject();}@Bean    public DataSourceTransactionManager slaveTransactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {        return new DataSourceTransactionManager(dataSource);    }@Beanpublic SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("slaveSqlSessionFactory")SqlSessionFactory sqlSessionFactory) {ExecutorType executorType = this.properties.getExecutorType();if (executorType != null) {return new SqlSessionTemplate(sqlSessionFactory, executorType);} else {return new SqlSessionTemplate(sqlSessionFactory);}}}}

接下来还需要配置mapper相关的配置

  • mapper配置
public class MapperScanConfig {@Configuration@MapperScan(basePackages = {"com.pack.base.mapper"}, sqlSessionTemplateRef  = "masterSqlSessionTemplate")static class MasterMapper {}@Configuration@MapperScan(basePackages = {"com.pack.slave.mapper"}, sqlSessionTemplateRef  = "slaveSqlSessionTemplate")@ConditionalOnProperty(name = "multiple.ds.enabled", havingValue = "true")static class SlaveMapper {}}

到这里我们所有的相关配置就完成了,接下来我们只需建立对应的包即可。

MyBatis-conf.xml配置文件内容如下:

测试:

建立com.pack.domain包,然后新建类Users.java

@Entity@Table(name = "T_USERS")@Datapublic class Users {  @Id  private Long id;private String username ;private String password ;private String realName ;private String phone ;private String idNo ;@Column(length=4000)private String authority ;@Column(columnDefinition="int default 0")private Integer status = 0 ;}

建立包com.pack.slave.domain,然后新建类

@Entity@Table(name = "T_PERSON")@Datapublic class Person{  @Id  private Long id;private String name ;private String email ;}

dao我就不写了。我们启动服务器分别在不同的用户下查看表是否建立,如果都建立了就表示成功。

完毕!!!

给个关注,给个赞呗,谢谢!!!

SpringBoot+Atomikos多数据源分布式事务

分布式事务框架Seata之AT模式

SpringCloud zuul 动态网关配置

SpringMVC参数统一验证方法

hikari数据源配置类_SpringBoot多数据源配置详解相关推荐

  1. Tomcat安装、配置、优化及负载均衡详解

    博客园 首页 新随笔 联系 管理 订阅 随笔- 31  文章- 0  评论- 25  Tomcat安装.配置.优化及负载均衡详解 一.常见JavaWeb服务器      1.WebLogic:是BEA ...

  2. Linux配置启动挂载:fstab文件详解

    Linux配置启动挂载:fstab文件详解 [日期:2014-12-23] 来源:Linux社区 作者:aceking10 [字体:大 中 小] fstab文件介绍 fstab文件包含了你的电脑上的存 ...

  3. linux下 卸载qt_Ubuntu14.04安装、配置与卸载QT5的步骤详解

    1.之前我下载的是QT5.13版本但是安装结束后Qtcreator出现打不开,这里我推荐Qt5.9版本,下载网址如下: https://download.qt.io/official_releases ...

  4. 尼尔机器人技能快捷键_尼尔机械纪元武器配置及全出招操作详解-游侠网

    看着游戏女主华丽的招式是不是很羡慕呢,其实只要掌握了一些出招操作,你也可以做到,那么怎么操作呢?小编这就给大家分享下尼尔机械纪元武器配置及全出招操作详解,一起看下吧. 武器配置1: 轻型刀装备于轻栏位 ...

  5. php自动加载类与路由,PHP实现路由与类自动加载步骤详解

    这次给大家带来PHP实现路由与类自动加载步骤详解,PHP实现路由与类自动加载步骤详解的注意事项有哪些,下面就是实战案例,一起来看一下. 项目目录如下 入口文件index.php<?php def ...

  6. C++友元函数和友元类(C++ friend)详解

    在看VISP视觉库的时候遇到友元函数: Friends void swap (vpDetectorAprilTag &o1, vpDetectorAprilTag &o2) 在定义一个 ...

  7. Java类的加载过程详解 面试高频!!!值得收藏!!!

    受多种情况的影响,又开始看JVM 方面的知识. 1.Java 实在过于内卷,没法不往深了学. 2.面试题问的多,被迫学习. 3.纯粹的好奇. 很喜欢一句话: 八小时内谋生活,八小时外谋发展. 望别日与 ...

  8. 中yeti不能加载_第二十章_类的加载过程详解

    类的加载过程详解 概述 在 Java 中数据类型分为基本数据类型和引用数据类型.基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载 按照 Java 虚拟机规范,从 Class 文件到加载到内 ...

  9. python跨函数调用变量_对python中不同模块(函数、类、变量)的调用详解

    首先,先介绍两种引入模块的方法. 法一:将整个文件引入 import 文件名 文件名.函数名( ) / 文件名.类名 通过这个方法可以运行另外一个文件里的函数 法二:只引入某个文件中一个类/函数/变量 ...

最新文章

  1. java raster_Raster (Java 2 Platform SE 5.0)
  2. Spring Boot 实战 —— MyBatis(注解版)使用方法
  3. 每天一道LeetCode-----寻找两个链表的交点
  4. spark集群详细搭建过程及遇到的问题解决(三)
  5. c语言malloc calloc,C语言内存管理:malloc、calloc、free的实现
  6. 错误整理:No plugin found for prefix 'jetty' in the current project and in the plugin groups
  7. git回滚到之前代码
  8. 格子刷油漆c++dp(最详细)
  9. 连接到此计算机的本地打印机无法选择,Win7系统连接打印机出现本地打印后台处理程序服务没有运行怎么办...
  10. 我用英语了结你的一生1
  11. 二维彩虹二维码产品功能更新:增加“赞赏”、“重置”功能
  12. 数学分析 - 隐函数
  13. [运维] linux定时关机命令
  14. 云队友丨张一鸣重在思考
  15. 全球与中国汽车线性稳压器市场运营状况及未来前景展望报告2022-2028年版
  16. 如何定义日志消息的级别?详解日志的5个级别
  17. 基于Matlab的3-D胸部扫描CT切片的肺部分割——使用活动轮廓(snakes)进行三维分割及建模
  18. c语言中的原码反码补码,c语言中的原码 反码 补码
  19. Zookeeper锁实现分布式锁解决高并发高可用秒杀系统
  20. gis根据行政区计算栅格数据计算_ARCGIS栅格计算器

热门文章

  1. jsp页面javascript没反应
  2. 车辆动力学及控制_第一届国际轮胎动力学仿真技术峰会在长春举行
  3. c语言省二历年真题讲解安徽,安徽省计算机等级二考试真题C语言年12月.doc
  4. js文件,同样的路径,拷贝过来的为什么不能访问
  5. CKEditor的使用,并实现图片上传
  6. 构建自己的PHP框架(ORM)
  7. Day Tips:关于搜索小问题
  8. why do we use process keys
  9. 面向手绘图形,涵盖多个主题,CVPR 2022 SketchDL Workshop开始征稿!
  10. 经典重温:FAIR提出SlowFast,用双分支非对称网络处理不同采样率的视频!代码开源!...