又到周六时间了。我有一次帮公安局开发项目时,有这么一个需求,在做统计报表的时候,我在Oralce数据中创建了一个视图,按管辖单位进行了分组,计算了每个管辖单位涉案人数及接警人数等,数据库视图倒是出来了,但是前台需求一个时间查询,也就是客户可以按时间检索,可是视图中,只能加上固定的时间进行where查询,但不能把时间字段加进去,一旦把时间字段加进去的话,就变成了按时间分组,原本管辖单位是六十来个,按时间分组就变成了上千上万条信息,这是不合要求的,这样根本无法统计出每个管辖单位的数据,因为数据库大,在查询时,性能也变慢。
在数据库中,可以写在where中写固定时间,一旦生成视图,在后台调用视图时,将无法再改变,在这里,就应该使用反射机制动态映射实体类,把SQL语言放在Hibernate中,直接执行语句,动态的把前台检索的条件传到后台中的SQL语句中的where中,然后Hibernate进行连接数据库并检查。
大家都知道,Hibernate主要还是使用Hql语句映射实体类进行与数据库关联。也就是说,你数据库表中的字段,都是要在实体类中映射对应的,要不然,就会报无法执行“could not execute query” 或是报‘标示符无效’等错误。因此,我们在这就要使用到反射进行映射一个数据库不存在的数据。说了这么多,我贴个代码段吧。
public List getAJTJ(String paramList,String bjsjTime,int startRow,
int endRow) {
String sql = "select * from (SELECT nvl(V.dwjc,'空') as gxdw,nvl(v.dwfj,'空') as GXFJ," +
"sum(decode((case when(v.zpje >= 600) then v.ajlx end),'案件',1,0)) as CAS," +
"sum(decode((case when(v.zpje < 600) then v.ajlx end),'案件',1,0)) as ZAAJ," +
"count(case when(v.ajlx='案件')then v.ajlx end) as ZS" +
" FROM VJJDB_ZPJQB V " +
" where 1=1 "+bjsjTime+
" group by v.dwjc,v.dwfj" +
" order by count(case when(v.ajlx='案件')then v.ajlx end) desc) Test where 1=1 "+ paramList ;
SQLQuery query = getSession().createSQLQuery(sql);
query.addEntity("V_WEB_AJFXTJ",V_WEB_AJTJ.class);
query.setFirstResult(startRow);
query.setMaxResults(endRow);
return query.list();
}
@Entity
@Table(name="V_WEB_AJFXTJ")
public class V_WEB_AJTJ {
@Id
@Column(name="GXDW")
private String GXDW; //管辖单位
@Column(name="GXFJ")
private String GXFJ; //管辖分局
@Column(name="CAS")
private int CAS; //成案数
@Column(name="ZAAJ")
private int ZAAJ; //治安案件
@Column(name="ZS")
private int ZS; //总数
//get/set....
上面对应的数据库表在数据库中是不存在的。表不存在,那字段自然也不存在,只是在他编译完后我们反射得到我们想要的而与,虽然这里说得抽象,但可以慢慢体会。步骤也就这两步而与,一个是Hibernate执行语句,一个是实体类,另外我再贴一下分页要用到的查询总数的代码,和查询语句是一样的,只是返回的是Int类型而与。
public int getCount(String paramList,String bjsjTime) {
String sql = "select * from (SELECT nvl(V.dwjc,'空') as gxdw,nvl(v.dwfj,'空') as GXFJ," +
"sum(decode((case when(v.zpje >= 600) then v.ajlx end),'案件',1,0)) as CAS," +
"sum(decode((case when(v.zpje < 600) then v.ajlx end),'案件',1,0)) as ZAAJ," +
"count(case when(v.ajlx='案件')then v.ajlx end) as ZS" +
" FROM VJJDB_ZPJQB V " +
" where 1=1 "+bjsjTime+
" group by v.dwjc,v.dwfj" +
" order by count(case when(v.ajlx='案件')then v.ajlx end) desc) Test where 1=1 "+ paramList ;
SQLQuery query = getSession().createSQLQuery(sql);
query.addEntity("V_WEB_AJFXTJ",V_WEB_AJTJ.class);
return query.list().size();
}
上面的语句就是返回一个查询数据的总数量,这两个查询都是Dao中的方法,我们在Action调用Service再调用这个方法,得到我们前台想要的结果。