SpringMVC+Mybatis框架的maven Spring boot项目,多数据源的实践

      目前最流行的也只是这种SpringMVC+Mybatis框架,做一个项目,公司也不可能让项目只涉及到一个数据源。因为后期可能数据量大的情况,可能项目要重新安排,分布式处理数据也是少不了的。所以无论是后期维护,还是前期准备,都应该多方面考虑,我们用一个数据源可能以后不能满足我们的需求,所以,在搭建框架时,为了以后可扩展性做相应的准备。废话不多说,直接讲如题说的,spring boot 项目如何引用多数据源的。

      

com.xsth ----Application Maven项目启动的类

com.xsth.config  ----配置连接不同的数据源 (AssistantDataSourceConfig 这个类是从数据源)
                  (HostDataSourceConfig 这个类是主数据源)。
com.xsth.controller  ---控制层。
com.xsth.dao  --dao层,实现Mapping包中接口。
com.xsth.mapping.assistant ---这个包是生成文件路径的保存的表的数据源,做副表。
com.xsth.mapping.host  ---这个包是产品数据库表,做主表。
com.xsth.model  ----实体类。
com.xsth.service  ----业务层 (接口和实现类)。
com.xsth.util   ---工具类

src/main/resources   ---这个文件夹是存放数据库配置,和主副数据源的xml文件(说明:
Mapping包不需要在写xml文件,在这里写即可。)
pom.xml  ---项目对象模型,jar包的配置,自动下载。

首先Application这个类里是这样的

package com.xsth;

import javax.servlet.MultipartConfigElement;
import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.MultipartConfigFactory;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
//@MapperScan(basePackages = "com.xsth.mapping")
@ComponentScan(basePackages = "com.xsth")
public class Application extends SpringBootServletInitializer {

	@Bean
	public MultipartConfigElement multipartConfigElement() {
		MultipartConfigFactory factory = new MultipartConfigFactory();
		factory.setMaxFileSize("5MB");
		factory.setMaxRequestSize("5MB");
		return factory.createMultipartConfig();
	}

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
		return builder.sources(Application.class);
	}

	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(dataSource);
		return sessionFactory.getObject();
	}
}
下面是配置的数据源的类:

package com.xsth.config;

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.beans.factory.annotation.Value;
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 com.alibaba.druid.pool.DruidDataSource;

/**
 * 连接服务器的数据库 主数据库
 * 
 *
 */
@Configuration
// 扫描 Mapping 接口并容器管理
@MapperScan(basePackages = HostDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "hostSqlSessionFactory")
public class HostDataSourceConfig {
	// 精确到 host 目录,以便跟其他数据源隔离
	static final String PACKAGE = "com.xsth.mapping.host";
	static final String MAPPER_LOCATION = "classpath:mapper/host/*.xml";

	@Value("${host.datasource.url}")
	private String url;

	@Value("${host.datasource.username}")
	private String user;

	@Value("${host.datasource.password}")
	private String password;

	@Value("${host.datasource.driverClassName}")
	private String driverClass;

	@Bean(name = "hostDataSource")
	@Primary
	public DataSource hostDataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driverClass);
		dataSource.setUrl(url);
		dataSource.setUsername(user);
		dataSource.setPassword(password);
		return dataSource;
	}

	/**
	 * 事务管理
	 * 
	 * @return
	 */
	@Bean(name = "hostTransactionManager")
	/**
	 * @Primary 标志这个 Bean 如果在多个同类 Bean 候选时,该 Bean 优先被考虑。
	 *          「多数据源配置的时候注意,必须要有一个主数据源.
	 */
	@Primary
	public DataSourceTransactionManager hostTransactionManager() {
		return new DataSourceTransactionManager(hostDataSource());
	}

	/**
	 * 创建SqlSessionFactory工厂
	 * 
	 * @param hostDataSource
	 * @return
	 * @throws Exception
	 */
	@Bean(name = "hostSqlSessionFactory")
	@Primary
	public SqlSessionFactory hostSqlSessionFactory(@Qualifier("hostDataSource") DataSource hostDataSource)
			throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(hostDataSource);
		sessionFactory.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources(HostDataSourceConfig.MAPPER_LOCATION));
		return sessionFactory.getObject();
	}
}

下面这个连接的数据源是副数据源,一个项目中,必须有一个主数据源,主数据源只有一个。主数据源用 @Primary这个注解,其他去掉这个,代码基本都相同。

package com.xsth.config;

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.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * 存储文件的数据库 副数据库
 * 
 * @author liulinsen
 *
 */
