package com.walker.store.strategy; import com.walker.connector.Address; import com.walker.dbmeta.util.DatabaseUtils; import java.util.List; /** * 默认的多库单表存储策略。
* 该策略适用于: ** 1、输入表不区分业务,只有一批,如:100个表 * 2、想把这些表存储到多个数据库中,便于维护 ** @author shikeying * @date 2015年12月18日 * */ public class OnlyMultiDatabaseStrategy extends DatabaseStoreStrategy { private int maxTablesInDatabase = 512; private int maxDatabaseInHost = 16; /** * 返回每个主机能存放数据库的最大数量 * @return */ public int getMaxDatabaseInHost() { return maxDatabaseInHost; } public void setMaxDatabaseInHost(int maxDatabaseInHost) { this.maxDatabaseInHost = maxDatabaseInHost; } /** * 返回系统设置的每个库存放表的最大值 * @return */ public int getMaxTablesInDatabase() { return maxTablesInDatabase; } public void setMaxTablesInDatabase(int maxTablesInDatabase) { this.maxTablesInDatabase = maxTablesInDatabase; } @Override protected Address doQueryAddress(String storeId, List addresses, Object parameter) { // 从现有的库中选择一个, if(this.getDefineAddressSize() > 1){ logger.debug("多库策略:存在多个地址库,查询表数量未超过的库"); Address usingAddr = this.getMetaDataEngine().getUsingAddress(getStoreId()); if(usingAddr == null){ usingAddr = this.getDefineAddressList().get(0); logger.debug("还没有使用任何库,需要选择第一个: " + usingAddr); return createFirstAddress(usingAddr); } else { logger.debug("已经使用了数据库:" + usingAddr); int tableSize = this.getMetaDataEngine().getTableSize(usingAddr); if(tableSize >= getMaxTablesInDatabase()){ logger.debug("表超过数量,准备切换数据库,tableSize = " + tableSize); // 如果存在多个主机,还要确定使用那个服务器 if(this.getMetaDataEngine().getDatabaseSize(usingAddr) >= getMaxDatabaseInHost()){ return switchHostServer(usingAddr); } else { return DatabaseUtils.copyAddress(usingAddr, true, usingAddr.getSuffixIndex()+1, this.defineDbName); } } else { return usingAddr; } } } else { logger.debug("MultiDbSingleTableStrategy:只有一个地址库"); Address usingAddr = this.getMetaDataEngine().getUsingAddress(getStoreId()); if(usingAddr == null){ logger.debug("还没有使用任何库,需要选择第一个"); usingAddr = this.getDefineAddressList().get(0); return createFirstAddress(usingAddr); } else { logger.debug("已经使用了数据库:" + usingAddr); int tableSize = this.getMetaDataEngine().getTableSize(usingAddr); logger.debug("数据库 '" + usingAddr.getServiceName() + "' 表数量 = " + tableSize); if(tableSize >= getMaxTablesInDatabase()){ Address changedAddr = DatabaseUtils.copyAddress(usingAddr, true, usingAddr.getSuffixIndex()+1, this.defineDbName); logger.info("表数量超过最大值,更换数据库:" + changedAddr); return changedAddr; } else { return usingAddr; } } } } private Address createFirstAddress(Address addr){ return DatabaseUtils.copyAddress(addr, true, 1, this.defineDbName); } private Address switchHostServer(Address using){ for(Address a : this.getDefineAddressList()){ if(!using.getUrl().equals(a.getUrl()) || using.getPort() != a.getPort()){ return DatabaseUtils.copyAddress(a, false, using.getSuffixIndex()+1, this.defineDbName); } } logger.warn("无法切换数据库,还使用目前的。请检查List配置"); return DatabaseUtils.copyAddress(using, true, using.getSuffixIndex()+1, this.defineDbName); } @Override protected String doQueryTableName(Address address, String srcTable, Object parameter) { return srcTable; } }