搜索
您的当前位置:首页正文

springboot+mybatis+yml文件配置多数据源

2021-01-28 来源:易榕旅网
springboot+mybatis+yml⽂件配置多数据源

记录⼀下java开发中多数据源的配置过程,1.配置⽂件application.yml

   personnel:#数据源1

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

jdbc-url: jdbc:mysql://localhost:3307/person?useSSL=false&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowMultiQueries=true&allowPublicKey username: root password: ******* userauth:#数据源2

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

jdbc-url: jdbc:mysql://localhost:3307/user?useSSL=false&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowMultiQueries=true&allowPublicKeyR username: root password: ******

2.不同数据源枚举:

public enum DataSourceEnum {master,slaver;}3.枚举类⼯具 set

public class DataSourceContextHolder {

private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal() {

@Override

protected DataSourceEnum initialValue() { return DataSourceEnum.master; } };

public static void setDataSourceType(DataSourceEnum type) { CONTEXT_HOLDER.set(type); }

public static DataSourceEnum getDataSourceType() { return CONTEXT_HOLDER.get(); }

public static void resetDataSourceType() {

CONTEXT_HOLDER.set(DataSourceEnum.master); }}

4.⾃定义注解

@Retention(RetentionPolicy.RUNTIME) // 在运⾏时可见@Target(ElementType.METHOD) // 注解可以⽤在⽅法上

public @interface DataSourceTypeAnno { //使⽤⽅式在service层⽅法上添加@DataSourceTypeAnno(DataSourceEnum.数据源枚举类型)⽤于指定所使⽤的数据源DataSourceEnum value() default DataSourceEnum.master; }

5.aop拦截:这⾥使⽤asp的

import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component@Aspect

@Order(-100)//为了保证可以拦截到public class DataSourceAspect {

@Pointcut(\"execution(* com.yzy.*.*..*(..)) \" + //这⾥扫描的切点包是主要是service层,根据service层⽅法的上边所说的的⾃定义注解,去判断所使⽤的数据源类型,并动态切换数据源 \"&& @annotation(com.yzy.config.DataSourceTypeAnno)\") public void dataSourcePointcut() { }

@Around(\"dataSourcePointcut()\")

public Object doAround(ProceedingJoinPoint pjp) {

MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); Method method = methodSignature.getMethod();

DataSourceTypeAnno typeAnno = method.getAnnotation(DataSourceTypeAnno.class); DataSourceEnum sourceEnum = typeAnno.value();

if (sourceEnum == DataSourceEnum.master) {

DataSourceContextHolder.setDataSourceType(DataSourceEnum.master); } else if (sourceEnum == DataSourceEnum.slaver) {

DataSourceContextHolder.setDataSourceType(DataSourceEnum.slaver); }

Object result = null; try {

result = pjp.proceed();

} catch (Throwable throwable) { throwable.printStackTrace(); } finally {

DataSourceContextHolder.resetDataSourceType(); }

return result; }}

6.继承 AbstractRoutingDataSource 类,实现对应数据源key的切换

package com.yzy.config;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource { protected Object determineCurrentLookupKey() {

return DataSourceContextHolder.getDataSourceType(); }}

7.配置mybatisConfig=》数据源信息

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.boot.jdbc.DataSourceBuilder;//org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;该包在springboot2.0被取代,⽬前⽹上的都是这个springboot1.5的包,所以会⼀直报错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 org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;import java.util.HashMap;import java.util.Map;

@Configuration

@MapperScan(basePackages = \"com.yzy.*.mapper\")//扫描dao层mapper接⼝public class MyBatisConfig {

/**

* @return

* @throws Exception

* @Primary 必需指定⼀个且只能有⼀个主数据源,否则报错 */

@Primary

@Bean(\"masterDataSource\")

@ConfigurationProperties(prefix = \"spring.datasource.userauth\")//根据数据源前缀到application.yml读取数据源信息//此处改变前缀可以改变默认数据源// public DataSource masterDataSource() throws Exception { return DataSourceBuilder.create().build(); }

@Bean(\"slaverDataSource\")

@ConfigurationProperties(prefix = \"spring.datasource.personnel\")//根据数据源前缀到application.yml读取数据源信息//可以配置更多数据源,到前提是application.yml中存在,⽽且也需要在枚举类中添加枚举类型 public DataSource slaverDataSource() throws Exception { return DataSourceBuilder.create().build(); }

/**

* @Qualifier 根据名称进⾏注⼊,通常是在具有相同的多个类型的实例的⼀个注⼊(例如有多个DataSource类型的实例) * @DataSourceTypeAnno(DataSourceEnum.master)事务⽅法需要指定数据源 */

@Bean(\"dynamicDataSource\")

public DynamicDataSource dynamicDataSource(@Qualifier(\"masterDataSource\") DataSource masterDataSource, @Qualifier(\"slaverDataSource\") DataSource slaverDataSource) { Map targetDataSources = new HashMap(); targetDataSources.put(DataSourceEnum.master, masterDataSource); targetDataSources.put(DataSourceEnum.slaver, slaverDataSource);

DynamicDataSource dataSource = new DynamicDataSource();

dataSource.setTargetDataSources(targetDataSources);// 该⽅法是AbstractRoutingDataSource的⽅法

dataSource.setDefaultTargetDataSource(masterDataSource);// 默认的datasource设置为myTestDbDataSource

return dataSource; }

/**

* 根据数据源创建SqlSessionFactory */

@Bean

public SqlSessionFactory sqlSessionFactory(@Qualifier(\"dynamicDataSource\") DynamicDataSource dynamicDataSource, @Value(\"mybatis.type-aliases-package\") String typeAliasesPackage) throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

factoryBean.setDataSource(dynamicDataSource);// 指定数据源(这个必须有,否则报错)

// 下边两句仅仅⽤于*.xml⽂件,如果整个持久层操作不需要使⽤到xml⽂件的话(只⽤注解就可以搞定),则不加

factoryBean.setTypeAliasesPackage(typeAliasesPackage);// 指定实体类所在的包 factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(\"classpath:mapping/**/*Mapper.xml\"));//扫描mapper.xml⽂ return factoryBean.getObject(); }

/**

* 配置事务管理器 */

@Bean

public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception { return new DataSourceTransactionManager(dataSource); }}

因篇幅问题不能全部显示,请点此查看更多更全内容

Top