【问题标题】:Loop through Resultset depending on what columns are getting generated根据生成的列循环遍历结果集
【发布时间】:2013-02-27 19:48:28
【问题描述】:

我正在处理一个多线程项目,我需要在其中随机找到将在我的SELECT sql 中使用的columns,然后我将执行该 SELECT sql 查询。

找到那些列后-

  1. 我需要查看 id 是否在有效范围之间,如果它在有效范围之间,则使用 columnsList 中的那些列循环结果集并取回数据并存储在变量中。
  2. 否则,如果 id 不在有效范围内,我需要检查我没有从结果集中取回任何数据。但不知何故,如果我要取回数据并且标志为真以停止程序,然后退出程序。否则,如果我正在取回数据但标志为 false 以停止程序,那么请计算发生了多少次。

下面是我的代码-

private volatile int count;

@Override
public void run() {

.....

final String columnsList = getColumns(table.getColumns());
....
rs = preparedStatement.executeQuery();
....
if (Read.endValidRange < id && id < Read.startValidRange) {

    while (rs.next()) {
        for(String column: columnsList.split(",")) {
            System.out.println(column + ": " + rs.getString(column));
        }
    }
} else {
    if(rs.next() && Read.flagTerminate) {
        System.exit(1);
    } else {
        count++;
    }
}

....

}

/**
 * A simple method to get the column names in the order in which it was
 * inserted
 * 
 * @param columns
 * @return
 */
private String getColumns(final List<String> columns) {
    List<String> copy = new ArrayList<String>(columns);
    Collections.shuffle(copy);

    int rNumber = random.nextInt(columns.size());

    List<String> subList = copy.subList(0, rNumber);
    Collections.sort(subList, new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            return columns.indexOf(o1) < columns.indexOf(o2) ? -1 : 1;
        }
    });
    return StringUtils.join(subList, ",");
}

问题陈述-

我无法理解我应该如何遍历结果集,因为每次我的 SELECT sql 中都会有不同的列,具体取决于生成的内容。除此之外,我怎样才能使它在 if else 循环中更干净。

【问题讨论】:

  • 我正在做一个项目,我需要在其中随机查找需要在 SELECT sql 中使用的列,然后我将执行该查询。 - 什么?
  • Else if I am getting the data back but flag is false to stop the program, then count how many of those happening.你在说什么?
  • else if I am getting the data back but flag is false to stop the program, then count how many of those has happened。通过这个,我想说只是计算那些潜在的情况。而当程序结束时,再从主线程打印出来。就是这样。
  • @Nevzz03:由于此代码在多个线程之间共享,因此需要适当同步以避免竞争条件......

标签: java sql database resultset


【解决方案1】:

好的.. 您可以将随机生成的列保存在字符串数组中......然后在通过结果集迭代时使用该数组......如下所示: 更新
您不应该在 select 语句中包含这些列。相反,您应该使用 *...选择 select 语句中的所有列...然后在 rs.next() 循环中获取该列的值...

rs = con.executeQuery("Select * from tablename");
while(rs.next())
{
   for (String col : columnsList )
   {
     System.out.print(rs.get(col));
   }
   System.out.print("\n");
}

更新1
您需要将您在 run() 中编写的关键代码部分包装在同步块中,以避免出现竞争条件,如下所示:

private volatile int count;

@Override
public void run() {

.....
while (!Read.flagTerminate)
{
    synchronized(this)
    {
        if (!Read.flagTerminate)
        {
            String columnsList = getColumns(table.getColumns());
            ....
            rs = preparedStatement.executeQuery();
            ....
            if (Read.endValidRange < id && id < Read.startValidRange) 
            {
                while (rs.next()) 
                {
                    for(String column: columnsList.split(",")) 
                    {
                        System.out.println(column + ": " + rs.getString(column));
                    }
                }
            } 
            else 
            {
                while (rs.next())
                {
                    count++;
                }
            }
        }

    }
}
System.exit(0);//it implies that flag = true;

....

}

/**
 * A simple method to get the column names in the order in which it was
 * inserted
 * 
 * @param columns
 * @return
 */
private String getColumns(final List<String> columns) {
    List<String> copy = new ArrayList<String>(columns);
    Collections.shuffle(copy);

    int rNumber = random.nextInt(columns.size());

    List<String> subList = copy.subList(0, rNumber);
    Collections.sort(subList, new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            return columns.indexOf(o1) < columns.indexOf(o2) ? -1 : 1;
        }
    });
    return StringUtils.join(subList, ",");
}

【讨论】:

  • 感谢 Vishal,这是有道理的。我的第二点问题呢。它现在看起来非常难看,因为我已经做了很多次 if else 循环。还有更清洁的方法吗?
  • 从未经处理的输入中打开安全漏洞
  • @VishalK 当然。没有对实际传递给初始查询的字符串进行清理。因此,有人可以使用 SQL 注入并遍历应该隐藏的列名。如果您参考我的最新更新,您可以看到如何解决问题的大纲。
  • @VishalK。你能再告诉我一件事吗。我需要在这里使用 volatile 来获得准确的计数吗?
  • @Nevzz03 并且包含 run() 方法的对象(正在实现 Runnable ..i Guess)正在被多个线程共享?
【解决方案2】:

这个呢:

if (Read.endValidRange < id && id < Read.startValidRange) {
    while (rs.next()) {
        for (String column : columnsList.split(",")) {
            System.out.println(column + ": " + rs.getString(column));
        }
    }
} else if (rs.next()) {
    if (Read.flagTerminate) {
        System.exit(1);
    } else {
        count++;
    }
}

我还根据我对问题的理解更新了 if-else 条件。

【讨论】:

  • 感谢 Nishant。那讲得通。我的第二点问题呢。我目前所做的方式,如果设置了 else 循环,它看起来非常难看。有什么更清洁的方法吗?
  • 因为上面的代码不完整我搞不懂逻辑。你能展示更多的核心吗?
  • 我明白了。如果您阅读我的问题,我有两点,这将说明 if else 循环的完整内容。让我知道这仍然没有任何意义
  • 如果 id 超出范围并且您没有从结果集中取回任何数据会发生什么?
  • 这是我在问题中的第二点。我将只有有效的 ID 范围和无效的 ID 范围。我的程序将选择有效 id 或无效 id 来处理。
猜你喜欢
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 2013-09-14
相关资源
最近更新 更多