Hibernate直接执行SQL语句

又到周六时间了。我有一次帮公安局开发项目时,有这么一个需求,在做统计报表的时候,我在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再调用这个方法,得到我们前台想要的结果。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-29 19:10:56

Hibernate直接执行SQL语句的相关文章

使用Hibernate 拦截执行sql语句,并输出sql语句,获取sql语句

重建包名 org.hibernate.type.descriptor.sql 重建类BasicBinder 代码如下 package org.hibernate.type.descriptor.sql; import java.sql.PreparedStatement; import java.sql.SQLException; import org.hibernate.internal.CoreLogging; import org.hibernate.type.descriptor.Jdb

使用SQLQuery 在Hibernate中使用sql语句

session.createSQLQuery.转载 对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口.下面来描述如何使用这个API进行查询. 1.标量查询(Scalar queries) 最基本的SQL查询就是获得一个标量(数值)的列表. sess.createSQLQuery("SELECT * FROM CATS").list();sess.createSQLQuery("SELECT ID,

模拟Hibernate动态生成SQL语句

这里有一个xml配置文件,也就是Hibernate框架中会用到的POJO和数据库的映射文件 1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://www.hibernate.org/dtd/hibernate-

在myeclipse中配置DB Driver(数据库用MySql),并在myeclipse执行sql语句操作

在myeclipse中配置DB Driver(数据库用MySql),并在myeclipse执行sql语句操作 MyEclipse6.5    ,  mysq驱动jar包为mysql-connector-java-5.1.8-bin.jar 在MyEclipse中添加hibernate支持时需要用到DB Driver所以需要配置 首先选择window-->Open Perspective-->Other 出现下图:选择MyEclipse Database Explore. 点击OK后出现如下画面

JDBC系列:(3)使用PreparedStatement执行sql语句

执行sql语句的接口 接口 作用 Statement接口 用于执行静态的sql语句 PreparedStatement接口 用于执行预编译sql语句 CallableStatement接口 用于执行存储过程的sql语句(call xxx) PreparedStatement Vs Statement 序号 不同 描述 1 语法不同 PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql 2 效率不同 PreparedStatement可以使用sql缓存区

循环执行sql语句

DECLARE--声明变量SQL_ALLTABLES LONG; SQL_INSERT LONG; TYPE THE_CURSOR_TYPE IS REF CURSOR; --定义引用游标的数据类型CURSOR_D THE_CURSOR_TYPE; --定义游标 DATAUP VARCHAR2(200);BEGIN--井筒文档SQL_ALLTABLES := 'SELECT DISTINCT (TABLE_NAME) FROM USER_TAB_COLUMNS WHERE COLUMN_NAME

EF中执行sql语句

EF原理 EF 会自动把 Where().OrderBy().Select()等这些编译成"表达式树(Expression Tree)",然后会把表达式树翻译成 SQL 语句去执行.(编译原理,AST)因此不是"把数据都取到内存中,然后使用集合的方法进行数据过滤",因此性能不会低.但是如果这个操作不能被翻译成 SQL 语句,则或者报错,或者被放到内存中操作,性能就会非常低 跟踪EF的查询Sql语句: DbContext 有一个 Database 属性,其中的 Log

EntityFramework执行SQL语句

在EF中执行Sql语句. using (var context = new EFRecipesEntities()) { string sql = @"insert into Chapter3.Payment(Amount, Vendor) values (@Amount, @Vendor)"; var args = new DbParameter[] { new SqlParameter { ParameterName = "Amount", Value = 99

linux程序设计——执行SQL语句(第八章)

8.3    使用C语言访问MySQL数据 8.3.3 执行SQL语句 执行SQL语句的主要API函数被恰当的命名为: int mysql_query(MYSQL *connection, const char *query); 这个例程接受连接结构指针和文本字符串形式的有效SQL语句,如果成功,它返回0. 1.不返回数据的SQL语句 为简单起见,先看一些不返回任何数据的SQL语句:UPDATE,DELETE和INSERT. 下面的函数用于检查受查询影响的行数: my_ulonglong mys