数据源 订阅
数据源是指数据库应用程序所使用的数据库或者数据库服务器。数据源(Data Source)顾名思义,数据的来源,是提供某种所需要数据的器件或原始媒体。在数据源中存储了所有建立数据库连接的信息。就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数据源名称,你可以找到相应的数据库连接。 展开全文
数据源是指数据库应用程序所使用的数据库或者数据库服务器。数据源(Data Source)顾名思义,数据的来源,是提供某种所需要数据的器件或原始媒体。在数据源中存储了所有建立数据库连接的信息。就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数据源名称,你可以找到相应的数据库连接。
信息
外文名
Data Source
中文名
数据源
数据源分类
信息系统的数据源必需可靠且具备更新能力,常用的数据源有:①观测数据,即现场获取的实测数据,它们包括野外实地勘测、量算数据,台站的观测记录数据,遥测数据等。②分析测定数据,即利用物理和化学方法分析测定的数据。③图形数据,各种地形图和专题地图等。④统计调查数据,各种类型的统计报表、社会调查数据等。⑤遥感数据,由地面、航空或航天遥感获得的数据。中国的数据源数量庞大。如:全国范围的土地资源清查及详查数据,航空摄影测量图像和国土普查卫星资料已覆盖全国,定位、半定位观测站网遍布全国,有地面调查、地图测绘等大量数据。上面提到的数据源例子只是很小一部 分,事实上数据源可以是任何数据类型。
收起全文
精华内容
下载资源
问答
  • Spring Boot 默认数据源 HikariDataSource 与 JdbcTemplate

    万次阅读 多人点赞 2018-08-19 08:37:07
    默认数据源 CRUD 数据库 PhoneController 测试结果 自动配置原理 DataSourceConfiguration 1、《Spring Boot 数据库访问 简介》中已经介绍,Spring Boot 可以通过多种方式访问各种数据库,本文将介绍 Spr...

    目录

    环境准备与依赖

    数据库 CRUD

    默认数据源 HikariDataSource

    JdbcTemplate CRUD 数据库

    数据源自动配置原理


    环境准备与依赖

    1、本文介绍 Spring Boot 内部集成的 JDBC 模板访问 Mysql 数据库,环境:java jdk 1.8 + Spring boot 2.0.4 + Mysql 。

    2、pom. xml 依赖如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>www.wmx.com.horse</groupId>
        <artifactId>horse</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>horse</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
            <relativePath/>
            <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <!-- 引入Spring封装的jdbc-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
    
            <!-- 引入html模板引擎Thymeleaf-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    
            <!-- 因为web项目启动模块-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- 引入mysql数据库连接驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
    
            <!-- 引入Spring Boot 测试模块-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <!-- Spring Boot 打包插件-->
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    mysql 数据库

    1、此 Mysql 数据库是在 CentOS 7.2 中的 Docker 容器中,所以用了 CentOS 的 3307 端口映射了 Docker 容器的 3306 端口,CentOS 主机 ip 为 192.168.58.129

    2、账号 root、密码 root。

    数据库 CRUD

    1、全局配置文件内容如下:

    spring:
      datasource:
        username: root
        password: root
        url: jdbc:mysql://192.168.58.129:3307/horse?characterEncoding=UTF-8
        driver-class-name: com.mysql.jdbc.Driver
    高版本的 spring boot 搭配 mysql 驱动版本较高时,如 mysql-connector-java:8.0.16,此时 driver-class-name 的值要带 cj;url 的值要带时区 serverTimezone,如:
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

    1、配置的内容以及意义就如同以前在 Sping 核心配置文件 beans.xml 中配置时是一样的

    2、到这里就已经可以操作数据库了,因为 Spring Boot 都已经自动配置好了,如 Spring Boot 默认已经提供了数据源

    3、关于上面的数据源配置内容,都可以从 Spring Boot 官方文档 查看

    # DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
    spring.datasource.continue-on-error=false # Whether to stop if an error occurs while initializing the database.
    spring.datasource.data= # Data (DML) script resource references.
    spring.datasource.data-username= # Username of the database to execute DML scripts (if different).
    spring.datasource.data-password= # Password of the database to execute DML scripts (if different).
    spring.datasource.dbcp2.*= # Commons DBCP2 specific settings
    spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
    spring.datasource.generate-unique-name=false # Whether to generate a random datasource name.
    spring.datasource.hikari.*= # Hikari specific settings
    spring.datasource.initialization-mode=embedded # Initialize the datasource with available DDL and DML scripts.
    spring.datasource.jmx-enabled=false # Whether to enable JMX support (if provided by the underlying pool).
    spring.datasource.jndi-name= # JNDI location of the datasource. Class, url, username & password are ignored when set.
    spring.datasource.name= # Name of the datasource. Default to "testdb" when using an embedded database.
    spring.datasource.password= # Login password of the database.
    spring.datasource.platform=all # Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or data-${platform}.sql).
    spring.datasource.schema= # Schema (DDL) script resource references.
    spring.datasource.schema-username= # Username of the database to execute DDL scripts (if different).
    spring.datasource.schema-password= # Password of the database to execute DDL scripts (if different).
    spring.datasource.separator=; # Statement separator in SQL initialization scripts.
    spring.datasource.sql-script-encoding= # SQL scripts encoding.
    spring.datasource.tomcat.*= # Tomcat datasource specific settings
    spring.datasource.type= # Fully qualified name of the connection pool implementation to use. By default, it is auto-detected from the classpath.
    spring.datasource.url= # JDBC URL of the database.
    spring.datasource.username= # Login username of the database.
    spring.datasource.xa.data-source-class-name= # XA datasource fully qualified name.
    spring.datasource.xa.properties= # Properties to pass to the XA data source.

    4、也可以从 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties 数据源配置文件类中进行查看

    默认数据源 HikariDataSource

    1、全局配置文件 application.yml 中 spring.datasource 下只配置了账号、密码、数据库地址、连接驱动,因为默认使用的是 class com.zaxxer.hikari.HikariDataSource 数据源

    2、如果过是自定义数据源,比如 DruidDataSource,则可以使用 type 指定,如下所示:type: com.alibaba.druid.pool.DruidDataSource,可以参考《切换 Druid 数据源

    3、测试数据源如下:

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import javax.annotation.Resource;
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.SQLException;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class HorseApplicationTests {
        /**
         * Spring Boot 默认已经配置好了数据源,程序员可以直接 DI 注入然后使用即可
         */
        @Resource
        DataSource dataSource;
        @Test
        public void contextLoads() throws SQLException {
     Connection connection = dataSource.getConnection();
            DatabaseMetaData metaData = connection.getMetaData();
    
            //数据源>>>>>>class com.zaxxer.hikari.HikariDataSource
            System.out.println("数据源>>>>>>" + dataSource.getClass());
            System.out.println("连接>>>>>>>>" + connection);
            System.out.println("连接地址>>>>" + connection.getMetaData().getURL());
            System.out.println("驱动名称>>>>" + metaData.getDriverName());
            System.out.println("驱动版本>>>>" + metaData.getDriverVersion());
            System.out.println("数据库名称>>" + metaData.getDatabaseProductName());
            System.out.println("数据库版本>>" + metaData.getDatabaseProductVersion());
            System.out.println("连接用户名称>" + metaData.getUserName());
    
            connection.close();
        }
    }
    

    1、可以看出 Spring Boot 2.0.4 默认使用 com.zaxxer.hikari.HikariDataSource 数据源,而以前版本,如 Spring Boot 1.5 默认使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源;

    2、HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;

    3、HikariDataSource 的内容本文暂时不做延伸,有了数据库连接,显然就可以 CRUD 操作数据库了。

    JdbcTemplate CRUD 数据库

    1、有了数据源(com.zaxxer.hikari.HikariDataSource),然后拿到l了数据库连接(java.sql.Connection),自然就可以使用连接和原生的 JDCB 语句来操作数据库

    2、即使不使用第三方第数据库操作框架,如 MyBatis、Hibernate 、JDBC Utils 等,Spring 本身也对 原生的 JDBC 做了轻量级的封装,即 org.springframework.jdbc.core.JdbcTemplate。这原本是 Spring 的知识点!

    3、数据库操作的所有 CRUD 方法都在 JdbcTemplate 中,有了 JdbcTemplate 就能更加轻松的操作数据库。

    4、Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用

    5、JdbcTemplate  的自动配置原理是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration 类

    PhoneController 控制层

    1、为了尽可能符合实际开发,新建一个控制层,通过浏览器访问来进行 CRUD,但是不再进行细致的分层,如 dao、service、domain 等都省略

    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import javax.annotation.Resource;
    import java.util.List;
    import java.util.Map;
    /**
     * Created by Administrator on 2018/8/19 0019.
     */
    @Controller
    public class PhoneController {
        /**
         * JdbcTemplate 是 core 包的核心类,用于简化 JDBC 操作,还能避免一些常见的错误,如忘记关闭数据库连接
         * Spring Boot 默认提供了数据源,默认提供了 org.springframework.jdbc.core.JdbcTemplate
         * JdbcTemplate 中会自己注入数据源,使用起来也不用再自己来关闭数据库连接
         */
        @Resource
        JdbcTemplate jdbcTemplate;
        /**
         * 查询 phone 表所有数据
         *
         * @return
         */
        @ResponseBody
        @GetMapping("phoneList")
        public List<Map<String, Object>> userList() {
            /**
             * 查询 phone 表所有数据
             * List 中的1个 Map 对应数据库的 1行数据
             * Map 中的 key 对应数据库的字段名,value 对应数据库的字段值
             */
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList("SELECT * FROM phone");
            return mapList;
        }
        /**
         * 新增 phone 数据
         *
         * @return
         */
        @GetMapping("savePhone")
        public String savePhone() {
            String sql = "INSERT INTO phone(number,region) VALUES (?,?)";
            Object[] objects = new Object[2];
            objects[0] = "18673886425";
            objects[1] = "湖南";
    
            jdbcTemplate.update(sql, objects);
            return "forward:/phoneList";
        }
        /**
         * 修改 phone 数据
         *
         * @return
         */
        @GetMapping("updatePhone")
        public String updatePhone() {
            String sql = "UPDATE phone SET number=? WHERE pid=?";
            Object[] objects = new Object[2];
            objects[0] = "18666668888";
            objects[1] = "1";
    
            jdbcTemplate.update(sql, objects);
            return "forward:/phoneList";
        }
        /**
         * 删除 phone 数据
         * update 方法可以做查询以外的 增加、修改、删除操作
         *
         * @return
         */
        @GetMapping("deletePhone")
        public String deletePhone() {
            String sql = "DELETE FROM phone WHERE number=?";
            Object[] objects = new Object[1];
            objects[0] = "18673886425";
    
            jdbcTemplate.update(sql, objects);
            return "forward:/phoneList";
        }
    }
    

    1、浏览器访问测试

    查询:http://localhost:8080/phoneList
    添加:http://localhost:8080/savePhone
    修改:http://localhost:8080/updatePhone
    删除:http://localhost:8080/deletePhone

     

    数据源自动配置原理

    1、自动配置都在 org.springframework.boot.autoconfigure.jdbc 包下。

    2、org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration 数据源配置类作用是根据逻辑判断之后,添加数据源

    3、SpringBoot 默认支持如下数据源;

    1、com.zaxxer.hikari.HikariDataSource (Spring Boot 2.0 以上,默认使用此数据源)
    2、org.apache.tomcat.jdbc.pool.DataSource
    3、org.apache.commons.dbcp2.BasicDataSource

    4、可以使用 spring.datasource.type 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。默认情况下,它是从类路径自动检测的。

        @ConditionalOnMissingBean({DataSource.class})
        @ConditionalOnProperty(
            name = {"spring.datasource.type"}
        )
        static class Generic {
            Generic() {
            }
            @Bean
            public DataSource dataSource(DataSourceProperties properties) {
                return properties.initializeDataSourceBuilder().build();
            }
        }

    Spring Boot 自定义数据源 DruidDataSource

    展开全文
  • MybatisPlus--切换多个数据源

    万次阅读 2020-08-18 02:20:19
    数据源配置 MP官网的文档写的很详细,这里不做累赘直接截图 从其特性可以看出MP对于常见的框架都有继承案例 特性12条是关于sharding-jdbc的集成, 我的sharding-jdbc专栏 集成案例 第一步、引入依赖 <!-- ...

    官方文档

    多数据源配置


    MP官网的文档写的很详细,这里不做累赘直接截图
    在这里插入图片描述
    从其特性可以看出MP对于常见的框架都有继承案例

    特性12条是关于sharding-jdbc的集成, 我的sharding-jdbc专栏
    集成案例


    第一步、引入依赖

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

    第二步、添加多数据源配置

    spring:
      datasource:
        dynamic:
          primary: master #设置默认的数据源或者数据源组,默认值即为master
          strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源.
          datasource:
            master:
              url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
            slave_1:
              url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
            slave_2:
              url: ENC(xxxxx) # 内置加密,使用请查看详细文档
              username: ENC(xxxxx)
              password: ENC(xxxxx)
              driver-class-name: com.mysql.jdbc.Driver
              schema: db/schema.sql # 配置则生效,自动初始化表结构
              data: db/data.sql # 配置则生效,自动初始化数据
              continue-on-error: true # 默认true,初始化失败是否继续
              separator: ";" # sql默认分号分隔符
              
           #......省略
           #以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
    

    第三步、通过注解指定操作的数据源

    使用 @DS切换数据源。

    @DS可以注解在方法上和类上,同时存在则 方法注解优先于类上注解

    强烈建议只注解在service实现上。
    注解 结果
    没有@DS 默认数据源
    @DS(“dsName”) dsName可以为组名也可以为具体某个库的名称

    如下注解的使用案例

    @Service
    @DS("slave") //注解在类上
    public class UserServiceImpl implements UserService {
    
      @Autowired
      private JdbcTemplate jdbcTemplate;
    
      public List selectAll() {
        return  jdbcTemplate.queryForList("select * from user");
      }
      
      @Override
      @DS("slave_1") //注解在方法上,指明使用数据源使用名字叫 slave_1 的数据源
      public List selectByCondition() {
        return  jdbcTemplate.queryForList("select * from user where age >10");
      }
    }
    
    展开全文
  • DataSource数据源简单理解

    万次阅读 多人点赞 2018-06-22 11:40:17
    DataSource数据源简单理解 因为热爱,所以拼搏。 –RuiDer 什么是数据源 JDBC2.0 提供了javax.sql.DataSource接口,它负责建立与数据库的连接,当在应用程序中访问数据库时 不必编写连接数据库的代码,...

    DataSource数据源简单理解


    因为热爱,所以拼搏。 –RuiDer


    什么是数据源

    JDBC2.0 提供了javax.sql.DataSource接口,它负责建立与数据库的连接,当在应用程序中访问数据库时
    不必编写连接数据库的代码,直接引用DataSource获取数据库的连接对象即可。用于获取操作数据Connection对象。

    数据源与数据库连接池

    数据源建立多个数据库连接,这些数据库连接会保存在数据库连接池中,当需要访问数据库时,只需要从数据库连接池中
    获取空闲的数据库连接,当程序访问数据库结束时,数据库连接会放回数据库连接池中。
    
    

    数据源DataSource与JNDI

    数据源DataSource是JNDI资源的一种,很简单,就是将“DataSource”字符串名称与真正的DataSource对象绑定起来,方便获取。
    
    

    数据库连接池的优势

    传统的JDBC访问数据库技术,每次访问数据库都需要通过数据库驱动器Driver和数据库名称以及密码等等资源建立数据库连接。
    这样的连接存在两大问题:
    
    1. 频繁的建立数据库连接与断开数据库,这样会消耗大量的资源和时间,降低性能。
    
    2. 数据库的连接需要用户名和密码等等,这些需要一定的内存和CPU一定开销。
    
    

    About Me

    欢迎各位读者访问,大家一起相互学习。
    带给你惊喜的不是我,也不是他,而是技术。
    我的博客

    我的GitHub

    展开全文
  • 项目地址:https://github.com/helloworlde/SpringBoot-DynamicDataSource/tree/dev 在 Spring Boot... 在这个项目中使用注解方式声明要使用的数据源,通过 AOP 查找注解,从而实现数据源的动态切换;该项目为 Product

    项目地址 https://github.com/helloworlde/SpringBoot-DynamicDataSource

    本项目使用 Spring Boot 和 MyBatis 实现多数据源,动态数据源的切换;有多种不同的实现方式,在学习的过程中发现没有文章将这些方式和常见的问题集中处理,所以将常用的方式和常见的问题都写在了在本项目的不同分支上:

    • master: 使用了多数据源的 RESTful API 接口,使用 Druid 实现了 DAO 层数据源动态切换和只读数据源负载均衡
    • dev: 最简单的切面和注解方式实现的动态数据源切换
    • druid: 通过切面和注解方式实现的使用 Druid 连接池的动态数据源切换
    • aspect_dao: 通过切面实现的 DAO 层的动态数据源切换
    • roundrobin: 通过切面使用轮询方式实现的只读数据源负载均衡
    • hikari: 升级到SpringBoot 2.0, 数据源使用 Hikari

    以上分支都是基于 dev 分支修改或扩充而来,基本涵盖了常用的多数据源动态切换的方式,基本的原理都一样,都是通过切面根据不同的条件在执行数据库操作前切换数据源

    在使用的过程中基本踩遍了所有动态数据源切换的坑,将常见的一些坑和解决方法写在了 Issues 里面

    该项目使用了一个可写数据源和多个只读数据源,为了减少数据库压力,使用轮循的方式选择只读数据源;考虑到在一个 Service 中同时会有读和写的操作,所以本应用使用 AOP 切面通过 DAO 层的方法名切换只读数据源;但这种方式要求数据源主从一致,并且应当避免在同一个 Service 方法中写入后立即查询,如果必须在执行写入操作后立即读取,应当在 Service 方法上添加 @Transactional 注解以保证使用主数据源

    需要注意的是,使用 DAO 层切面后不应该在 Service 类层面上加 @Transactional 注解,而应该添加在方法上,这也是 Spring 推荐的做法

    动态切换数据源依赖 configuration 包下的4个类来实现,分别是:

    • DataSourceRoutingDataSource.java
    • DataSourceConfigurer.java
    • DynamicDataSourceContextHolder.java
    • DynamicDataSourceAspect.java

    添加依赖

    dependencies {
        compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1')
        compile('org.springframework.boot:spring-boot-starter-web')
        compile('org.springframework.boot:spring-boot-starter-aop')
        compile('com.alibaba:druid-spring-boot-starter:1.1.6')
        runtime('mysql:mysql-connector-java')
        testCompile('org.springframework.boot:spring-boot-starter-test')
    }
    

    创建数据库及表

    • 分别创建数据库product_master, product_slave_alpha, product_slave_beta, product_slave_gamma
    • 在以上数据库中分别创建表 product,并插入不同数据
    DROP DATABASE IF EXISTS product_master;
    CREATE DATABASE product_master;
    CREATE TABLE product_master.product(
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(50) NOT NULL,
      price DOUBLE(10,2) NOT NULL DEFAULT 0);
    INSERT INTO product_master.product (name, price) VALUES('master', '1');
    
    
    DROP DATABASE IF EXISTS product_slave_alpha;
    CREATE DATABASE product_slave_alpha;
    CREATE TABLE product_slave_alpha.product(
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(50) NOT NULL,
      price DOUBLE(10,2) NOT NULL DEFAULT 0);
    INSERT INTO product_slave_alpha.product (name, price) VALUES('slaveAlpha', '1');
    
    DROP DATABASE IF EXISTS product_slave_beta;
    CREATE DATABASE product_slave_beta;
    CREATE TABLE product_slave_beta.product(
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(50) NOT NULL,
      price DOUBLE(10,2) NOT NULL DEFAULT 0);
    INSERT INTO product_slave_beta.product (name, price) VALUES('slaveBeta', '1');
    
    DROP DATABASE IF EXISTS product_slave_gamma;
    CREATE DATABASE product_slave_gamma;
    CREATE TABLE product_slave_gamma.product(
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(50) NOT NULL,
      price DOUBLE(10,2) NOT NULL DEFAULT 0);
    INSERT INTO product_slave_gamma.product (name, price) VALUES('slaveGamma', '1');
    
    

    配置数据源

    • application.properties
    # Master datasource config
    spring.datasource.druid.master.name=master
    spring.datasource.druid.master.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.druid.master.url=jdbc:mysql://localhost/product_master?useSSL=false
    spring.datasource.druid.master.port=3306
    spring.datasource.druid.master.username=root
    spring.datasource.druid.master.password=123456
    
    # SlaveAlpha datasource config
    spring.datasource.druid.slave-alpha.name=SlaveAlpha
    spring.datasource.druid.slave-alpha.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.druid.slave-alpha.url=jdbc:mysql://localhost/product_slave_alpha?useSSL=false
    spring.datasource.druid.slave-alpha.port=3306
    spring.datasource.druid.slave-alpha.username=root
    spring.datasource.druid.slave-alpha.password=123456
    
    # SlaveBeta datasource config
    spring.datasource.druid.slave-beta.name=SlaveBeta
    spring.datasource.druid.slave-beta.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.druid.slave-beta.url=jdbc:mysql://localhost/product_slave_beta?useSSL=false
    spring.datasource.druid.slave-beta.port=3306
    spring.datasource.druid.slave-beta.username=root
    spring.datasource.druid.slave-beta.password=123456
    
    # SlaveGamma datasource config
    spring.datasource.druid.slave-gamma.name=SlaveGamma
    spring.datasource.druid.slave-gamma.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.druid.slave-gamma.url=jdbc:mysql://localhost/product_slave_gamma?useSSL=false
    spring.datasource.druid.slave-gamma.port=3306
    spring.datasource.druid.slave-gamma.username=root
    spring.datasource.druid.slave-gamma.password=123456
    
    # Druid dataSource config
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.druid.initial-size=5
    spring.datasource.druid.max-active=20
    spring.datasource.druid.min-idle=5
    spring.datasource.druid.max-wait=60000
    spring.datasource.druid.pool-prepared-statements=false
    spring.datasource.druid.validation-query=SELECT 1
    spring.datasource.druid.validation-query-timeout=30000
    spring.datasource.druid.test-on-borrow=false
    spring.datasource.druid.test-on-return=false
    spring.datasource.druid.test-while-idle=true
    #spring.datasource.druid.time-between-eviction-runs-millis=
    #spring.datasource.druid.min-evictable-idle-time-millis=
    #spring.datasource.druid.max-evictable-idle-time-millis=10000
    
    # Druid stat filter config
    spring.datasource.druid.filters=stat,wall,log4j
    spring.datasource.druid.web-stat-filter.enabled=true
    spring.datasource.druid.web-stat-filter.url-pattern=/*
    spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
    spring.datasource.druid.web-stat-filter.session-stat-enable=true
    spring.datasource.druid.web-stat-filter.session-stat-max-count=10
    spring.datasource.druid.web-stat-filter.principal-session-name=user
    #spring.datasource.druid.web-stat-filter.principal-cookie-name=
    spring.datasource.druid.web-stat-filter.profile-enable=true
    spring.datasource.druid.filter.stat.db-type=mysql
    spring.datasource.druid.filter.stat.log-slow-sql=true
    spring.datasource.druid.filter.stat.slow-sql-millis=1000
    spring.datasource.druid.filter.stat.merge-sql=true
    spring.datasource.druid.filter.wall.enabled=true
    spring.datasource.druid.filter.wall.config.delete-allow=true
    spring.datasource.druid.filter.wall.config.drop-table-allow=false
    spring.datasource.druid.filter.slf4j.enabled=true
    # Druid manage page config
    spring.datasource.druid.stat-view-servlet.enabled=true
    spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
    spring.datasource.druid.stat-view-servlet.reset-enable=true
    spring.datasource.druid.stat-view-servlet.login-username=admin
    spring.datasource.druid.stat-view-servlet.login-password=admin
    #spring.datasource.druid.stat-view-servlet.allow=
    #spring.datasource.druid.stat-view-servlet.deny=
    spring.datasource.druid.use-global-data-source-stat=true
    # Druid AOP config
    spring.datasource.druid.aop-patterns=cn.com.hellowood.dynamicdatasource.service.*
    spring.aop.proxy-target-class=true
    
    # MyBatis config
    mybatis.type-aliases-package=cn.com.hellowood.dynamicdatasource.mapper
    mybatis.mapper-locations=mappers/**Mapper.xml
    server.port=9999
    

    配置数据源

    • DataSourceKey.java
    package cn.com.hellowood.dynamicdatasource.common;
    
    public enum DataSourceKey {
        master,
        slaveAlpha,
        slaveBeta,
        slaveGamma
    }
    
    
    • DataSourceRoutingDataSource.java

    该类继承自 AbstractRoutingDataSource 类,在访问数据库时会调用该类的 determineCurrentLookupKey() 方法获取数据库实例的 key

    package cn.com.hellowood.dynamicdatasource.configuration;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
    
        private final Logger logger = LoggerFactory.getLogger(getClass());
    
        @Override
        protected Object determineCurrentLookupKey() {
            logger.info("Current DataSource is [{}]", DynamicDataSourceContextHolder.getDataSourceKey());
            return DynamicDataSourceContextHolder.getDataSourceKey();
        }
    }
    
    
    • DataSourceConfigurer.java

    数据源配置类,在该类中生成多个数据源实例并将其注入到 ApplicationContext

    package cn.com.hellowood.dynamicdatasource.configuration;
    
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    
    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;
    
    @Configuration
    public class DataSourceConfigurer {
    
        /**
         * master DataSource
         * @Primary 注解用于标识默认使用的 DataSource Bean,因为有5个 DataSource Bean,该注解可用于 master
         * 或 slave DataSource Bean, 但不能用于 dynamicDataSource Bean, 否则会产生循环调用 
         * 
         * @ConfigurationProperties 注解用于从 application.properties 文件中读取配置,为 Bean 设置属性 
         * @return data source
         */
        @Bean("master")
        @Primary
        @ConfigurationProperties(prefix = "spring.datasource.druid.master")
        public DataSource master() {
            return DruidDataSourceBuilder.create().build();
        }
    
        /**
         * Slave alpha data source.
         *
         * @return the data source
         */
        @Bean("slaveAlpha")
        @ConfigurationProperties(prefix = "spring.datasource.druid.slave-alpha")
        public DataSource slaveAlpha() {
            return DruidDataSourceBuilder.create().build();
        }
    
        /**
         * Slave beta data source.
         *
         * @return the data source
         */
        @Bean("slaveBeta")
        @ConfigurationProperties(prefix = "spring.datasource.druid.slave-beta")
        public DataSource slaveBeta() {
            return DruidDataSourceBuilder.create().build();
        }
    
        /**
         * Slave gamma data source.
         *
         * @return the data source
         */
        @Bean("slaveGamma")
        @ConfigurationProperties(prefix = "spring.datasource.druid.slave-gamma")
        public DataSource slaveGamma() {
            return DruidDataSourceBuilder.create().build();
        }
    
        /**
         * Dynamic data source.
         *
         * @return the data source
         */
        @Bean("dynamicDataSource")
        public DataSource dynamicDataSource() {
            DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
            Map<Object, Object> dataSourceMap = new HashMap<>(4);
            dataSourceMap.put(DataSourceKey.master.name(), master());
            dataSourceMap.put(DataSourceKey.slaveAlpha.name(), slaveAlpha());
            dataSourceMap.put(DataSourceKey.slaveBeta.name(), slaveBeta());
            dataSourceMap.put(DataSourceKey.slaveGamma.name(), slaveGamma());
    
            // 将 master 数据源作为默认指定的数据源
            dynamicRoutingDataSource.setDefaultTargetDataSource(master());
            // 将 master 和 slave 数据源作为指定的数据源
            dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);
    
            // 将数据源的 key 放到数据源上下文的 key 集合中,用于切换时判断数据源是否有效
            DynamicDataSourceContextHolder.dataSourceKeys.addAll(dataSourceMap.keySet());
    
            // 将 Slave 数据源的 key 放在集合中,用于轮循
            DynamicDataSourceContextHolder.slaveDataSourceKeys.addAll(dataSourceMap.keySet());
            DynamicDataSourceContextHolder.slaveDataSourceKeys.remove(DataSourceKey.master.name());
            return dynamicRoutingDataSource;
        }   
        
        /**
         * 配置 SqlSessionFactoryBean
         * @ConfigurationProperties 在这里是为了将 MyBatis 的 mapper 位置和持久层接口的别名设置到 
         * Bean 的属性中,如果没有使用 *.xml 则可以不用该配置,否则将会产生 invalid bond statement 异常
         * 
         * @return the sql session factory bean
         */
        @Bean
        @ConfigurationProperties(prefix = "mybatis")
        public SqlSessionFactoryBean sqlSessionFactoryBean() {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            // 配置数据源,此处配置为关键配置,如果没有将 dynamicDataSource 作为数据源则不能实现切换
            sqlSessionFactoryBean.setDataSource(dynamicDataSource());
            return sqlSessionFactoryBean;
        }
        
        /**
         * 注入 DataSourceTransactionManager 用于事务管理
         */
        @Bean
        public PlatformTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dynamicDataSource());
        }
        
    }
    
    
    • DynamicDataSourceContextHolder.java

    该类为数据源上下文配置,用于切换数据源

    package cn.com.hellowood.dynamicdatasource.configuration;
    
    
    import cn.com.hellowood.dynamicdatasource.common.DataSourceKey;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class DynamicDataSourceContextHolder {
    
        private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
    
        /**
         * 用于在切换数据源时保证不会被其他线程修改
         */
        private static Lock lock = new ReentrantLock();
    
        /**
         * 用于轮循的计数器
         */
        private static int counter = 0;
    
        /**
         * Maintain variable for every thread, to avoid effect other thread
         */
        private static final ThreadLocal<Object> CONTEXT_HOLDER = ThreadLocal.withInitial(DataSourceKey.master);
    
    
        /**
         * All DataSource List
         */
        public static List<Object> dataSourceKeys = new ArrayList<>();
    
        /**
         * The constant slaveDataSourceKeys.
         */
        public static List<Object> slaveDataSourceKeys = new ArrayList<>();
    
        /**
         * To switch DataSource
         *
         * @param key the key
         */
        public static void setDataSourceKey(String key) {
            CONTEXT_HOLDER.set(key);
        }
    
        /**
         * Use master data source.
         */
        public static void useMasterDataSource() {
            CONTEXT_HOLDER.set(DataSourceKey.master);
        }
    
        /**
         * 当使用只读数据源时通过轮循方式选择要使用的数据源
         */
        public static void useSlaveDataSource() {
            lock.lock();
    
            try {
                int datasourceKeyIndex = counter % slaveDataSourceKeys.size();
                CONTEXT_HOLDER.set(String.valueOf(slaveDataSourceKeys.get(datasourceKeyIndex)));
                counter++;
            } catch (Exception e) {
                logger.error("Switch slave datasource failed, error message is {}", e.getMessage());
                useMasterDataSource();
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        /**
         * Get current DataSource
         *
         * @return data source key
         */
        public static String getDataSourceKey() {
            return CONTEXT_HOLDER.get();
        }
    
        /**
         * To set DataSource as default
         */
        public static void clearDataSourceKey() {
            CONTEXT_HOLDER.remove();
        }
    
        /**
         * Check if give DataSource is in current DataSource list
         *
         * @param key the key
         * @return boolean boolean
         */
        public static boolean containDataSourceKey(String key) {
            return dataSourceKeys.contains(key);
        }
    }
    
    
    
    • DynamicDataSourceAspect.java

    动态数据源切换的切面,切 DAO 层,通过 DAO 层方法名判断使用哪个数据源,实现数据源切换

    package cn.com.hellowood.dynamicdatasource.configuration;
    
    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.aspectj.lang.annotation.Pointcut;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class DynamicDataSourceAspect {
        private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);
    
        private final String[] QUERY_PREFIX = {"select"};
    
        @Pointcut("execution( * cn.com.hellowood.dynamicdatasource.mapper.*.*(..))")
        public void daoAspect() {
        }
    
        @Before("daoAspect()")
        public void switchDataSource(JoinPoint point) {
            Boolean isQueryMethod = isQueryMethod(point.getSignature().getName());
            if (isQueryMethod) {
                DynamicDataSourceContextHolder.useSlaveDataSource();
                logger.info("Switch DataSource to [{}] in Method [{}]",
                        DynamicDataSourceContextHolder.getDataSourceKey(), point.getSignature());
            }
        }
    
        @After("daoAspect()")
        public void restoreDataSource(JoinPoint point) {
            DynamicDataSourceContextHolder.clearDataSourceKey();
            logger.info("Restore DataSource to [{}] in Method [{}]",
                    DynamicDataSourceContextHolder.getDataSourceKey(), point.getSignature());
        }
    
        private Boolean isQueryMethod(String methodName) {
            for (String prefix : QUERY_PREFIX) {
                if (methodName.startsWith(prefix)) {
                    return true;
                }
            }
            return false;
        }
    
    }
    
    

    配置 Product REST API 接口

    • ProductController.java
    package cn.com.hellowood.dynamicdatasource.controller;
    
    import cn.com.hellowood.dynamicdatasource.common.CommonResponse;
    import cn.com.hellowood.dynamicdatasource.common.ResponseUtil;
    import cn.com.hellowood.dynamicdatasource.modal.Product;
    import cn.com.hellowood.dynamicdatasource.service.ProductService;
    import cn.com.hellowood.dynamicdatasource.utils.ServiceException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @RequestMapping("/product")
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @GetMapping("/{id}")
        public CommonResponse getProduct(@PathVariable("id") Long productId) throws ServiceException {
            return ResponseUtil.generateResponse(productService.select(productId));
        }
    
        @GetMapping
        public CommonResponse getAllProduct() {
            return ResponseUtil.generateResponse(productService.getAllProduct());
        }
    
        @PutMapping("/{id}")
        public CommonResponse updateProduct(@PathVariable("id") Long productId, @RequestBody Product newProduct) throws ServiceException {
            return ResponseUtil.generateResponse(productService.update(productId, newProduct));
        }
    
        @DeleteMapping("/{id}")
        public CommonResponse deleteProduct(@PathVariable("id") long productId) throws ServiceException {
            return ResponseUtil.generateResponse(productService.delete(productId));
        }
    
        @PostMapping
        public CommonResponse addProduct(@RequestBody Product newProduct) throws ServiceException {
            return ResponseUtil.generateResponse(productService.add(newProduct));
        }
    }
    
    
    
    • ProductService.java
    package cn.com.hellowood.dynamicdatasource.service;
    
    import cn.com.hellowood.dynamicdatasource.mapper.ProductDao;
    import cn.com.hellowood.dynamicdatasource.modal.Product;
    import cn.com.hellowood.dynamicdatasource.utils.ServiceException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.dao.DataAccessException;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.List;
    
    @Service
    public class ProductService {
    
        @Autowired
        private ProductDao productDao;
    
        public Product select(long productId) throws ServiceException {
            Product product = productDao.select(productId);
            if (product == null) {
                throw new ServiceException("Product:" + productId + " not found");
            }
            return product;
        }
    
        @Transactional(rollbackFor = DataAccessException.class)
        public Product update(long productId, Product newProduct) throws ServiceException {
    
            if (productDao.update(newProduct) <= 0) {
                throw new ServiceException("Update product:" + productId + "failed");
            }
            return newProduct;
        }
    
        @Transactional(rollbackFor = DataAccessException.class)
        public boolean add(Product newProduct) throws ServiceException {
            Integer num = productDao.insert(newProduct);
            if (num <= 0) {
                throw new ServiceException("Add product failed");
            }
            return true;
        }
    
        @Transactional(rollbackFor = DataAccessException.class)
        public boolean delete(long productId) throws ServiceException {
            Integer num = productDao.delete(productId);
            if (num <= 0) {
                throw new ServiceException("Delete product:" + productId + "failed");
            }
            return true;
        }
    
        public List<Product> getAllProduct() {
            return productDao.getAllProduct();
        }
    }
    
    
    • ProductDao.java
    package cn.com.hellowood.dynamicdatasource.mapper;
    
    import cn.com.hellowood.dynamicdatasource.modal.Product;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    @Mapper
    public interface ProductDao {
        Product select(@Param("id") long id);
    
        Integer update(Product product);
    
        Integer insert(Product product);
    
        Integer delete(long productId);
    
        List<Product> getAllProduct();
    }
    
    
    • ProductMapper.xml

    启动项目,此时访问 /product/1 会返回 product_master 数据库中 product 表中的所有数据,多次访问 /product 会分别返回 product_slave_alphaproduct_slave_betaproduct_slave_gamma 数据库中 product 表中的数据,同时也可以在看到切换数据源的 log,说明动态切换数据源是有效的


    注意

    在该应用中因为使用了 DAO 层的切面切换数据源,所以 @Transactional 注解不能加在类上,只能用于方法;有 @Trasactional注解的方法无法切换数据源

    展开全文
  • 本文介绍两种切换数据库的方法。 方法1:数据库信息都配置在spring xml中,适用于一般数据库切换。...方法2:将数据库信息配置在默认数据源中,适用于切换数据库操作同一方法,相当于批量执行方法。...
  • Win10如何配置数据源ODBC数据源

    万次阅读 2019-05-06 20:03:25
    如何配置数据源ODBC数据源 1.打开控制面板,按下图,依次进行操作: 2.双击打开 “ODBC数据源” ,按下图进行操作: 3.选择 “Microsoft Access Driver”,如下图: 4.对 “ODBC Microsoft Access” 进行安装,...
  • 前言在开发过程中可能需要用到多个数据源,比如一个项目(MySQL)就是和(SQL Server)混合使用,就需要使用多数据源;如果业务场景比较复炸,可以使用动态数据源,灵活切换,典型的应用就是读写分离。下面分两个...
  • spring boot多数据源配置,多数据源事务 springboot 中数据源配置,连接池配置,源码剖析,如何选择连接池 阅读本文前 ,请先阅读笔者另一片文章Spring Boot 源码深入分析 需求描述 在业务开发中,需要读写...
  • 自定义数据源 Druid 引入数据源 切换 Druid 数据源 配置 Druid 数据源参数 配置 Druid 数据源监控 配置 Druid 后台管理 Servlet 配置 Druid web 监控 filter DRUID 简介 1、Druid 是阿里巴巴开源平台上一个...
  • Spring Boot 动态数据源(多数据源自动切换)

    万次阅读 多人点赞 2016-01-24 20:04:43
    为了在开发中以最简单的方法使用,本文基于注解和AOP的方法实现,在spring boot框架的项目中,添加本文实现的代码类后,只需要配置好数据源就可以直接通过注解使用,简单方便。一配置二使用 1. 配置文件中配置多个...
  • Spring Boot 集成Mybatis实现多数据源

    万次阅读 热门讨论 2017-06-30 19:12:38
    项目提交测试,趁着中当间的这个空档期,把springboot的多数据源配置学习一下,总体来说多数据源配置有两种方式,一种是静态的,一种是动态的。 静态的方式 我们以两套配置方式为例,在项目中有两套配置文件,两套...
  • Spring动态切换多数据源Demo

    千次下载 热门讨论 2015-02-03 15:24:55
    请自行修改com/resources/datasource.properties中数据库配置,Demo中配置的两个数据源,一个是Mysql,一个是Oracle。 运行之前请自行建立数据库的表。
  • springboot中多数据源的配置

    万次阅读 2018-07-27 15:11:08
    在实际项目中,一个工程配置多个数据源很常见,工程可能会根据业务或者模块访问不同的数据库或表;今天笔者就springboot中配置多数据源作个详细的讲解 2.实现方案 注意:一个应用工程中有且只有一个启动类,其...
  • 相信很多开发者也遇到过这样的问题,随着项目的增大,使用的数据源会越来越多,现在比较流行配置数据源的方法是在xml配置文件配置数据源, ![图片说明]...
  • AbstractRoutingDataSource动态数据源切换 上周末,室友通宵达旦的敲代码处理他的多数据源的问题,搞的非常的紧张,也和我聊了聊天,大概的了解了他的业务的需求。一般的情况下我们都是使用SSH或者SSM框架进行处理...
  • SpringBoot配置数据源 1.创建项目 创建好项目以后,pom文件应该是这样的: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=...
  • Spark多数据源处理

    千人学习 2016-05-10 15:55:34
    Spark多数据源处理教程,该课程主要介绍如何通过Spark的DataSource API来读写外部数据源中的数据,并结合一些具体场景来分析和解释使用DataSource API的好处以及需要注意的问题。
  • springboot默认加载application.properties或application.yml配置,配置规则已经定好且为单数据源,想要配置多数据源必须禁用默认加载,然后手动去配置多数据源,完整代码如下:数据源配置:application.properties#...
  • 数据源、元数据、数据元

    千次阅读 2020-01-10 15:14:57
    ##数据源(data source) 顾名思义,数据的来源,是提供某种所需要数据的器件或原始媒体。在数据源中存储了所有建立数据库连接的信息。就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数据源名称,...
  • 之前写过一篇文章是静态切换双数据源,yml里面初始化2个数据源一个mapper管理一个数据源,调用mapper1的就是从A库取数据,调用mapper2从B库取数据 地址:springboot双数据源 这次有一个需求是,项目启动以后根据一个新的...
  • SSM多数据源配置(配置两个数据源) 前言:SSM项目需要配置多数据源,以达到操作不同数据库的数据,网上看到大多是通过动态切换数据源的方式,但在项目中总会出现问题,这里通过配置两个spring-mybatis.xml...
  • 在作数据库实例的时候,需要创建Access数据库的ODBC数据源,管理工具 ODBC数据源管理器里面只有SQL Server ,没有Access等其他,因为Access数据源驱动器是32位的,64位不支持,只要打开32位版本的ODBC管理工具就可以...
  • 1、多数据源与动态数据源 当项目不只是要用到一个数据库的时候就需要使用到多个数据源了,这种场景很多,比如要查找的数据不在同一个数据库库中,或者是要做数据库读写分离。应对上面的问题主要有两种解决方法。 ...
  • 动态数据源在多数据源的基础上,要实现数据源的动态切换。这两种复杂系统的数据库联接有相关性,也有不同应用场景的区别。如要连接两个不同的业务库,一般会使用多数据源,如要动态切换不同数据源的相同业务库,会...
  • Weblogic Xa数据源和非Xa数据源的选择

    千次阅读 2018-02-05 05:42:32
    背景:在项目上,不管是ADF应用,BPM应用,或者是OSB、SOA接口,数据源和出站连接池的建立必然少不了,而数据源的类型就有Xa数据源和非Xa数据源,那我们如何选择呢,选择不当会造成什么后果呢,下面给出一点小小的...
  • 数据源(DataSource)是什么以及SpringBoot中数据源配置

    千次阅读 多人点赞 2018-08-09 16:46:10
    数据源 数据源,简单理解为数据源头,提供了应用程序所需要数据的位置。数据源保证了应用程序与目标数据之间交互的规范和协议,它可以是数据库,文件系统等等。其中数据源定义了位置信息,用户验证信息和交互时所需...
  • spring + druid 配置动态配置数据源以及多数据源切换功能实现 数据源连接池使用druid 其他的数据源基本原理相同 spring中配置默认数据源连接池如下: <!-- 数据源配置, 使用 BoneCP 数据库连接池 --> &...
  • SpringBoot多数据源切换,AOP实现动态数据源切换 操作数据一般都是在DAO层进行处理,可以选择直接使用JDBC进行编程 或者是使用多个DataSource 然后创建多个SessionFactory,在使用Dao层的时候通过不同的...
  • 提供所有微服务数据源的图形化维护功能 代码生成可以根据选择的数据源加载表等源信息 数据源管理要支持动态配置,实时生效 附录效果图 实现思路 本文提供方法仅供类似简单业务场景,在生产环境和复杂的业务场景 ...
  • 最近项目需要指出多数据源,同时支持事务回滚,这里记录一下 1、多数据源方式介绍 主要方式有以下两种: 通过配置多个SqlSessionFactory 来实现多数据源,这么做的话,未免过于笨重,而且无法实现动态添加数据源...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 212,987
精华内容 85,194
关键字:

数据源