一、环境准备

新建一个Spring Boot项目,然后在pom.xml中引入相关依赖

mysql

mysql-connector-java

com.microsoft.sqlserver

mssql-jdbc

6.5.4.jre8-preview

test

com.microsoft.sqlserver

sqljdbc4

4.0

org.aspectj

aspectjweaver

1.9.2

二、数据源配置

本文用到的两个数据源分别是MySQL数据库和SqlServer数据库,其中MySQL数据库为主数据库(可自行更改)

spring:

datasource:

##配置主数据库

primary:

jdbc-url: jdbc:mysql://xx.x.x.xxx:3306/quality?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false

username: xxx

password: xxx

driver-class-name: com.mysql.cj.jdbc.Driver

##配置次数据库

secondary:

jdbc-url: jdbc:sqlserver://xxx.xxx.xxx.x:1433;DatabaseName=quality

username: sa

password: xxx

driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

三、创建数据源配置类

完成数据源的配置后,需创建数据源的配置类;其作用是帮助项目区分spring.datasource.primary和secondary。

第一个配置类:

package com.chinameyer.qualitymanagementsystem.config;

import org.apache.ibatis.session.SqlSessionFactory;

import org.mybatis.spring.SqlSessionFactoryBean;

import org.mybatis.spring.SqlSessionTemplate;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.boot.context.properties.ConfigurationProperties;

import org.springframework.boot.jdbc.DataSourceBuilder;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@Configuration

// 配置mybatis的接口类放的地方

@MapperScan(basePackages = "com.chinameyer.qualitymanagementsystem.dao.one", sqlSessionFactoryRef = "PrimarySqlSessionFactory")

public class PrimaryDataSourceConfig {

// 将这个对象放入Spring容器中

@Bean(name = "PrimaryDataSource")

// 表示这个数据源是默认数据源

@Primary

// 读取application.properties中的配置参数映射成为一个对象

// prefix表示参数的前缀

@ConfigurationProperties(prefix = "spring.datasource.primary")

public DataSource getPrimaryDateSource() {

return DataSourceBuilder.create().build();

}

@Bean(name = "PrimarySqlSessionFactory")

// 表示这个数据源是默认数据源

@Primary

// @Qualifier表示查找Spring容器中名字为test1DataSource的对象

public SqlSessionFactory primarySqlSessionFactory(@Qualifier("PrimaryDataSource") DataSource datasource)

throws Exception {

SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

bean.setDataSource(datasource);

return bean.getObject();

}

@Bean("PrimarySqlSessionTemplate")

// 表示这个数据源是默认数据源

@Primary

public SqlSessionTemplate primarySqlSessionTemplate(

@Qualifier("PrimarySqlSessionFactory") SqlSessionFactory sessionfactory) {

return new SqlSessionTemplate(sessionfactory);

}

}

第二个配置类:

package com.chinameyer.qualitymanagementsystem.config;

import org.apache.ibatis.session.SqlSessionFactory;

import org.mybatis.spring.SqlSessionFactoryBean;

import org.mybatis.spring.SqlSessionTemplate;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.boot.context.properties.ConfigurationProperties;

import org.springframework.boot.jdbc.DataSourceBuilder;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration

@MapperScan(basePackages = "com.chinameyer.qualitymanagementsystem.dao.two", sqlSessionFactoryRef = "SecondarySqlSessionFactory")

public class SecondaryDataSourceConfig {

@Bean(name = "SecondaryDataSource")

@ConfigurationProperties(prefix = "spring.datasource.secondary")

public DataSource getSecondaryDataSource() {

return DataSourceBuilder.create().build();

}

@Bean(name = "SecondarySqlSessionFactory")

public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("SecondaryDataSource") DataSource datasource)

throws Exception {

SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

bean.setDataSource(datasource);

return bean.getObject();

}

@Bean("SecondarySqlSessionTemplate")

public SqlSessionTemplate secondarySqlSessionTemplate(

@Qualifier("SecondarySqlSessionFactory") SqlSessionFactory sessionfactory) {

return new SqlSessionTemplate(sessionfactory);

}

}

四、自定义注解 @DataSource

通过自定义的注解@DataSource,方便在对数据库操作时,确定其操作的对象。

package com.chinameyer.qualitymanagementsystem.service;

/**

* @Author HongYe

* @Date 2019/12/26 9:29

*/

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface DataSource {

String value() default "primary"; //默认使用默认数据库

}

五、通过AOP的方式实现多数据源

通常可以通过分包实现多数据源的,检测多数据源存在的事务管理问题、通过jta-atomikos解决传统项目多数据源事务管理问题以及通过aop的方式实现多数据源,该处使用的是最后一种方式。

通过使用aop拦截,获取注解的属性value的值。如果value的值并没有在我们DataBaseType里面,则使用我们默认的数据源,如果有的话,则切换为相应的数据源。

package com.chinameyer.qualitymanagementsystem.service;

import com.chinameyer.qualitymanagementsystem.entity.DataSourceType;

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.springframework.stereotype.Component;

/**

* @Author HongYe

* @Date 2019/12/26 9:29

*/

@Aspect

@Component

public class DynamicDataSourceAspect {

@Before("@annotation(dataSource)")//拦截我们的注解

public void changeDataSource(JoinPoint point, DataSource dataSource) throws Throwable {

String value = dataSource.value();

if (value.equals("primary")){

DataSourceType.setDataBaseType(DataSourceType.DataBaseType.Primary);

}else if (value.equals("secondary")){

DataSourceType.setDataBaseType(DataSourceType.DataBaseType.Secondary);

}else {

DataSourceType.setDataBaseType(DataSourceType.DataBaseType.Primary);//默认使用主数据库

}

}

@After("@annotation(dataSource)") //清除数据源的配置

public void restoreDataSource(JoinPoint point, DataSource dataSource) {

DataSourceType.clearDataBaseType();

}

}

六、在Dao层写操作数据库的SQL语句

package com.chinameyer.qualitymanagementsystem.dao.one;

import com.chinameyer.qualitymanagementsystem.entity.SqlProvider;

import com.chinameyer.qualitymanagementsystem.service.DataSource;

import org.apache.ibatis.annotations.Delete;

import org.apache.ibatis.annotations.Param;

import org.apache.ibatis.annotations.Select;

import org.apache.ibatis.annotations.SelectProvider;

import java.util.List;

/**

* @Author HongYe

* @Date 2019/12/31 10:03

*/

public interface BmDao {

/**

* 清空表中数据

*/

@DataSource

@Delete("truncate table bm")

void updateThisTable();

}

package com.chinameyer.qualitymanagementsystem.dao.two;

import com.chinameyer.qualitymanagementsystem.entity.BHGDJCLB;

import com.chinameyer.qualitymanagementsystem.entity.BM;

import com.chinameyer.qualitymanagementsystem.service.DataSource;

import org.apache.ibatis.annotations.Select;

import java.util.List;

/**

* @Author HongYe

* @Date 2019/12/31 10:04

*/

public interface BmSecondaryDao {

/**

* 从MSSQL中获取所有的BM

* @return

*/

@DataSource("secondary")

@Select("select 部门编号 as departmentNumber,部门名称 as departmentName from bm")

List findAllEntityFromMssql();

}

最后写一个测试类,查看是否分别实现了对主、从数据库的操作!!!至少我实现了

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