论坛首页 Java企业应用论坛

Hibernate执行原生态SQL语句通用方法

浏览 15395 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (11)
作者 正文
   发表时间:2010-03-03   最后修改:2010-03-03

Hibernate执行原生态SQL语句通用方法

      最近在给系统(原系统是Hibernate做的持久层)加一些统计方面的功能,一般用Hihbernate都是用DAO类继承org.springframework.orm.hibernate.support.HibernateDaoSupport类的getHibernateTemplate()方法来获取链接执行HQL语句。可是有时(如做一些统计功能时)一些比较复杂的SQL在转换成HQL比较麻烦时就希望Hibernate能直接SQL(不想在系统外再去加一个JDBC拉链)。

注:对参数cls(VO对象)的要求:cls对象的setter方法名get后的字母全大写(如:setMAXACCEPTDATE)

    

                /**
	 * @author crsystem
	 * @param sql SQL语句
	 * @param cls 查询结果集(ResultSet)转换成ArrayList时要用到的VO对象(如:GatherNodeVO.class)
	 * @return ResultSet
	 * 通过Hibernate 执行原生态的SQL语句通用方法
	 * 对参数cls(VO对象)的要求:cls对象的setter方法名get后的字母全大写(如:setMAXACCEPTDATE)
	 */
                @SuppressWarnings("unchecked")
	public List getListBysql(String sql,Class cls){
		List list=new ArrayList();
		Connection conn=null;
		Statement stm=null;
		ResultSet rs=null;
		try {
			conn=this.getHibernateTemplate().getSessionFactory().openSession().connection();
			stm = conn.createStatement();
			rs=stm.executeQuery(sql);
			ResultSetMetaData rsmd = rs.getMetaData(); //取得数据表中的字段数目,类型等返回结果
		    //是以ResultSetMetaData对象保存
		    int columnCount = rsmd.getColumnCount(); //列的总数
		    while(rs.next()){
		    	Object obj=Class.forName(cls.getName()).newInstance();//类的实例化
		    	for (int i = 1; i <= columnCount; i++) {
		    		//取得ActionForm或VO中的set方法
		    		String colName=rsmd.getColumnName(i); //获取字段名 (全大写) 
		    		//System.out.println("AAA "+colName);
                    colName=colName.replace(colName.charAt(0)+"", new String(colName.charAt(0)+"").toUpperCase()); //将字段名字母全大写  
                    String methodName="set"+colName;   //拼出setter方法名
                    //System.out.println("bbb "+methodName);   
                    
                    Object value=rs.getObject(i);//获取字段值   
                    //获得Model类的set方法,获取字段的类型设置为set方法的参数类型
                    Method method=obj.getClass().getMethod(methodName, value.getClass()); 
                    //调用set方法,将获取到的字段值设置到obj对象中
                    method.invoke(obj, value);   
		    	}
		    	list.add(obj);
		    }
		} catch (HibernateException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}finally{
			try {
//				if(null != rs){
//					rs.close();
//				}
				if(null != stm){
					stm.close();
				}
				if(null != conn){
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;	
	}
 

 参考:http://ibc.iteye.com/blog/247126

         http://blog.csdn.net/alexjjf/archive/2007/02/07/1504876.aspx

         http://www.blogjava.net/jrkui188/archive/2007/12/23/169757.html

         http://lavasoft.blog.51cto.com/62575/15433

我的第一篇博客,记录一下学习过程。

 

 

   发表时间:2010-03-04  
楼主标题党,这个就是原始JDBC的操作啊,跟Hibernate啥关系啊,除了通过HIbernate API获取一个connection,其他一点关系都没有啊。

你把conn=this.getHibernateTemplate().getSessionFactory().openSession().connection();  这句换成 JDBCUtil.getConnection()后就是最早的JDBC做法了。


0 请登录后投票
   发表时间:2010-03-04  
标题党,付上两种用法:

return hibernateTemplate.getSessionFactory().getCurrentSession().createSQLQuery(sql)
.setFirstResult(start)
.setMaxResults(size)
.setResultTransformer(Transformers.aliasToBean(CommunityView.class))
.list();



return getMyHibernateTemplate().getSessionFactory().getCurrentSession().createSQLQuery(sql).addEntity("orderItem", SysOrderItem.class).list
0 请登录后投票
   发表时间:2010-03-04  
Hibernate里记得好像直接有执行原生sql的方法?
0 请登录后投票
   发表时间:2010-03-04  
可以用下面的方法实现
/**
* 通过sql语句查询出符合条件的list
*/

public List findListBySqlQuery(final String queryString) {
return (List) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
if(queryString==null) throw new DaoParamException("BaseDao-Check.findPageByQuery - param can not be null");
Long beforTime = System.currentTimeMillis();
Connection conn = getConnection();
Statement stmt = conn.createStatement();
logger.info(queryString);
ResultSet resultSet = (ResultSet)stmt.executeQuery(queryString);
List listResult = new ArrayList();
while(resultSet.next()){


ResultSetMetaData rsmd = resultSet.getMetaData();  
int   columnCount   =   rsmd.getColumnCount();
Object[] arrObj = new Object[columnCount];
for(int j=0;j<arrObj.length;j++){
arrObj[j] = resultSet.getObject(j+1);
}
listResult.add(arrObj);
}
LogExecutionTime(System.currentTimeMillis() - beforTime);
return listResult;
}
}, true);
}
0 请登录后投票
   发表时间:2010-03-04  
这样做不如直接使用JDBC或者iBATIS。。没任何意义。。。
0 请登录后投票
   发表时间:2010-03-05  
额...有必要写的 这么复杂吗?
0 请登录后投票
   发表时间:2010-03-05  
yangdefeng95802 写道
可以用下面的方法实现
/**
* 通过sql语句查询出符合条件的list
*/
public class ApplicationDAO extends HibernateDaoSupport {
public List findListBySqlQuery(final String queryString) {
return (List) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
if(queryString==null) throw new DaoParamException("BaseDao-Check.findPageByQuery - param can not be null");
Long beforTime = System.currentTimeMillis();
Connection conn = getConnection();
Statement stmt = conn.createStatement();
logger.info(queryString);
ResultSet resultSet = (ResultSet)stmt.executeQuery(queryString);
List listResult = new ArrayList();
while(resultSet.next()){


ResultSetMetaData rsmd = resultSet.getMetaData();  
int   columnCount   =   rsmd.getColumnCount();
Object[] arrObj = new Object[columnCount];
for(int j=0;j<arrObj.length;j++){
arrObj[j] = resultSet.getObject(j+1);
}
listResult.add(arrObj);
}
LogExecutionTime(System.currentTimeMillis() - beforTime);
return listResult;
}
}, true);
}

Connection conn = getConnection();报错,不知是怎么获取的?
0 请登录后投票
   发表时间:2010-03-13  
确实有点标题党,想进步的话看看这里http://lgdlgd.iteye.com/admin/blogs/473147,这也许是此问题是最好的解决方案
0 请登录后投票
   发表时间:2010-03-15  
java_fxj 写道
额...有必要写的 这么复杂吗?

这样只要在原系统中加一个方法就可以完成一个或多个的统计功能(就是不想多改动原系统中一些底层DAO类),其它的一些些写法我基本上也都试过,可是在我的系统中行不通。
谢谢各位的观注和回复!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics