Springダイナミック作成データソース
Springダイナミック作成データソース
SpringはAbstract RoutingDataSourceを内蔵しており、Keyによって対応するデータソースを見つけることができます.じゃ、複数のデータソースをMapに保存して、keyによってデータソースを切り替えることができます.クラスを作成し、AbstractRoutingDataSource を継承します. keyはスレッドタイプRoutingData SourceConttextでアクセスします.RoutingData SourceContect類は以下の通りです. データソース を作成します.
SpringはAbstract RoutingDataSourceを内蔵しており、Keyによって対応するデータソースを見つけることができます.じゃ、複数のデータソースをMapに保存して、keyによってデータソースを切り替えることができます.
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return RoutingDataSourceContext.getDataSourceRoutingKey();
}
}
ここでdetermine Curent Lookup Keyはkeyに戻ります.自動的に対応するDataSourceを探しに行きます.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