Tha*_*del 5 java hibernate subquery criteria-api jpa-2.0
到目前为止,我尝试将SQL查询转换为Criteria API但没有成功.我可以创建两个单独的查询,返回我需要的值,但我不知道如何在单个查询中组合它们.
这是有效的sql语句:
select company.*, ticketcount.counter from company
join
(select company, COUNT(*) as counter from ticket where state<16 group by company) ticketcount
on company.compid = ticketcount.company;
Run Code Online (Sandbox Code Playgroud)
此Criteria查询返回内部查询结果:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<intCompany> qTicket = cb.createQuery(intCompany.class);
Root<Ticket> from = qTicket.from(Ticket.class);
Path groupBy = from.get("company");
Predicate state = cb.notEqual(from.<State>get("state"), getStateById(16));
qTicket.select(cb.construct(
intCompany.class, cb.count(from),from.<Company>get("company")))
.where(state).groupBy(groupBy);
em.createQuery(qTicket).getResultList();
Run Code Online (Sandbox Code Playgroud)
在应用程序中我定义了一个小包装器/辅助类:
public class intCompany{
public Company comp;
public Long opentickets;
public intCompany(Long opentickets,Company comp){
this.comp = comp;
this.opentickets = opentickets;
}
public intCompany(){
}
}
Run Code Online (Sandbox Code Playgroud)
那么有谁知道如何使这个工作?
更新
谢谢.我按照你的建议改变了我的标准查询.我只需要在最后添加一个循环来获取我想要的信息.
List<intCompany> result = em.createQuery(cq).getResultList();
List<Company> cresult = new ArrayList();
for(intCompany ic: result){
ic.comp.setOpentickets(ic.opentickets.intValue());
cresult.add(ic.comp);
}
return cresult;
Run Code Online (Sandbox Code Playgroud)
也许只是不可能将原始的sql转换为Criteria API.
另一个更新
我想我必须将原来的sql表达式更改为
select company.*, ticketcount.counter from company
left join
(select company, COUNT(*) as counter from ticket where state<16 group by company) ticketcount
on company.compid = ticketcount.company;
Run Code Online (Sandbox Code Playgroud)
否则我不会让票证表中没有条目的公司.
还有其他建议吗?
你几乎已经完成了所有事情。
//---//
CriteriaBuilder cb = em.getCriteriaBuilder();
//Your Wrapper class constructor must match with multiselect arguments
CriteriaQuery<IntCompany> cq = cb.createQuery(IntCompany.class);
//Main table
final Root<Ticket> fromTicket= cq.from(Ticket.class);
//Join defined in Ticket Entity
final Path company = fromTicket.get("company");
//Data to select
cq.multiselect(cb.count(from), company);
//Grouping
cq.groupBy(company);
//Restrictions (I don't really understand what you're querying)
Predicate p = cb.lessThan(fromTicket.get("state"), 16);
//You can add more restrictions
// p = cb.and/or(p, ...);
cq.where(p);
List<IntCompany> results = entityManager.createQuery(cq).getResultList();
Run Code Online (Sandbox Code Playgroud)
这应该按预期工作。
| 归档时间: |
|
| 查看次数: |
9745 次 |
| 最近记录: |