日期:2014-05-20  浏览次数:20747 次

SSH项目中遇到问题
SSH项目框架
有个功能是按行读取TXT文件,可能有成千上万条
在Service中需要提取每条记录中的某些字段作为查询条件,在对查出的对象进行一些处理。每次查询的结果不是很多,只有1、2条
DAO使用Hibernate查询很慢。还会outOfMemery异常
后来改用了在DAO中使用JDBC连接
每次查询都先
conn = this.getSession(false).connection();
然后再关闭conn

部分代码如下:
public List<ChaobiaoJilu> findJfdqsCbjlByYqzhAndYhh(String yqzh, String bankcode) throws SQLException
{
conn = getConnection();
stmt = conn.createStatement();
StringBuffer hqlBf = new StringBuffer();
hqlBf.append("select cbjl.cbjl_id, cbjl.cbjl_yje, cbjl.cbjl_bcyql_js,cbjl.cbjl_yqzh,cbjl.cbjl_yqdz,cbjl.rh_id ");
hqlBf.append("from Chaobiao_Jilu cbjl,yongqidizhi yqdz ");
hqlBf.append("where cbjl.cbjl_yqdz=yqdz.yqdz_id ");
hqlBf.append("and cbjl.cbjl_Zt='" + 4 + "' ");
hqlBf.append("and cbjl.cbjl_yqzh='" + yqzh + "' ");
hqlBf.append("and cbjl.cbjl_yje>0 ");
hqlBf.append("and yqdz.yqdz_Fklx='" + 2 + "' ");
hqlBf.append("and yqdz.yqdz_Yhh='" + bankcode + "' ");
rs = stmt.executeQuery(hqlBf.toString());
List<ChaobiaoJilu> cjs = new ArrayList<ChaobiaoJilu>();
while (rs.next())
{
ChaobiaoJilu cj = new ChaobiaoJilu();
cj.setCbjlId(rs.getString("cbjl_id"));
cj.setCbjlYje(rs.getDouble("cbjl_yje"));
cj.setCbjlBcyqlJs(rs.getDouble("cbjl_bcyql_js"));
cj.setCbjlYqzh(rs.getString("cbjl_yqzh"));
cj.setYqdzID(rs.getString("cbjl_yqdz"));
cj.setRhID(rs.getString("rh_id"));
cjs.add(cj);
}
closeConnection();
return cjs;
}

这样改进后,是有点快了,但是数据TXT文件中记录多时,即以上的查询方法被调用了N次还会outOfMemery异常
异常的地方是:rs = stmt.executeQuery(hqlBf.toString());


不知道怎么在优化了,这个问题急待解决。谢谢高人指点




------解决方案--------------------
hibernate可以手动flush session啊

你不手动清一级缓存,当然会有溢出

具体办法就是做个判断,去多少行flush一下,依次走过
------解决方案--------------------

------解决方案--------------------
配一下连接池试试?
------解决方案--------------------
修改JDK的Xms Xmx,增加你服务器的内存使用量,不修改默认都比较小
------解决方案--------------------
异常的地方是:rs = stmt.executeQuery(hqlBf.toString()); 
说明hibernate都把查询出的记录加载到缓存中了,
建议定时的清楚缓存.
------解决方案--------------------
探讨
引用:
hibernate可以手动flush session啊

你不手动清一级缓存,当然会有溢出

具体办法就是做个判断,去多少行flush一下,依次走过


如果分批flushd的话,后面有异常,前面的会回滚吗?我不是很了解Hibernate

------解决方案--------------------
探讨
我测试了下,查询时间间隔比较长,是什么原因呢

------解决方案--------------------
试一下在每次cjs.add(cj)之后都把session给flush掉
------解决方案--------------------
可以在hibernate.cfg.xml中配置:
<session-factory> 
... 
<property name="hibernate.jdbc.batch_size">50</property> 
... 
</session.factory>
Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。一般设置为30、50、100。设置Fetch Size设置为:30、50,性能会有明显提升,如果继续增大,超出100,性能提升不明显,反而会消耗内存。
------解决方案--------------------
异常的地方是:rs = stmt.executeQuery(hqlBf.toString());