免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      spring多數(shù)據(jù)源實(shí)現(xiàn)讀寫(xiě)分離

      一、常用場(chǎng)景

      讀寫(xiě)分離:寫(xiě)走主庫(kù),讀走從庫(kù)

      分庫(kù)分表:通常有兩種路由算法,范圍或hash。

      二、讀寫(xiě)分離實(shí)現(xiàn)方法

      1.實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源

      spring提供了抽象類AbstractRoutingDataSource,里面有兩個(gè)重要的參數(shù),

      targetDataSources代表提供的數(shù)據(jù)源。

      defaultTargetDataSource代表默認(rèn)數(shù)據(jù)源。

      public void setTargetDataSources(Map targetDataSources) { this.targetDataSources = targetDataSources;}public void setDefaultTargetDataSource(Object defaultTargetDataSource) { this.defaultTargetDataSource = defaultTargetDataSource;}

      還有一個(gè)抽象方法

      @Nullableprotected abstract Object determineCurrentLookupKey();

      我們可以繼承AbstractRoutingDataSource,實(shí)現(xiàn)determineCurrentLookupKey方法進(jìn)行動(dòng)態(tài)路由數(shù)據(jù)源。實(shí)現(xiàn)如下:

      public class DynamicRoutingDataSource extends AbstractRoutingDataSource { private static ThreadLocal ROUTING_KEY = new ThreadLocal(); @Override protected Object determineCurrentLookupKey() { return ROUTING_KEY.get(); } public static void setRoutingKey(String routingKey) { ROUTING_KEY.set(routingKey); } public static void removeRoutingKey() { ROUTING_KEY.remove(); } //不用重寫(xiě)改方法,這里是為了打印數(shù)據(jù)源信息 @Override public Connection getConnection() throws SQLException { DataSource dataSource = this.determineTargetDataSource(); logger.info(dataSource); return dataSource.getConnection(); }}

      2.基于注解的方式,實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源

      @Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Master {}@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Slave {}@Aspect@Component@Order(-99)public class MasterAop { @Pointcut(“@annotation(com.example.demo.aop.Master)”) public void recordAspect() {} @Around(“recordAspect()”) public Object recordAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { try { DynamicRoutingDataSource.setRoutingKey(“master”); return proceedingJoinPoint.proceed(); } finally { DynamicRoutingDataSource.removeRoutingKey(); } }}@Aspect@Component@Order(-99)public class SlaveAop { @Pointcut(“@annotation(com.example.demo.aop.Slave)”) public void recordAspect() { } @Around(“recordAspect()”) public Object recordAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { try { DynamicRoutingDataSource.setRoutingKey(“slave”); return proceedingJoinPoint.proceed(); } finally { DynamicRoutingDataSource.removeRoutingKey(); } }}

      3.配置數(shù)據(jù)源

      @Bean@Primarypublic DataSource dataSource() { DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource(); HikariConfig masterHikariConfig = new HikariConfig(); masterHikariConfig.setPassword(“xx”); masterHikariConfig.setUsername(“xx”); masterHikariConfig.setDriverClassName(“com.mysql.cj.jdbc.Driver”); masterHikariConfig.setJdbcUrl(“jdbc:mysql://xxxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true”); masterHikariConfig.setPoolName(“masterPool”); HikariDataSource masterDataSource = new HikariDataSource(masterHikariConfig); HikariConfig slaveHikariConfig = new HikariConfig(); slaveHikariConfig.setPassword(“xx”); slaveHikariConfig.setUsername(“xx”); slaveHikariConfig.setDriverClassName(“com.mysql.cj.jdbc.Driver”); slaveHikariConfig.setJdbcUrl(“jdbc:mysql://xxxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true”); slaveHikariConfig.setPoolName(“slavePool”); HikariDataSource slaveDataSource = new HikariDataSource(slaveHikariConfig); HashMap targetDataSources = new HashMap(); targetDataSources.put(“master”, masterDataSource); targetDataSources.put(“slave”, slaveDataSource); dynamicRoutingDataSource.setTargetDataSources(targetDataSources); return dynamicRoutingDataSource;}

      4.實(shí)現(xiàn)一個(gè)測(cè)試Service

      @Service@Slf4jpublic class MasterSlaveService { @Slave @Transactional public void slaveTest() { } @Master @Transactional public void masterTest() { }}

      5.測(cè)試如下

      @SpringBootApplication@EnableTransactionManagementpublic class RoutingDataSourceDemoApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(RoutingDataSourceDemoApplication.class, args); MasterSlaveService bean = run.getBean(MasterSlaveService.class); bean.masterTest(); bean.slaveTest(); }}

      我們可以看到數(shù)據(jù)源的切換信息

      com.zaxxer.hikari.HikariDataSource : masterPool – Starting…com.zaxxer.hikari.HikariDataSource : masterPool – Start completed.com.zaxxer.hikari.HikariDataSource : slavePool – Starting…com.zaxxer.hikari.HikariDataSource : slavePool – Start completed.c.e.d.RoutingDataSourceDemoApplication : Started RoutingDataSourceDemoApplication in 2.054 seconds (JVM running for 2.682)c.e.d.d.DynamicRoutingDataSource : HikariDataSource (masterPool)c.e.d.d.DynamicRoutingDataSource : HikariDataSource (slavePool)

      三、其他

      如果業(yè)務(wù)簡(jiǎn)單,我們可以自己實(shí)現(xiàn)數(shù)據(jù)源的切換,如果復(fù)雜的話,建議使用ShardingSphere框架,ShardingSphere是基于更底層的jdbc代理實(shí)現(xiàn)。

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
      用戶投稿
      上一篇 2022年7月1日 12:57
      下一篇 2022年7月1日 12:57

      相關(guān)推薦

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息