@Configuration
// 扫描 Mapping 接口并容器管理
@MapperScan(basePackages = AssistantDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "assistantSqlSessionFactory")
public class AssistantDataSourceConfig {
	// 精确到 assistant 目录,以便跟其他数据源隔离
	static final String PACKAGE = "com.xsth.mapping.assistant";
	static final String MAPPER_LOCATION = "classpath:mapper/assistant/*.xml";

	@Value("${assistant.datasource.url}")
	private String url;

	@Value("${assistant.datasource.username}")
	private String user;

	@Value("${assistant.datasource.password}")
	private String password;

	@Value("${assistant.datasource.driverClassName}")
	private String driverClass;

	@Bean(name = "assistantDataSource")
	public DataSource assistantDataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driverClass);
		dataSource.setUrl(url);
		dataSource.setUsername(user);
		dataSource.setPassword(password);
		return dataSource;
	}

	/**
	 * 事务管理
	 * 
	 * @return
	 */
	@Bean(name = "assistantTransactionManager")
	public DataSourceTransactionManager assistantTransactionManager() {
		return new DataSourceTransactionManager(assistantDataSource());
	}

	@Bean(name = "assistantSqlSessionFactory")
	public SqlSessionFactory assistantSqlSessionFactory(
			@Qualifier("assistantDataSource") DataSource assistantDataSource) throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(assistantDataSource);
		sessionFactory.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources(AssistantDataSourceConfig.MAPPER_LOCATION));
		return sessionFactory.getObject();
	}
}
application.properties这个这样写:

assistant.datasource.url=jdbc:mysql://192.168.0.112:3306/database1
assistant.datasource.username=root
assistant.datasource.password=123456
assistant.datasource.driverClassName=com.mysql.jdbc.Driver

host.datasource.url=jdbc:mysql://192.168.0.112:3306/database2
host.datasource.username=root
host.datasource.password=123456
host.datasource.driverClassName=com.mysql.jdbc.Driver

#host.datasource.max-idle=10
#host.datasource.max-wait=10000
#host.datasource.min-idle=5
#host.datasource.initial-size=5
#host.datasource.validation-query=SELECT 1
#host.datasource.test-on-borrow=false
#host.datasource.test-while-idle=true
#host.datasource.time-between-eviction-runs-millis=18800
#host.datasource.jdbc-interceptors=ConnectionState;SlowQueryReport(threshold=0)
pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://maven.apache.org/POM/4.0.0"
	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>com.xsth</groupId>
	<artifactId>XsthInterfaceProject</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>XsthInterfaceProject</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<springversion>4.2.7.RELEASE</springversion>
	</properties>

	<parent>

		<groupId>org.springframework.boot</groupId>

		<artifactId>spring-boot-starter-parent</artifactId>

		<version>1.3.6.RELEASE</version>

	</parent>
	<dependencies>
		<!-- Spring Boot -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- Spring 其他 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${springversion}</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${springversion}</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>1.8.4</version>
		</dependency>
		<dependency>
			<!-- 只能使用较低版本的jsonpath -->
			<groupId>com.jayway.jsonpath</groupId>
			<artifactId>json-path</artifactId>
			<version>0.9.0</version>
			<!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.3.0</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.2.3</version>
		</dependency>
		<!-- 分页插件支持MyBatis3.2.0~3.3.0(包含) -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.1.6</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-autoconfigure -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
			<version>1.3.3.RELEASE</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<!-- 框架会默认注入 DataSourceTransactionManager 实例 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.29</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.39</version>
			<!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<version>9.4-1203-jdbc4</version>
			<!--$NO-MVN-MAN-VER$ -->
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.2.5.RELEASE</version><!--$NO-MVN-MAN-VER$ -->

		</dependency>
		<!-- web项目依赖包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.2.5.RELEASE</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.2.5.RELEASE</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>4.2.5.RELEASE</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<!-- 记录日志 log4j -->
		<!-- https://mvnrepository.com/artifact/log4j/log4j -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.14</version>
		</dependency>
		<!-- JSON -->
		<dependency>
			<groupId>org.json</groupId>
			<artifactId>json</artifactId>
			<version>20160810</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<!-- 设置局部的jdk 1.7 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


其他的业务层,持久层,控制层,都是和正常的一样。唯一要说明的是mapper这层,里面的xml应该写在如下图所示:


因此,要是数据源量只要一到两个左右,用这种方法其实是可以的。若是数据量大了,我推荐你用我下面一篇文章。本篇文章是个人实践和在在网上查找资料总结出来的,希望对各位开发者有所帮助。

代码在码云上已上传:https://git.oschina.net/edenl/xsthinterfaceproject.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

除不掉的灰色

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值