Java Hibernate查询优化

Java Hibernate查询优化,java,hibernate,hql,Java,Hibernate,Hql,我有一段类似于以下内容的代码: public void doQuery(final Baz baz){ final Query query = getSessionFactory().getCurrentSession().createQuery( "select distinct foo from Foo as foo "+ "join foo.a as a"+ "join foo.b as b "+

我有一段类似于以下内容的代码:

  public void doQuery(final Baz baz){
    final Query query = getSessionFactory().getCurrentSession().createQuery(
            "select distinct foo from Foo as foo "+
            "join foo.a as a"+
            "join foo.b as b "+
            "join b.c as c "+
            "where baz=:baz"
            );
    query.setParameter("baz", baz);
    final List<Foo> list = query.list();

    for (final Foo foo : list) {
        final Set<C> cSet = foo.getB().getCs();
        final String value = foo.getSomeValue();
        for (final C c : cSet) {                
            final Long key = c.getSomeLong();
            // Do stuff with key and value
        }
    }
  }
public void doQuery(最终Baz Baz){
最终查询查询=getSessionFactory().getCurrentSession().createQuery(
“从foo中选择不同的foo作为foo”+
“加入foo.a成为一名”+
“以b的身份加入foo.b”+
“以c的身份加入b.c”+
“其中baz=:baz”
);
query.setParameter(“baz”,baz);
最终列表=query.List();
用于(最终Foo-Foo:列表){
最终设置cSet=foo.getB().getCs();
最终字符串值=foo.getSomeValue();
对于(最终C:cSet){
final Long key=c.getSomeLong();
//做一些关键和有价值的事情
}
}
}
每次执行for循环时,它都会在后台运行额外的hibernate查询来提取额外的数据(因为对象被标记为延迟加载)。不需要将这些对象切换到eager,因为其他使用POJO的类不需要该数据

显然,上面的代码会造成瓶颈,这是我想要避免的。是否有一种特定于hibernate的方法(即没有本机SQL)来修改查询,以便一次只返回必要的数据

我可以让查询返回一个字符串[],以col1作为键,以col2作为值,而不是返回Foo

更新:

我更改了查询,只返回所需的键/值


“从…

中选择distinct c.id,foo.someValue,因为我理解您的问题,您不希望在默认情况下让集合立即启动,但在这些具体情况下/方法在一个查询中获取所有数据?!”

以下是hibernate文档中与此相关的片段:

“fetch”联接允许使用单个select将值的关联或集合与其父对象一起初始化。这在集合的情况下特别有用。它有效地覆盖关联和集合映射文件的外部联接和惰性声明。请参阅第19.1节“fetch策略”了解更多信息


如果我理解正确,“延迟加载”可能就是您想要的。首先调整sql查询,然后转换为Hibernate查询。有几件事,请尽量避免使用“distinct”这是一个很重的问题,同时也尝试减少连接的数量。但是,延迟加载本质上不会运行相同的附加查询吗?我不确定是否要在POJO上运行即时加载,因为其他代码使用该类,不需要这些附加对象。这就是为什么我希望我能在查询中这样做(虽然我不想返回Foo,而是想象它会返回字符串[],其中col1是键,col2是值)+1表示延迟加载。基本上把Foo背面的集合标记为lazy。如果您正在使用注释,那么在注释中执行此操作(我认为它是@OneToMany(fetch=FetchType.Lazy),或者HBML中有一个属性。(但是谁使用HBML)我刚刚检查了POJO,它们是这些对象的延迟加载。这仍然让hibernate在后台运行我试图避免的其他查询。
from Cat as cat
    inner join fetch cat.mate
    left join fetch cat.kittens