package com.walker.store.strategy;
|
|
import com.walker.connector.Address;
|
import com.walker.dbmeta.util.DatabaseUtils;
|
|
import java.util.List;
|
|
/**
|
* 默认的多库单表存储策略。</p>
|
* 该策略适用于:
|
* <pre>
|
* 1、输入表不区分业务,只有一批,如:100个表
|
* 2、想把这些表存储到多个数据库中,便于维护
|
* </pre>
|
* @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<Address> 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<Address>配置");
|
return DatabaseUtils.copyAddress(using, true, using.getSuffixIndex()+1, this.defineDbName);
|
}
|
|
@Override
|
protected String doQueryTableName(Address address, String srcTable, Object parameter) {
|
return srcTable;
|
}
|
|
}
|