我和国家一样有城市关系(城市不时被添加)。我希望制定一个查询规范来检索所有状态和它拥有的当前城市数量。理想情况下,在同一个查询中并尽可能高效。
我说的是规范,因为我希望将它与项目不同部分的其他规范相结合。
通常我会在我的数据库中使用触发器创建派生属性,但是可移植性是一个问题。在不影响效率的情况下,我在Spring应用程序中执行此操作有哪些选择?
由于我对Spring很新,我想过对状态进行查询,然后在foreach循环中计算城市,但肯定有更好的选择。
答案 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...
所以我认为只有一个大选择,对于你在结果中得到的每个状态都有一个子选择。
如果您有时需要并且有时不需要计数,则可以定义两个类StateEntity
和StateEntityWithCount 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();