我需要一些建议,从你更有经验的编码与我有一个问题。
我创建了一个Java SE应用程序,它处理本地存储在MySQL服务器上的数据。它在有少量或记录的地方工作得很好,但当我开始提取大量记录时,它有时会冻结应用程序几秒钟,直到它获得所有数据。
我使用了DAO模式,并确保每次完成连接时都关闭连接。99%的时候我都是用预陈述(我没有使用它的唯一一次是没有连接到程序冻结的部分)
我尝试小批量加载记录,这样可以减少冻结的时间,但对我来说仍然是一个很大的问题。
当应用程序冻结并且没有看到任何错误时,我检查了NetBeans的日志,只有像一些system.out.println
这样的东西我放在各种循环和函数中处理数据。我只看到NetBeans输出日志,当GUI冻结时,应用程序在后台工作,system.out.println
文本向上滚动。
我想知道我能做些什么来阻止冻结或至少减少它?
我一直在考虑使用像c3p0这样的API,但我想先问问你的意见。
下面是GUI部分的代码示例
fx_trade_model ftm = new fx_trade_model();
ArrayList all2 = ftm.loadall_B(t);
,下面是外汇交易模型类的load all_B函数,它扩展了我的DAO类:
public ArrayList loadall_B(int x) throws SQLException {
ArrayList g = new ArrayList();
connect = Get_Conn();
statement = connect.createStatement();
resultSet = statement.executeQuery("select * from fx_trade limit "+ x +" ");
//preparedStatement.setInt(1, x);
while (resultSet.next()) {
fx_trade t = new fx_trade();
t.id = resultSet.getInt("id");
t.BS = resultSet.getString("BS");
t.account_id = resultSet.getInt("Account_id");
t.comm = resultSet.getDouble("comm");
t.fr = resultSet.getString("fr");
t.to = resultSet.getString("to");
t.price = resultSet.getDouble("price");
t.amount = resultSet.getInt("amount");
t.settle_date = resultSet.getDate("Settle_Date");
t.trade_date = resultSet.getDate("Trade_Date");
t.note = resultSet.getString("note");
//get qty in stock
t.qty = get_qty(t.id);
g.add(t);
}
connect.close();
return g;
}
您在这里看到的是数据库占用大量时间(?)来解析您的查询,因为您正在加载大量记录。此调用是一个同步调用,因此应用程序将等待,直到数据库能够生成包含所有结果的适当响应。
如何处理这些情况?
通常,你在另一个线程中执行这个慢的工作,并向用户显示一个漂亮的Loading message/gif/animation/etc。在后台线程完成它的工作后,它将数据检索回主线程,并继续执行当前的工作。可以通过创建一个新线程来加载数据来消除冻结。如果您希望用户等待数据,您可以提供一个进度条或旋转器来显示它正在加载。否则,你可以让用户与UI交互,而数据在后台加载。