Java 通过随机选取表来执行SELECTSQL
我正在从事一个项目,在该项目中,我在不同的数据库中有两个具有不同模式的表。这意味着我有两个不同的连接参数用于使用JDBC连接这两个表- 假设下面是Java 通过随机选取表来执行SELECTSQL,java,database,multithreading,random,executorservice,Java,Database,Multithreading,Random,Executorservice,我正在从事一个项目,在该项目中,我在不同的数据库中有两个具有不同模式的表。这意味着我有两个不同的连接参数用于使用JDBC连接这两个表- 假设下面是config.property文件- TABLES: table1 table2 #For Table1 table1.url: jdbc:mysql://localhost:3306/garden table1.user: gardener table1.password: shavel table1.driver: jdbc-driver tab
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文件
,并为每个表创建一个ReadTableConnectionInfo对象
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);
}
}
现在,我正在为指定数量的线程创建ExecutorService,并将这个tableList对象
传递给ReadTask
类的构造函数-
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
service.submit(new ReadTask(tableList));
}
目前我有两个表,这意味着每个线程将为每个表建立两个连接,然后根据随机生成数使用特定的表连接在该表上执行SELECT*
算法:-
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;
}
}
table1.getPercentage()
,则选择table1
然后使用table1语句对象
对该数据库进行selectsql调用
李>
table2
,然后使用table2语句对象
对该数据库进行selectsql调用
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;
}
}
我很难弄清楚应该如何应用上述算法,我应该如何比较随机数
与每个表的百分比
,然后决定需要使用哪个表,然后弄清楚需要使用哪个表连接和语句
来进行选择sql呼叫
这意味着我需要检查每个表的getPercentage()
方法,并将它们与随机数进行比较
现在我只有两个表,将来我可以有三个表,百分比分布可能为8010
更新:-
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;
}
}
class ReadTask实现可运行{
私有连接[]dbConnection=null;
私有ConcurrentHashMap tableStatement=新ConcurrentHashMap();
公共读取任务(LinkedHashMap表列表){
this.tableList=tableList;
}
@凌驾
公营{
int j=0;
dbConnection=新连接[tableLists.size()];
//循环映射值并创建连接列表
对于(ReadTableConnectionInfo ci:TableList.values()){
dbConnection[j]=getDBConnection(ci.getUrl(),ci.getUser(),ci.getPassword(),ci.getDriver());
表statement.putIfAbsent(ci,dbConnection[j]);
j++;
}
Random Random=新的SecureRandom();
而(<60分钟){
双随机数=random.nextDouble()*100.0;
ReadTableConnectionInfo table=选择随机连接(随机数);
for(Map.Entry:tableStatement.entrySet()){
if(entry.getKey().getTableName().equals(table.getTableName())){
最终字符串id=GeneratorDomain(随机);
最终字符串selectSql=generateRandomSQL(表);
preparedStatement=entry.getValue().prepareCall(选择SQL);
准备好的报表。设置字符串(1,id);
rs=preparedStatement.executeQuery();
}
}
}
}
私有字符串生成器SQL(ReadTableConnectionInfo表){
int rNumber=random.nextInt(table.getColumns().size());
List shuffledColumns=newarraylist(table.getColumns());
Collections.shuffle(shuffledColumns);
字符串columnsList=“”;
for(int i=0;i
无论您有多少个表,它们的百分比总和始终为100。概念化选择方式的最简单方法是将每个表视为代表一个百分比范围
例如,有三个表包含您提到的百分比(80%、10%、10%),您可以将它们概念化为:
随机数
From To==表==
0.0000 0.8000表1
0.8000 0.9000表2
0.9000 1.0000表3
因此,生成一个介于0.0000和1.0000之间的随机#,然后沿着有序列表,查看哪个范围合适,因此使用哪个表
(顺便说一句:我不知道为什么每个表都有两个连接。)不管有多少个表,它们的百分比加起来总是100。概念化选择方式的最简单方法是将每个表视为代表一个百分比范围 例如,有三个表包含您提到的百分比(80%、10%、10%),您可以将它们概念化为: 随机数 From To==表== 0.0000 0.8000表1 0.8000 0.9000表2 0.9000 1.0000表3 因此,生成一个介于0.0000和1.0000之间的随机#,然后沿着有序列表,查看哪个范围合适,因此使用哪个表
(顺便说一句:我不知道为什么每个表有两个连接。)您可以将其视为可用连接上的一个循环,如下所示:
public run() {
...
Random random = new SecureRandom();
while ( < 60 minutes) {
double randomNumber = random.nextDouble() * 100.0;
ReadTableConnectionInfo tableInfo = selectRandomConnection(randomNumber);
// do query...
}
}
private ReadTableConnectionInfo selectRandomConnection(double randomNumber) {
double limit = 0;
for (ReadTableConnectionInfo ci : tableLists.values()) {
limit += ci.getPercentage();
if (randomNumber < limit) {
return ci;
}
throw new IllegalStateException();
}
public run(){
...
Random Random=新的SecureRandom();
而(<60分钟){
双随机数=random.nextDouble()*100.0;
ReadTableConnectionInfo tableInfo=选择随机连接(随机编号
class LookupTable {
private int[] weights;
private String[] tables;
private int size = 0;
public LookupTable(int n) {
this.weights = new int[n];
this.tables = new String[n];
}
public void addTable(String tableName, int r) {
this.weights[size] = r;
this.tables[size] = tableName;
size++;
}
public String lookupTable(int n) {
for (int i = 0; i < this.size; i++) {
if (this.weights[i] >= n) {
return this.tables[i];
}
}
return null;
}
}
LookupTable tr = new LookupTable(3);
// make sure adds the range from lower to upper!
tr.addTable("table1", 20);
tr.addTable("table2", 80);
tr.addTable("table3", 100);
Random r = new Random(System.currentTimeMillis());
for (int i = 0; i < 10; i++) {
// r.nextInt(101) + 1 would return a number of range [1~100].
int n = r.nextInt(101) + 1;
String tableName = tr.lookupTable(n);
System.out.println(n + ":" + tableName);
}