Spring-boot MyBatis配置 (2)

多数据源配置

  1. 分包: 不同数据源的在不同的目录下;事务的回滚需要创建根据数据源创建
  2. 注解
  3. AOP: aop注解切面需要在Service层进行数据源切换;事务可以将多个数据源放在一个事务中;

分包形式

不同的数据源的sql操作分布在不同的路径下

两个数据源的basepackage分别为:

  • com.yany.dao.multi.ads
  • com.yany.dao.multi.rds

在创建MapperScannerConfigurer时,对应不同的数据源扫描不同的basepackage路径

mapperScannerConfigurer.setBasePackage("xxxx");

对应的xml,即MAPPER_PATH

  • classpath:/com/yany/mapper/multi/ads/**.xml
  • classpath:/com/yany/mapper/multi/rds/**.xml

在创建SqlSessionFactoryBean时,MAPPER_PATH对应分别对应于ads和rds的sql路径

 sessionFactory.setMapperLocations(pathMatchingResourcePatternResolver.getResources(MAPPER_PATH));

在使用时,不同数据源的操作在分别在不同的路径创建即可。

注解形式

准备好两个注解类,分别对应于两个数据源:

public @interface RdsRepository {
}
public @interface AdsRepository {
}

同分包类似分别为Rds和Ads两个数据源创建两个SqlSessionFactoryBean和DataSourceTransactionManager,略微不同的是SqlSessionFactoryBean的setMapperLocations是允许相同路径
在创建两个MapperScannerConfigurer

    /**
     * 以注解的方式 进行多数据源配置
     *
     * @return
     */
    @Bean
    public MapperScannerConfigurer createAnnotatationAdsMapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.yany.dao.multi.annotation");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("annotationAdsSqlSessionFactory");
        mapperScannerConfigurer.setAnnotationClass(AdsRepository.class);
        return mapperScannerConfigurer;
    }

    /**
     * 以注解的方式 进行多数据源配置
     *
     * @return
     */
    @Bean
    public MapperScannerConfigurer createAnnotatationRdsMapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.yany.dao.multi.annotation");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("annotationRdsSqlSessionFactory");
        mapperScannerConfigurer.setAnnotationClass(RdsRepository.class);
        return mapperScannerConfigurer;
    }

上述代码和以前的主要的区别在:setAnnotationClass设置对应不同的注解类

使用时,在不同数据源的dao接口上添加对应的注解

@RdsRepository
public interface AnnotationRdsDao {
    int selectCount();
}
@AdsRepository
public interface AnnotationAdsDao {
    int selectCount();
}

而sql对应的xml不变,对应好namespace即可

AOP形式

创建一个动态数据源

  • 创建数据源类型的枚举类
public enum DatabaseType {
    Ads, Rds
}
  • 创建一个线程安全的DatabaseType容器
public class DatabaseContextHolder {
    private final static ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();

    public static DatabaseType getDatabaseType() {
        return contextHolder.get();
    }

    public static void setDatabaseType(DatabaseType type) {
        contextHolder.set(type);
    }

}

ThreadLocal类为每一个线程都维护了自己独有的变量拷贝,每个线程都拥有了自己独立的一个变量,避免并发问题。

  • 创建动态数据源DynamicDataSource继承AbstractRoutingDataSource
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DatabaseContextHolder.getDatabaseType();
    }
}
  • 创建AOP对应的MyBatis配置
    创建动态数据源的bean
    @Bean
    public DynamicDataSource setDataSource() {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DatabaseType.Ads, adsDataSource);
        targetDataSources.put(DatabaseType.Rds, rdsDataSource);

        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(rdsDataSource);// 默认的datasource设置为rdsDataSource
        return dataSource;
    }

创建SqlSessionFactoryBean和DataSourceTransactionManager以及这个和以前类似不再赘述,具体看github上代码

  • 创建切边
    扫描对应的Service层,在执行具体的服务代码前,根据调用的Service类进行数据源的切换。
@Aspect
@Component
public class DataSourceAspect {
    /**
     * 使用空方法定义切点表达式
     */
    @Pointcut("execution(* com.yany.service.**.*(..))")
    public void declareJointPointExpression() {
    }

    @Before("declareJointPointExpression()")
    public void setDataSourceKey(JoinPoint point) {
        if (point.getTarget() instanceof IAdsAopService ||
                point.getTarget() instanceof AdsAopServiceImpl) {
            //根据连接点所属的类实例,动态切换数据源
            System.out.println("IAdsAopService Aspect");
            DatabaseContextHolder.setDatabaseType(DatabaseType.Ads);
        } else {//连接点所属的类实例是(当然,这一步也可以不写,因为defaultTargertDataSource就是该类所用的rdsDataSource)
            System.out.println("IRdsAopService Aspect");
            DatabaseContextHolder.setDatabaseType(DatabaseType.Rds);
        }

    }
}

上述切换规则比较简单,具体可根据业务情况,包目录结构,或者是类名规则等进行解析切换。

具体代码将github:https://github.com/yany8060/SpringDemo.git
博客:http://yany8060.xyz

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,680评论 6 342
  • application的配置属性。 这些属性是否生效取决于对应的组件是否声明为Spring应用程序上下文里的Bea...
    新签名阅读 5,342评论 1 27
  • 妻子兄妹四人,作为八零后的我们这一“盛况”可谓是凤毛麟角。探其原由老丈人一门心思的为了中国千百年传统的思想那就是“...
    追梦CEO阅读 277评论 0 2
  • 文/带刺的玫瑰 你真的很贪水,隔着一层柔软 冷暖自知地游戏着 将母亲的召唤 置若罔闻 你从水中来,最是懂得 水的无...
    吉英子阅读 325评论 0 1
  • 故自格物至诚意,纯是一贯工夫。 近期遇到一创业者,拉拢我做微信公众平台一起创业。整个项目需要我付出时间和精力,虽然...
    菁小菁阅读 388评论 0 0