編程生活

             :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            113 隨筆 :: 0 文章 :: 18 評論 :: 0 Trackbacks
          <2007年10月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          留言簿(5)

          隨筆檔案

          搜索

          積分與排名

          最新評論

          openJPA的用戶說明文檔中說明,在用createNativeQuery時,如果不是SELEC,則統(tǒng)一按存儲過程調(diào)用處理,但Oracle的存儲過程返回結(jié)果集的情況與MSSQL和Sybase等數(shù)據(jù)庫均不相同,它是返回一個引用游標,而不是直接返回結(jié)果集,即對CallableStatement不能直接調(diào)用executeQuery來取得結(jié)果集,而必須先用excute,然后用statement.getObject(int index)來取得結(jié)果集,因此,必須對源程序進行修改(0.9.7-1.0.0均要改)。按openJPA的設(shè)計思想,我在DBDictionary.java中(openjpa-jdbc組件下)增加兩個方法

          public class DBDictionary
              
          implements Configurable, ConnectionDecorator, JoinSyntaxes,
              LoggingConnectionDecorator.SQLWarningHandler 


          /**
               * register stored procedure resultset parameters
               * 
          @param stmnt
               * 
          @throws SQLException
               
          */

              
          public void regStoredProcedureResultParam(CallableStatement stmnt) throws SQLException {
              }

              
              
          /**
               * get stored procedure resultset
               * 
          @param stmt
               * 
          @return 
               * 
          @throws SQLException
               
          */

              
          public ResultSet getStoredProcedureOutResult(CallableStatement stmnt) throws SQLException {
                
          return null;
              }
           
          }
          然后修改OracleDictionary.java(openjpa-jdbc組件下),具體實現(xiàn)這兩個方法
          public class OracleDictionary
              
          extends DBDictionary {

              
          /**
               * register stored procedure resultset parameters
               * 
          @param stmnt
               * 
          @throws SQLException
               
          */

              
          public void regStoredProcedureResultParam(CallableStatement stmnt) throws SQLException {
                stmnt.registerOutParameter(
          1-10);
              }

              
              
          /**
               * get stored procedure resultset
               * 
          @param stmt
               * 
          @return 
               * 
          @throws SQLException
               
          */

              
          public ResultSet getStoredProcedureOutResult(CallableStatement stmnt) throws SQLException {
                stmnt.execute();
                
          return (ResultSet) stmnt.getObject(1);
              }
              
          }

          對于其它的數(shù)據(jù)庫,請打開對應(yīng)的Dictionary.java,進行針對性修改(我只用Oracle)
          然后再修改SQLStoreQuery.java
          public class SQLStoreQuery extends AbstractStoreQuery {
          private static class SQLExecutor extends AbstractExecutor {

          public ResultObjectProvider executeQuery(StoreQuery q, Object[] params, Range range) {
                JDBCStore store 
          = ((SQLStoreQuery) q).getStore();
                DBDictionary dict 
          = store.getDBDictionary();
                String sql 
          = q.getContext().getQueryString();

                List paramList;
                
          if (params.length > 0{
                  paramList 
          = new ArrayList(Arrays.asList(params));
                  
          try {
                    sql 
          = substituteParams(sql, paramList);
                  }
           catch (IOException ioe) {
                    
          throw new UserException(ioe);
                  }

                }
           else
                  paramList 
          = Collections.EMPTY_LIST;

                SQLBuffer buf 
          = new SQLBuffer(dict).append(sql);
                Connection conn 
          = store.getConnection();
                JDBCFetchConfiguration fetch 
          = (JDBCFetchConfiguration) q.getContext().getFetchConfiguration();

                
          boolean wrcall = false;
                ResultObjectProvider rop;
                PreparedStatement stmnt 
          = null;
                
          try {
                  
          // use the right method depending on sel vs. proc, lrs setting
                  if (_select && !range.lrs)
                    stmnt 
          = buf.prepareStatement(conn);
                  
          else if (_select)
                    stmnt 
          = buf.prepareStatement(conn, fetch, -1-1);
                  
          else {
                    
          // stored procedure
                    if (!range.lrs)
                      stmnt 
          = buf.prepareCall(conn);
                    
          else
                      stmnt 
          = buf.prepareCall(conn, fetch, -1-1);
                    
          // if the stored procedure has resultset,set the out resultset param
                    if (q.getContext().getResultType() != null{
                      dict.regStoredProcedureResultParam((CallableStatement) stmnt);
                      wrcall 
          = true;
                    }

                  }

                  
          int index = 0;
                  
          for (Iterator i = paramList.iterator(); i.hasNext();)
                    dict.setUnknown(stmnt, 
          ++index, i.next(), null);

                  ResultSetResult res 
          = new ResultSetResult(conn, stmnt, wrcall ? dict
                      .getStoredProcedureOutResult((CallableStatement) stmnt) : stmnt.executeQuery(), store);
                  
          if (_resultMapping != null)
                    rop 
          = new MappedQueryResultObjectProvider(_resultMapping, store, fetch, res);
                  
          else if (q.getContext().getCandidateType() != null)
                    rop 
          = new GenericResultObjectProvider((ClassMapping) _meta, store, fetch, res);
                  
          else
                    rop 
          = new SQLProjectionResultObjectProvider(store, fetch, res, q.getContext().getResultType());
                }
           catch (SQLException se) {
                  
          if (stmnt != null)
                    
          try {
                      stmnt.close();
                    }
           catch (SQLException se2) {
                    }

                  
          try {
                    conn.close();
                  }
           catch (SQLException se2) {
                  }

                  
          throw SQLExceptions.getStore(se, dict);
                }


                
          if (range.start != 0 || range.end != Long.MAX_VALUE)
                  rop 
          = new RangeResultObjectProvider(rop, range.start, range.end);
                
          return rop;
              }

          用maven重新編譯和打包,即可。
          用法:
          EntityManager em = ...
          Query q = em.createNativeQuery("{?=call a()}", A.class);
          List<?> list q.getResultList();
          posted on 2007-10-30 09:14 wilesun 閱讀(1528) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 讷河市| 巴彦县| 新野县| 平舆县| 开鲁县| 汉中市| 临桂县| 固阳县| 宜昌市| 咸阳市| 贵定县| 深水埗区| 五大连池市| 工布江达县| 孟连| 和硕县| 鄂温| 宜宾市| 达日县| 腾冲县| 新野县| 淮南市| 喀喇沁旗| 凉山| 汕尾市| 枣庄市| 呼伦贝尔市| 唐海县| 钟山县| 卢湾区| 大理市| 汾西县| 阳曲县| 蕉岭县| 咸阳市| 玉龙| 津南区| 正镶白旗| 贵溪市| 章丘市| 定远县|