下面是一个示例,使用一个查询来计算查询的大小,然后将处理分解到多个线程。
我使用MySQL,所以查询是为此编写的。您需要更改数据库引擎的查询。
public static void main(String[] args) throws Exception {
final int count;
try (final Connection conn = DATA_SOURCE.getConnection()) {
final String countQuery = "SELECT COUNT(*) FROM my_table";
try (final PreparedStatement ps = conn.prepareStatement(countQuery);
final ResultSet resultSet = ps.executeQuery()) {
resultSet.next();
count = resultSet.getInt(1);
}
}
final int chunksize = 1000;
final Queue<SqlResult> results = new ConcurrentLinkedQueue<>();
final ExecutorService es = Executors.newFixedThreadPool(10);
for (int end = 0; end < count; end += chunksize) {
es.execute(new ResultReader(count, end, DATA_SOURCE, results));
}
}
private static class ResultReader implements Runnable {
private final int start;
private final int size;
private final DataSource dataSource;
private final Queue<SqlResult> results;
public ResultReader(int start, int size, DataSource dataSource, Queue<SqlResult> results) {
this.start = start;
this.size = size;
this.dataSource = dataSource;
this.results = results;
}
@Override
public void run() {
try (final Connection connection = dataSource.getConnection()) {
final String query = "SELECT id, something, somethingElse FROM my_table LIMIT ?, ?";
try (final PreparedStatement ps = connection.prepareStatement(query)) {
ps.setInt(1, start);
ps.setInt(2, size);
try (final ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
final SqlResult sqlResult = new SqlResult();
sqlResult.setId(rs.getInt("id"));
sqlResult.setSomething(rs.getString("something"));
sqlResult.setSomethingElse(rs.getString("somethingElse"));
results.add(sqlResult);
}
}
}
} catch (SQLException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private static class SqlResult {
private int id;
private String something;
private String somethingElse;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSomething() {
return something;
}
public void setSomething(String something) {
this.something = something;
}
public String getSomethingElse() {
return somethingElse;
}
public void setSomethingElse(String somethingElse) {
this.somethingElse = somethingElse;
}
}
这假设您已经使用datasource
进行连接池。
问题内容: 使用JDBC时,我经常遇到类似 我问自己(也包括代码作者)为什么不使用标签来检索列值: 我听到的最好的解释是关于性能的。但是实际上,这使处理速度非常快吗?我不相信,尽管我从未进行过测量。我认为,即使按标签检索会稍慢一些,但它仍具有更好的可读性和灵活性。 因此,有人可以给我很好的解释,避免使用列索引而不是列标签来检索列值吗?两种方法的优缺点(也许涉及某些DBMS)是什么? 问题答案: 默
我是不是漏掉了什么?
问题内容: 如何使用(可能使用和)检索完整目录树? 问题答案: 默认情况下,将用于的第二个参数。这意味着它将仅返回文件。如果要包括文件 和 目录(至少这是我认为的 完整 目录树),则必须执行以下操作: 然后您就可以结束它。如果要返回目录树而不是输出它,则可以将其存储在数组中,例如 您还可以通过执行以下操作来创建没有的数组: 如果只想返回目录,则可以这样:
问题内容: 我需要连续运行几个查询 这是前两个ResultSet未正确关闭的问题还是在垃圾回收期间隐式完成? 问题答案: 一旦执行第二个查询,上一个查询就会自动关闭。就您而言,您不必担心。最后,您可以仅此而已。它将自动关闭所有相关对象。 看一下:-文档,其中说:- 当关闭,重新执行或用于从多个结果序列中检索下一个结果时,由该对象生成的Statement对象将自动关闭ResultSet对象。 如果要
问题内容: 在Java中,我试图从ResultSet中测试是否为空值,在ResultSet中,该列将被转换为原始 int 类型。 从上面的代码片段中,是否有更好的方法可以做到这一点,并且我认为第二个wasNull()测试是多余的? 教育我们,谢谢 问题答案: 默认时,字段值是返回,这也是您的默认值声明。在这种情况下,您的测试是完全多余的。 如果您实际上想在字段值为NULL的情况下执行其他操作,则建
问题内容: 对于为什么我无法使用urllib2从FriendFeed下载一些JSON响应的全部内容,我感到困惑。 如何使用urllib2检索完整响应? 问题答案: 获取所有数据的最佳方法: 原因是考虑到套接字的性质,不能保证返回整个响应。我以为是在文档中讨论过的(也许是),但找不到。