posts - 28,comments - 3,trackbacks - 0
Hibernate3允许你使用手写的sql来完成所有的create,update,delete,和load操作(包括存储过程)    
   
  使用存储过程来查询  
  Hibernate   3引入了对存储过程查询的支持.   存储过程必须返回一个结果集,作为Hibernate能够使用的第一个外部参数.   下面是一个Oracle9和更高版本的存储过程例子.    
   
  CREATE   OR   REPLACE   FUNCTION   selectAllEmployments    
          RETURN   SYS_REFCURSOR    
  AS    
          st_cursor   SYS_REFCURSOR;    
  BEGIN    
          OPEN   st_cursor   FOR    
    SELECT   EMPLOYEE,   EMPLOYER,    
    STARTDATE,   ENDDATE,    
    REGIONCODE,   EID,   VALUE,   CURRENCY    
    FROM   EMPLOYMENT;    
              RETURN     st_cursor;    
    END;  
  在Hibernate里要要使用这个查询,你需要通过命名查询来映射它.    
   
  <sql-query   name="selectAllEmployees_SP"   callable="true">  
          <return   alias="emp"   class="Employment">  
                  <return-property   name="employee"   column="EMPLOYEE"/>  
                  <return-property   name="employer"   column="EMPLOYER"/>                          
                  <return-property   name="startDate"   column="STARTDATE"/>  
                  <return-property   name="endDate"   column="ENDDATE"/>                          
                  <return-property   name="regionCode"   column="REGIONCODE"/>                          
                  <return-property   name="id"   column="EID"/>                                                  
                  <return-property   name="salary">    
                          <return-column   name="VALUE"/>  
                          <return-column   name="CURRENCY"/>                          
                  </return-property>  
          </return>  
          {   ?   =   call   selectAllEmployments()   }  
  </sql-query>   
    
{ ? = call selectAllUsers() } 也可以写成{ call selectAllUsers() },
如果有参数就写成
{ ? = call selectAllUsers(?,?,?) }
代码中对query设置相应位置上的值就OK

Java调用关键代码如下
      
  Session session = HibernateUtil.currentSession();
  Query query = session.getNamedQuery("selectAllUsers");
  List list = query.list();
  System.out.println(list);

要求你的存储过程必须能返回记录集,否则要出错
如果你的存储过程是完成非查询任务就应该在配置文件用以下三个标签
  <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
  <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
  <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update> 

  注意存储过程当前仅仅返回标量和实体.现在不支持<return-join>和<load-collection>     
   
使用存储过程的规则和限制  
        为了在Hibernate中使用存储过程,你必须遵循一些规则.不遵循这些规则的存储过程将不可用.如果你仍然想要使用他们,   你必须通过session.connection()来执行他们.这些规则针对于不同的数据库.因为数据库   提供商有各种不同的存储过程语法和语义.    
   
  对存储过程进行的查询无法使用setFirstResult()/setMaxResults()进行分页。    
   
  对于Oracle有如下规则:    
   
  存储过程必须返回一个结果集.它通过返回SYS_REFCURSOR实现(在Oracle9或10),在Oracle里你需要定义一个REF   CURSOR   类型    
   
  推荐的格式是   {   ?   =   call   procName(<parameters>)   }   或   {   ?   =   call   procName   }(这更像是Oracle规则而不是Hibernate规则)    
   
  对于Sybase或者MS   SQL   server有如下规则:    
   
  存储过程必须返回一个结果集。.注意这些servers可能返回多个结果集以及更新的数目.Hibernate将取出第一条结果集作为它的返回值,   其他将被丢弃。    
   
  如果你能够在存储过程里设定SET   NOCOUNT   ON,这可能会效率更高,但这不是必需的。
posted on 2007-05-18 08:50 李大嘴 阅读(2559) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: