基于Spirngboot2.0实现Mybatis多数据源

版权声明:@412958751 https://blog.csdn.net/Jake_JJJ/article/details/82684146

Springboot2.0多数据源实现方式:

  1. 静态配置方式实现
  2. 动态配置方式
  3. 注解方式实现

Springboot2.0多数据源使用大致分为两种:

  1. 分包方式使用
  2. 注解方式使用

在这里我们讲分包方式实现静态配置方式(Mysql数据库形式)

  1. 首先我们都知道,Spring一开始是以XML形式以及properties形式组成Spring容器的基本配置。
  2. Springboot则是将SpringXML以及properties的配置文件简化,但是在实现某些配置,则都是需要用到原配置中的类

在这里我们首先来看原XML配置文件,才能理解多数据源需要哪些

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
     
     <!-- 配置数据源 -->
    <context:property-placeholder location="classpath:properties/db.properties" />
    <!-- 加载日志配置文件 -->
    <context:property-placeholder location="classpath:properties/log4j.properties" />
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${driver}"></property>
        <property name="jdbcUrl" value="${url}"></property>
        <property name="user" value="${dbName}"></property>
        <property name="password" value="${dbPassword}"></property>
        <!-- 每60秒检查所有连接池中的空闲连接。Default: 0 -->
        <property name="idleConnectionTestPeriod" value="60" />
        <!-- 初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 --> 
        <property name="initialPoolSize" value="5" />
        <!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="60" />
        <!-- 连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="10" />
        <!-- 连接池中保留的最小连接数。 -->
        <property name="minPoolSize" value="5" />
        <!-- JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 
        属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 
        如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
        <property name="maxStatements" value="100" />
        <!-- maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0  -->
        <property name="maxStatementsPerConnection" value="3" />
        <!-- 定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个显著提高测试速度。注意: 
        测试的表必须在初始数据源的时候就存在。Default: null -->
        <property name="preferredTestQuery" value="select 1" />
        <!-- 定义在从数据库获取新连接失败后重复尝试的次数。Default: 30-->
        <property name="acquireRetryAttempts" value="3" />
        <!-- 两次连接中间隔时间,单位毫秒。Default: 1000 -->
        <property name="acquireRetryDelay" value="1000" />
        <!-- 当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出 
        SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->
        <property name="checkoutTimeout" value="30000" />
    </bean>
    
    <!-- 配置sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 扫描mybatis核心配置文件 -->
        <property name="configLocation" value="classpath:spring/mybatis.xml"/>
        <!-- 扫描java bean,自动使用别名 -->
        <property name="typeAliasesPackage" value="com.czlj.pojo"/>
        <!-- 扫描 Mybatis 的SQL配置文件 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>
    
    <!-- 扫描Dao接口包 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.czlj.dao"/>
    </bean>
    
	<!-- 配置事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

</beans>

在这里我们能看到mybatis数据源的实现大概需要下列bean:

  1. DataSource
  2. SqlSessionFactory
  3. MapperScannerConfigurer
  4. TransactionManager

这时候我们开始配置Springboot数据源

##datasource01
ext01.spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf8
ext01.spring.datasource.username=root
ext01.spring.datasource.password=123456
ext01.spring.datasource.driver-class-name=com.mysql.jdbc.Driver

##datasource02
ext02.spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf8
ext02.spring.datasource.username=root
ext02.spring.datasource.password=123456
ext02.spring.datasource.driver-class-name=com.mysql.jdbc.Driver

这里我们配置了两个DataSource的基本参数。这里我们需要注意在每个datasource后面的jdbc-url,username,username,driver-class-name都是不能改变的,也需要注意不能使用原来方式配置 例:

##Springboot2.0方式原配置jdbc
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=

使用原来方式配置的话,Springboot会默认使用一个数据源,这样就不能实现多数据源了,而且使用原方式的话,这里需要注意,原方式的url与自定义方式的jdbc-url是不一样的,如果使用原方式的url进行多数据源配置会报找不到url的driver配置信息,在Springboot1.5时driver-class-name也是不一样的,Springboot1.5方式是driverclassname配置。

然后我们开始配置数据源的bean

需要讲解以下注解:


     * @Bean注解  //将此方法当作bean的形式注入Spring
     * @ConfigurationProperties //此注解为找application.properties配置文件中前缀为ext01.spring.datasource的配置信息
     * @Primary //此注解意思为当寻找Datasource时将此bean为第一候选,也就是默认在没指定使用哪个        
     * Datasource时,将此bean设置为主使用,在这里使用此注解是因为Springboot2.0及1.5需要配置一个主从才能执行多数据源,不然就会报错

     * @Qualifier //此数据在有多个匹配的bean时,指定具体使用哪个bean,不然在多个具备使用条件的bean的情况下会,报异常

下列类配置为主配置:

package com.nyhs.datasource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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.jdbc.datasource.DataSourceTransactionManager;

//此注解将此类以配置的形式注入到Springboot中
@Configuration
//此注解原意为扫包
//在这里使用此注解相当于配置XML中的MapperScannerConfigurer
//需要注意basePackages,这里才是根本决定分包,分数据源
@MapperScan(basePackages = "com.nyhs.test01.dao", sqlSessionFactoryRef = "Test01SqlSessionFactory")
public class DataSource01 {

	/**
	 * datasource 配置
     * @Bean注解  //将此方法当作bean的形式注入Spring
     * @ConfigurationProperties //此注解为找application.properties配置文件中前缀为            
     * ext01.spring.datasource的配置信息
     * @Primary //此注解意思为当寻找Datasource时将此bean为第一候选,也就是默认在没指定使用哪个        
     * Datasource时,将此bean设置为主使用,在这里使用此注解是因为Springboot2.0及1.5需要配置一     
     * 个主从才能执行多数据源,不然就会报错
	 * @return
	 */
	@Bean(name = "Test01DataSource")
	@ConfigurationProperties(prefix = "ext01.spring.datasource")
	@Primary
	public DataSource getDataSource() {
		return DataSourceBuilder.create().build();
	}


	/**
	 * sqlsessionfactory 配置
     * 
	 * @return
	 */
	@Bean(name = "Test01SqlSessionFactory")
	@Primary
	public SqlSessionFactory getSqlSessionFactory(@Qualifier("Test01DataSource") DataSource dataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		return bean.getObject();
	}


	/**
	 * DataSourceTransactionManager 事务管理器配置
	 * @return
	 */
	@Bean(name = "Test01DataSourceTransactionManager")
	@Primary
	public DataSourceTransactionManager getDataSourceTransactionManager(
			@Qualifier("Test01DataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

}

在这里我们需要注意每一个Datasouce都有一个专门的事务管理器,也就是说,当有多个数据源时,也有多个数据事务管理器

从配置:

package com.nyhs.datasource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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.jdbc.datasource.DataSourceTransactionManager;

@Configuration
//需要注意这里的basePackages路径不一样,这样才能进行分包处理多个数据源
@MapperScan(basePackages = "com.nyhs.test02.dao", sqlSessionFactoryRef = "Test02SqlSessionFactory")
public class DataSource02 {

	@Bean(name = "Test02DataSource")
	@ConfigurationProperties(prefix = "ext02.spring.datasource")
	public DataSource getDataSource() {
		return DataSourceBuilder.create().build();
	}

	@Bean(name = "Test02SqlSessionFactory")
	public SqlSessionFactory getSqlSessionFactory(@Qualifier("Test02DataSource") DataSource dataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		return bean.getObject();
	}

	@Bean(name = "Test02DataSourceTransactionManager")
	public DataSourceTransactionManager getDataSourceTransactionManager(
			@Qualifier("Test02DataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

}

主配置进行数据处理路径为:com.nyhs.test01.dao

从配置进行数据处理路径为:   com.nyhs.test02.dao

 这里我们需要注意使用事务时的问题

@Transactional//如果不指定数据源的情况下,会无法进行对应的事务管理。所以我们需要指定事务管理器的使用。参数值为对应事务管理器的beanID

package com.nyhs.test01.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nyhs.test01.dao.Test01UserDao;
import com.nyhs.test01.service.Test01UserService;

/**
 * TEST01数据源的业务层
 * @author 412958751
 *
 */
@Service
public class Test01UserServiceImpl implements Test01UserService {

	@Autowired
	private Test01UserDao test01UserDao;

	@Override
	@Transactional(transactionManager="Test01DataSourceTransactionManager")
	public int insertUser(String name, int age) {
		return test01UserDao.insertUser(name, age);
	}

}

这样我们就配置好了事务以及多数据源的使用。动态数据源后续更新。。。。

猜你喜欢

转载自blog.csdn.net/Jake_JJJ/article/details/82684146