SpringMVC+Mybatis之多數據源搭建

(Notice:歡迎交流和溝通,Wx:IT_Ezra,QQ 654303408。僅個人觀點和個人理解有問題討論也可聯(lián)系我。)

(PS:寫這篇博客的原因是因為剛入行不久,第一次把自己的自己所學的東西應用在實際層面,更讓我意識到,基礎的重要性。)

使用場景:當我們的生產數據在逐漸增多,數據庫分庫分表技能也變得很常見。那么假如說,我們也用戶表放到DB1,把訂單表放到DB2…等。那么我們查詢的時候,要根據不同的數據庫去查不同的數據。眾所周知,通常一個Mybatis-config.xml里面是配置一個datasource,但是實際上是我們可以配置到多個datasource,然后通過spring-aop來實現(xiàn)。下面直接上干貨。

首先我們要配置mybatis的xml配置文件,當然有不規(guī)范的寫法,就是把其中的內容直接放到spring的beans.xml文件下也是能夠實現(xiàn)的。

1.datasource的配置,配置多個datasource,根據自己的實際情況而定。

DataSource

2.設置多數據源路由。實際上就是一個分發(fā)器,就是通過到時候切面的切點值來選擇不同的數據庫

多數據源路由

3 JDBC事務管理。配置jdbc的事務。spring里面也有事務注解來實現(xiàn)DB的事務。

JDBC事務管理

4 配置sessionFactory ,以及包掃描

配置sessionFactory

5 然后兩個工具類以及aop的實現(xiàn)。

切面接口,DataSourceAspect ,該接口是在service層。也可以實現(xiàn)controller層切

/**

  • @ author ezra
  • @ date 2019/7/5 11:27
    /
    @Slf4j
    @Aspect
    @Component
    @Order(1) //請注意:這里order一定要小于tx:annotation-driven的order,即先執(zhí)行DataSourceAspect切面,再執(zhí)行事務切面,才能獲取到最終的數據源
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    public class DataSourceAspect {
    /
    *
 * 切入點 service包及子孫包下的所有類   也可以改為controller級別下的所有
 */
@Pointcut("execution(* com.dfs.service..*.*(..))")
public void aspect() {
}
/**
 * 配置前置通知,使用在方法aspect()上注冊的切入點
 */
@Before("aspect()")
public void before(JoinPoint point) {
    Class<?> target = point.getTarget().getClass();
    MethodSignature signature = (MethodSignature) point.getSignature();
    Method method = signature.getMethod() ;
    DataSource dataSource = null ;
    //從類初始化
    dataSource = this.getDataSource(target, method) ;
    //從接口初始化
    if(dataSource == null){
        for (Class<?> clazz : target.getInterfaces()) {
            dataSource = getDataSource(clazz, method);
            if(dataSource != null){
                break ;//從某個接口中一旦發(fā)現(xiàn)注解,不再循環(huán)
            }
        }
    }
    if(dataSource != null && !StringUtils.isEmpty(dataSource.value()) ){
        HandleDataSource.setDataSource(dataSource.value());
    }
}
@After("aspect()")
public void after(JoinPoint point) {
    //使用完記得清空
    HandleDataSource.setDataSource(null);
}
/**
 * 獲取方法或類的注解對象DataSource
 * @param target    類class
 * @param method    方法
 * @return DataSource
 */
public DataSource getDataSource(Class<?> target, Method method){
    try {
        //1.優(yōu)先方法注解
        Class<?>[] types = method.getParameterTypes();
        Method m = target.getMethod(method.getName(), types);
        if (m != null && m.isAnnotationPresent(DataSource.class)) {
            return m.getAnnotation(DataSource.class);
        }
        //2.其次類注解
        if (target.isAnnotationPresent(DataSource.class)) {
            return target.getAnnotation(DataSource.class);
        }
    } catch (Exception e) {
        e.printStackTrace();
        log.error(MessageFormat.format("通過注解切換數據源時發(fā)生異常[class={0},method={1}]:"
                , target.getName(), method.getName()),e)  ;
    }
    return null ;
}

}

DataSource 注解接口

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value();
}

DataSourceRouter 工具類

public class DataSourceRouter extends AbstractRoutingDataSource {
// 獲取數據源名稱
protected Object determineCurrentLookupKey() {
return HandleDataSource.getDataSource();
}
}

HandleDataSource 工具類

public class HandleDataSource {
// 數據源名稱線程池
private static final ThreadLocal<String> holder = new ThreadLocal<String>();
/**
* 設置數據源
* @param datasource 數據源名稱
/
public static void setDataSource(String datasource) {
holder.set(datasource);
}
/
*
* 獲取數據源
* @return 數據源名稱
/
public static String getDataSource() {
return holder.get();
}
/
*
* 清空數據源
*/
public static void clearDataSource() {
holder.remove();
}
}

在Service添加注解,實現(xiàn)AOP。

在這里插入圖片描述

所有代碼已經實現(xiàn)。通過運行即可。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • MyBatis多數據源切換 項目結構為: 項目相關依賴pom.xml: 1、配置文件application.yml...
    zenghi閱讀 13,365評論 5 13
  • springAop:面向切面的編程 應用場景:權限控制、事物管理、日志打印等等,就是在不同的方法中重復用到相同的代...
    HJJ_3c00閱讀 431評論 0 0
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,995評論 0 11
  • 1.加入依賴 <!-- springboot-aop包,AOP切面注解,Aspectd等相關注解 --> <dep...
    如果我是周杰倫閱讀 1,162評論 0 0
  • 首先講的是三列布局,左右兩列寬度固定,中間一列寬度自適應 這個很好實現(xiàn),左右兩列分別左浮動和右浮動并給一個固定寬度...
    他在發(fā)呆閱讀 339評論 0 0

友情鏈接更多精彩內容