Hibernate 查询数据时,速度慢的异常。请大家帮忙看看。

我使用SSH 在持久层进行查询,使用的是HibernteaTemplate().findByCriteria(DetachedCriteria.forClass(User.class))
进行查询 其中User.class是我在action里面传过来的 ,现在的问题是 我的User表中只有100多条信息 12列 每次打开网页查询的时间居然要15-30秒 才能打开页面数据,实在不太明白,所以来这里问问。希望能找到答案。

根据你提供的日志,这是你一次查询执行的所有SQL[code="SQL"]SELECT * FROM mastery.sale_pricing_record this_;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.doc_port docport0_ WHERE docport0_.id = ?;

SELECT * FROM mastery.doc_port docport0_ WHERE docport0_.id = ?;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.doc_port docport0_ WHERE docport0_.id = ?;

SELECT * FROM mastery.doc_port docport0_ WHERE docport0_.id = ?;

SELECT * FROM mastery.sale_customer this_;

SELECT * FROM mastery.doc_port this_;

SELECT * FROM mastery.doc_aircompany this_;

SELECT * FROM mastery.doc_shipcompany this_;[/code]其中我省略了你的表字段。

我们可以看下[code="sql"]SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;

SELECT * FROM mastery.sale_customer salecustom0_ WHERE salecustom0_.id = ?;[/code]
这个应该是你设置了一对多,但没有设置抓取数量导致的,针对一个id都需要一条sql,所以你需要设置下BatchSize。其他的就不说了。类似吧。注意个大小要合适,不能太大,因为其实他是吧上述四条SQL变成 id in (?,?,?...)的方式。

至于你的意外发现,我没怎么遇到过,不过你的log4j也挺复杂的。你可以只把写文件关了,看是不是由写文件导致的。在一个就是吧不需要的打印的信息去掉,指保留SQL的。这是我的ssh项目log4j给你参考下,很简单的[quote]
log4j.rootLogger=info, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %m [%l]%n

#下面是为了查看hibernate映射,设置为debug。想要生效,
#只需要吧第一行的info改成debug就行
log4j.appender.org.springframework.orm.hibernate3 = debug
[/quote]

对于log4j就只能提供这么多。你可以在自己搜搜。或者对你的log4j进行下测试。

100条数据不会要那么长时间的,肯定是其他的地方写的有问题,看看页面

还是用Spring的JDBCTemplate吧,定制性强,性能好、学习成本低

HibernteaTemplate().findByCriteria(DetachedCriteria.forClass(User.class))
如果User没有关联的话,可以这样写,简单也快:
[code="java"]
User user = new User();
user.setName("wasd");//查询条件
List list = session.createCriteria(User.class).add(Example.create(user)).list();
[/code]

可能是你的关联造成的性能问题。
最后吧后台打印的SQL发出来。hibernate慢的问题一般是由于表间关系在映射中配置不合适,导致的访问SQL比实际想想中多导致的。尤其是在表多关联的情况下,因此先考察下运行后后台打印的SQL数量跟你预期的是否相同

你的意思其实就是B表其实就先当于一个字典表,存放的是省份编码及对应的中文。而A表存放的是省份编码。你需要的是查询A表时显示是其对应的省份名称而非代码,但在A表中,省份编码字段是可以为空的。

那么你的配置不用看也肯定是A->B 是多对一的关系。那么你就需要在A中配置多对1时,允许b对象可以为空(not-null="true")。注意这里为空的意思意味着A表中与B关联的字段为空(不是0)。

对于你提到的[quote]org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [pojo.B#1] [/quote]
其实可以这样理解,你所谓A的省市代码可以为空其实你是用0表示的,但0这个地区代码你并没有在B表中出现。所以在做关联查询的时候,通过A拿B的时候,hibernate执行select name from b where id = 0 也就是代码中的 a.b (A a = session.list())时,会抛出这个错。

所以解决方法有两个:
1、你可以吧这个A表中不存在的省市代码置成空,而非0。
2、不该改动你现有代码,只是在B表中增加一条 no=0 name is null的数据即可。

当然建议你使用第一种,这样可以减少SQL语句。估计你的A中的编号是number,你的model里是int之类的原始类型。可以将model中的INT该车个封装类型,比如Integer等。当然那你改动了表结构,也一样需要这样改。

希望对你有所帮助!

呵呵,回复的慢了!

[quote]谢谢你的回复与帮助,这个问题已经解决了.在many to one里面加上not-found="ignore"就可以了,让他忽略.因为即使没有数据我也要显示.现在又回归到本质的问题了 就是查询速度非常的慢 我查询A这个类 结果花了5秒钟 A类和B类有一个关联映射关系 和C类有一个关联映射关系 然后我还需要查询B类和C类当中的两个字段 这个直接查 不需要映射 。这三个表中的数据加起来不超过200条 居然花了10秒多。。。很奇怪[/quote]

我还是希望你给出后台执行的SQL。

通过SQL你可以分析下,是不是比想想中的SQL语句都了。或者是不是因为没有设置BatchSize导致查询关联时n+1了。如果都不是,SQL也符合你的预期,那么执行下查询计划,看下到底问题出现在那里了。

[quote]不知道怎么给出后台的SQL....我是直接加载类去查询的。。。this.getHibernateTemplate().findByCriteria(DetachedCriteria.forClass(entity.class));[/quote]
spring+hibernate
true

单独的hibernate项目
true