在春天选择和统计

时间:2017-04-17 04:47:13

标签: spring hibernate spring-data-jpa

我和国家一样有城市关系(城市不时被添加)。我希望制定一个查询规范来检索所有状态和它拥有的当前城市数量。理想情况下,在同一个查询中并尽可能高效。

我说的是规范,因为我希望将它与项目不同部分的其他规范相结合。

通常我会在我的数据库中使用触发器创建派生属性,但是可移植性是一个问题。在不影响效率的情况下,我在Spring应用程序中执行此操作有哪些选择?

由于我对Spring很新,我想过对状态进行查询,然后在foreach循环中计算城市,但肯定有更好的选择。

2 个答案:

答案 0 :(得分:1)

StateEntity中,您可以使用@Formula加子查询来获取城市号码。

@Entity
@Table(name="state")
public class StateEntity

    @Id
    @Column(name="state_id")
    private int id;

    ....
    @Formula(" (select count(*) from city c where c.state_id=state_id ")
    public int citiesCount;

在这里,我假设您有一个表city,其中列state_id引用state表主键state_id

更新: 实际上,它在SQl中转换为

select
  state_id,
  ... some more columns
  (select count(*) from city c where c.state_id=state_id) as cities_count
from
... all the conditions and joins here...

所以我认为只有一个大选择,对于你在结果中得到的每个状态都有一个子选择。

如果您有时需要并且有时不需要计数,则可以定义两个类StateEntityStateEntityWithCount extends StateEntity。带公式的count列可以添加到StateEntityWithCount中。根据您是否需要计数,您可以使用相应的实体类。

关于便携性你是对的。在通常情况下,这是真的。 SQL不是可移植的,但SQL是标准的,据我所知,大多数RDBMS都支持表达式。第二,你真的需要改变DB吗?变化的概率是多少?

最后。您可以编写单独的查询(基于HQL)来检索您传递的每个州的城市计数。这也是可能的解决方案。见here an example

答案 1 :(得分:1)

您想要构建一个HQL查询,如下所示:

select state_id, state_name, count(city_id)
from states
group by state_id, state_name 

然后你可以通过写下这样的东西来提取结果:

SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
  Session session = sessionFactory.openSession();
  session.beginTransaction();

  String SQL_QUERY = "select state_id, state_name, count(city_id)
                      from states
                      group by state_id, state_name ";

  Query query = session.createQuery(SQL_QUERY);

  for(Iterator it=query.iterate();it.hasNext();)
  {
   Object[] row = (Object[]) it.next();
   System.out.print("State Name: " + row[1]);
   System.out.println(" | Number of Cities: " + row[2]);
  }
  session.getTransaction().commit();
  session.close();