我正在一個項目中處理不同模式的不同數據庫中的兩個表。因此,這意味着我有這兩個表的兩種不同的連接參數使用JDBC-通過隨機選取表執行SELECT sql
連接我們下面假設是config.property
文件 -
TABLES: table1 table2
#For Table1
table1.url: jdbc:mysql://localhost:3306/garden
table1.user: gardener
table1.password: shavel
table1.driver: jdbc-driver
table1.percentage: 80
#For Table2
table2.url: jdbc:mysql://otherhost:3306/forest
table2.user: forester
table2.password: axe
table2.driver: jdbc-driver
table2.percentage: 20
下面的方法將讀取上述config.property file
,併爲每一個ReadTableConnectionInfo object
表。
private static HashMap<String, ReadTableConnectionInfo> tableList = new HashMap<String, ReadTableConnectionInfo>();
private static void readPropertyFile() throws IOException {
prop.load(Read.class.getClassLoader().getResourceAsStream("config.properties"));
tableNames = Arrays.asList(prop.getProperty("TABLES").split(" "));
for (String arg : tableNames) {
ReadTableConnectionInfo ci = new ReadTableConnectionInfo();
String url = prop.getProperty(arg + ".url");
String user = prop.getProperty(arg + ".user");
String password = prop.getProperty(arg + ".password");
String driver = prop.getProperty(arg + ".driver");
double percentage = Double.parseDouble(prop.getProperty(arg + ".percentage"));
ci.setUrl(url);
ci.setUser(user);
ci.setPassword(password);
ci.setDriver(driver);
ci.setPercentage(percentage);
tableList.put(arg, ci);
}
}
下面是ReadTableConnectionInfo
類,將持有的所有特定表的表連接信息。
public class ReadTableConnectionInfo {
public String url;
public String user;
public String password;
public String driver;
public String percentage;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public double getPercentage() {
return percentage;
}
public void setPercentage(double percentage) {
this.percentage = percentage;
}
}
現在我對線程的指定數量創造的ExecutorService,並把該tableList object
來構造的ReadTask
講座
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
service.submit(new ReadTask(tableList));
}
下面是我ReadTask
實現Runnable interface
其中每個線程應該做連接每個表。
目前我有兩個表,這意味着每個線程都爲每個表中的兩個連接,然後用做SELECT *上取決於隨機生成數表中特定的表連接。
算法: -
- 生成隨機數1和100之間
- 如果該隨機數小於
table1.getPercentage()
然後選擇table1
然後用table1 statement object
做出SELECT sql call
該數據庫。 - 否則選擇
table2
,然後使用table2 statement object
爲該數據庫生成SELECT sql call
。
我Question-
我有搞清楚應該如何應用上面的算法,我應該如何比較random number
每個tables percentage
,然後再決定我需要使用哪個表和經過艱苦的時間那算出哪個table connection and statements
我需要用來做一個SELECT sql call
。
這意味着我需要檢查每張表的getPercentage()
方法,並將它們與隨機數進行比較。
現在我只有兩張桌子,將來我可以有三張桌子,百分比分佈可能爲80 10 10
。
更新: -
class ReadTask implements Runnable {
private Connection[] dbConnection = null;
private ConcurrentHashMap<ReadTableConnectionInfo, Connection> tableStatement = new ConcurrentHashMap<ReadTableConnectionInfo, Connection>();
public ReadTask(LinkedHashMap<String, XMPReadTableConnectionInfo> tableList) {
this.tableLists = tableList;
}
@Override
public run() {
int j = 0;
dbConnection = new Connection[tableLists.size()];
//loop around the map values and make the connection list
for (ReadTableConnectionInfo ci : tableLists.values()) {
dbConnection[j] = getDBConnection(ci.getUrl(), ci.getUser(), ci.getPassword(), ci.getDriver());
tableStatement.putIfAbsent(ci, dbConnection[j]);
j++;
}
Random random = new SecureRandom();
while (< 60 minutes) {
double randomNumber = random.nextDouble() * 100.0;
ReadTableConnectionInfo table = selectRandomConnection(randomNumber);
for (Map.Entry<ReadTableConnectionInfo, Connection> entry : tableStatement.entrySet()) {
if (entry.getKey().getTableName().equals(table.getTableName())) {
final String id = generateRandomId(random);
final String selectSql = generateRandomSQL(table);
preparedStatement = entry.getValue().prepareCall(selectSql);
preparedStatement.setString(1, id);
rs = preparedStatement.executeQuery();
}
}
}
}
private String generateRandomSQL(ReadTableConnectionInfo table) {
int rNumber = random.nextInt(table.getColumns().size());
List<String> shuffledColumns = new ArrayList<String>(table.getColumns());
Collections.shuffle(shuffledColumns);
String columnsList = "";
for (int i = 0; i < rNumber; i++) {
columnsList += ("," + shuffledColumns.get(i));
}
final String sql = "SELECT ID" + columnsList + " from "
+ table.getTableName() + " where id = ?";
return sql;
}
private ReadTableConnectionInfo selectRandomConnection(double randomNumber) {
double limit = 0;
for (ReadTableConnectionInfo ci : tableLists.values()) {
limit += ci.getPercentage();
if (random.nextDouble() < limit) {
return ci;
}
throw new IllegalStateException();
}
return null;
}
}
感謝sharakan的建議。我只是通過稍微修改代碼來更新我的問題。讓我知道這也不錯。關於你的查詢表。我會試着看看它是否成爲瓶頸。 – AKIWEB 2013-02-24 04:47:53
不,那不行。 1)nextRandom()每次調用它時會生成一個新的隨機數。 2)nextRandom()從[0..1]返回一個數字,如果'limit'的值將從[0..100]開始,則需要對其進行縮放。3)您應該創建一次Random對象,然後重複使用它,不要每次都重新創建它。看看javadocs:http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#nextDouble() – sharakan 2013-02-24 04:52:26
我想我對你發佈代碼的方式感到困惑。你能在你的代碼中告訴我你從哪裏得到randomNumber值嗎?如果您可以在我的代碼中提供基於代碼的實際流程,這也將非常有幫助。然後我可以正確理解流程。提前致謝。 – AKIWEB 2013-02-24 04:55:57