Springダイナミック作成データソース

5705 ワード

Springダイナミック作成データソース
SpringはAbstract RoutingDataSourceを内蔵しており、Keyによって対応するデータソースを見つけることができます.じゃ、複数のデータソースをMapに保存して、keyによってデータソースを切り替えることができます.
  • クラスを作成し、AbstractRoutingDataSource
  • を継承します.
    public class RoutingDataSource extends AbstractRoutingDataSource {
    
        @Override
        protected Object determineCurrentLookupKey() {
            return RoutingDataSourceContext.getDataSourceRoutingKey();
        }
    }
    
    ここでdetermine Curent Lookup Keyはkeyに戻ります.自動的に対応するDataSourceを探しに行きます.
  • keyはスレッドタイプRoutingData SourceConttextでアクセスします.RoutingData SourceContect類は以下の通りです.
    public class RoutingDataSourceContext  {
    
        static final ThreadLocal threadLocalDataSourceKey = new ThreadLocal<>();
    
        /**
         *        key
         * @return
         */
        public static String getMainKey() {
            return "fan_main";
        }
    
        /**
         *      key
         * @return
         */
        public static String getDataSourceRoutingKey() {
            String key = threadLocalDataSourceKey.get();
            return key == null ? getMainKey() : key;
        }
    
        /**
         *       key
         * @param key
         */
        public static void setThreadLocalDataSourceKey(String key) {
            threadLocalDataSourceKey.set(key);
        }
    
    }
    
  • データソース
  • を作成します.
    private synchronized void createAndSaveDataSource(String currentAccountSuit) {
            DruidDataSource dataSource = createDataSource(currentAccountSuit);
            log.info("{}       ", currentAccountSuit);
            dataSources.put(currentAccountSuit, dataSource);
            super.setTargetDataSources(dataSources);
            afterPropertiesSet();
     }
    
    ここでは、currentAcceountSuitに基づいてDruidDataSourceを作成し、作成後にMapに格納し、データソースを設定します.
    super.setTargetDataSources(dataSources);
    afterPropertiesSet();
    
    ここで使っているのはアリのドルイドです.createData Sourceの方法は以下の通りです.
    /**
         *      
         * @param currentAccountSuit
         * @return
         */
        private DruidDataSource createDataSource(String currentAccountSuit) {
            FanDataSource fanDataSource;
            if (currentAccountSuit.equalsIgnoreCase("fan_main")) {
                fanDataSource = new FanDataSource();
                fanDataSource.setName("fan_main");
                fanDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/fan_main?useUnicode=true&allowMultiQueries=true&useSSL=false");
                fanDataSource.setUsername("root");
                fanDataSource.setPassword("fxl123");
            } else {
                fanDataSource = getFanDataSource(currentAccountSuit);
            }
            if (fanDataSource == null) {
                throw new InvalidParameterException("     ");
            }
            return createDruidDataSource(fanDataSource);
        }
    
    メインカバーならファンです.mainは、接続情報を直接読み取り、他の帳簿カバーはget FanttaSourceで取得し、取得できない場合は異常を投げ、データベース接続の配置を見つけたらDruidDataSource、createDruidDataSource(fanDataSource)方法は以下の通りである.
    /**
         *       DruidDataSource
         * @param fanDataSource
         * @return
         */
        public static DruidDataSource createDruidDataSource(FanDataSource fanDataSource) {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setName(fanDataSource.getName());
            dataSource.setUrl(fanDataSource.getUrl());
            dataSource.setUsername(fanDataSource.getUsername());
            dataSource.setPassword(fanDataSource.getPassword());
    
            dataSource.setInitialSize(2);
            //              ,       
            dataSource.setTestOnBorrow(true);
            //         1     
            dataSource.setMinEvictableIdleTimeMillis(1 * 60000 * 60);
            //           
            dataSource.setTimeBetweenEvictionRunsMillis(600000);
            //   ilde      ,        
            dataSource.setTestWhileIdle(true);
            dataSource.setMaxWait(-1);
            return dataSource;
        }
    
    構造方法ではデフォルトのマスターライブラリ接続を初期化し、マスターデータベースからJdbcTemplateを作成します.
    public RoutingDataSource() {
          log.info("        ");
          createAndSaveDataSource(RoutingDataSourceContext.getMainKey());
    
          log.info("  jdbcTemplate");
          DruidDataSource dataSource = getDruidDataSource("fan_main");
          jdbcTemplate = new JdbcTemplate();
          jdbcTemplate.setDataSource(dataSource);
     }
    
    後の他のライブラリの接続資料はjdbcTemplateで取得します.
    /**
         *   jdbc            
         * @param name
         * @return
         */
        private FanDataSource getFanDataSource(String name) {
            String sql = "select name, url, username, password from fan_datasource where name = ?";
            RowMapper rowMapper = new BeanPropertyRowMapper<>(FanDataSource.class);
            return jdbcTemplate.queryForObject(sql, rowMapper, name);
        }
    
    determine Currenent LookuKeyは最終的に次のように実現しました.ユーザーがデータベース操作をすると、現在設定されているkeyを取得します.もしkeyに対応するデータソースが存在しないならば、作成します.存在すれば、直接に戻ります.
    @Override
    protected Object determineCurrentLookupKey() {
        String currentAccountSuit = RoutingDataSourceContext.getDataSourceRoutingKey();
        if (StringUtils.isEmpty(currentAccountSuit)) {
            currentAccountSuit = RoutingDataSourceContext.getMainKey();
        }
        log.info("      :{}", currentAccountSuit);
        if (!dataSources.containsKey(currentAccountSuit)){
           log.info("{}      ,         ", currentAccountSuit);
            createAndSaveDataSource(currentAccountSuit);
        } else {
            log.info("{}           ", currentAccountSuit);
        }
        log.info("   {}   ", currentAccountSuit);
        return currentAccountSuit;
    }
    
    データベースマスタファン_メイン、他の3つのライブラリのファン.001,ファン002,ファン_003完全プロジェクトコードgithub