又到周六时间了。我有一次帮*局开发项目时,有这么一个需求,在做统计报表的时候,我在Oralce数据中创建了一个视图,按管辖单位进行了分组,计算了每个管辖单位涉案人数及接警人数等,数据库视图倒是出来了,但是前台需求一个时间查询,也就是客户可以按时间检索,可是视图中,只能加上固定的时间进行where查询,但不能把时间字段加进去,一旦把时间字段加进去的话,就变成了按时间分组,原本管辖单位是六十来个,按时间分组就变成了上千上万条信息,这是不合要求的,这样根本无法统计出每个管辖单位的数据,因为数据库大,在查询时,性能也变慢。
在数据库中,可以写在where中写固定时间,一旦生成视图,在后台调用视图时,将无法再改变,在这里,就应该使用反射机制动态映射实体类,把SQL语言放在Hibernate中,直接执行语句,动态的把前台检索的条件传到后台中的SQL语句中的where中,然后Hibernate进行连接数据库并检查。
大家都知道,Hibernate主要还是使用Hql语句映射实体类进行与数据库关联。也就是说,你数据库表中的字段,都是要在实体类中映射对应的,要不然,就会报无法执行“could not execute query” 或是报‘标示符无效’等错误。因此,我们在这就要使用到反射进行映射一个数据库不存在的数据。说了这么多,我贴个代码段吧。
public List<V_WEB_AJTJ> 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(); }
上面代码是一段查询方法,直接把SQL语句,bjsjTime是前台传到后台Action中的时间条件。paramList也是前台传到后台的条件与值,这样用String进行字符串拼接,使用成为一个可执行的SQL语句,然后把这个SQL语句扔到Hibernate工厂里进行执行:sessionfactory.getcurrentSession().createsQLQuery(sql),返回的是SQLQuery。然后我们用addEntity("", )给他反射映射一个实体类,字段就是前台要查询的条件,大家可以从我上面的代码中可得知,我的条件都是sum函数计算出来的别名,这个是在数据库中没有的字段,如果使用HQL语句的话,就必须对应数据库中有的字段才行。上面虽然使用了。class反射映射,但实体类还是要有的,
@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再调用这个方法,得到我们前台想要的结果。