`

hibernate中执行标准sql需要注意的问题

阅读更多
在hibernate执行标准的sql,一开始写了如下的代码:
java 代码
  1. public List querySQL(final String sql) {   
  2.     HibernateTemplate ht = getHibernateTemplate();   
  3.     return (List) ht.execute(new HibernateCallback() {   
  4.             public Object doInHibernate(Session session) throws HibernateException {   
  5.                    try {   
  6.                        SQLQuery query = session.createSQLQuery(sql);   
  7.                        return query.list();   
  8.                    } catch (RuntimeException e) {   
  9.                        log.error("query sql catch exception: " , e);   
  10.                        throw e;   
  11.                    }   
  12.             }   
  13.         });   
  14. }   

执行一般的查询还没有问题,但是对于某些复杂的sql语句,比如如下这句:

        sql="select fact.inetip as item1,count(distinct(fact.mac)) as item2 from report_fact_t fact where " +
        "not exists (select * from netbar_outsideips_t ips where fact.inetip=ips.ip) " +
        "and terminallog_time=str_to_date('2007-09-04','%Y-%m-%d') group by inetip";
就会报出如下的异常:

java 代码
  1. [appfuse] ERROR [main] LookupDaoHibernate.doInHibernate(56) | query sql catch exception:    
  2. org.hibernate.exception.SQLGrammarException: could not execute query   
  3.     at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)   
  4.     at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)   
  5. 。。。   
  6.   
  7. Caused by: java.sql.SQLException: Column 'inetip' not found.   
  8.     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)   
  9.     at com.mysql.jdbc.ResultSet.findColumn(ResultSet.java:955)   
  10.     at com.mysql.jdbc.ResultSet.getString(ResultSet.java:5447)  

很是奇怪的报错!查看了它的文档,也没有看到有啥特别的说明。最后通过试验发现对于复杂的对象类型,必须用addScalar说明数据的类型,才能正常工作。修改后的代码如下:

 

  1. public List querySQL(final String sql, final Map<String,Type> paramMap) {   
  2.     HibernateTemplate ht = getHibernateTemplate();   
  3.     return (List) ht.execute(new HibernateCallback() {   
  4.             public Object doInHibernate(Session session) throws HibernateException {   
  5.                    try {   
  6.                        SQLQuery query = session.createSQLQuery(sql);   
  7.                        Set entrySet=paramMap.entrySet();   
  8.                        for (Iterator it=entrySet.iterator();it.hasNext();) {   
  9.                            Entry entry=(Entry)it.next();   
  10.                            query=query.addScalar((String)entry.getKey(),(Type)entry.getValue());   
  11.                        }   
  12.                        return query.list();   
  13.                    } catch (RuntimeException e) {   
  14.                        log.error("query sql catch exception: " , e);   
  15.                        throw e;   
  16.                    }   
  17.             }   
  18.         });   
  19. }  

外部调用的时候,要传递数据的类型:

java 代码
  1.    sql="select fact.inetip as item1,count(distinct(fact.mac)) as item2 from report_fact_t fact where " +   
  2.    "not exists (select * from netbar_outsideips_t ips where fact.inetip=ips.ip) " +   
  3.    "and terminallog_time=str_to_date('2007-09-04','%Y-%m-%d') group by inetip";   
  4.   
  5.    Map paramMap=new HashMap();   
  6.    paramMap.put("item1", Hibernate.STRING);   
  7.    paramMap.put("item2",Hibernate.INTEGER);   
  8.   
  9. List results = dao.querySQL(sql,paramMap);  

修改以后就不会有问题啦

分享到:
评论
2 楼 hanqunfeng 2011-03-23  
很好,学习了
1 楼 fishyych 2007-10-10  
上面的东西搞错了一点,就是参数的传递应当使用list,如果使用map的话会造成类型和数据的顺序不一致而报错。

相关推荐

Global site tag (gtag.js) - Google Analytics