queryimpl.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,262 行 · 第 1/3 页

JAVA
1,262
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.amber.manager;import com.caucho.amber.AmberException;import com.caucho.amber.cfg.ColumnResultConfig;import com.caucho.amber.cfg.EntityResultConfig;import com.caucho.amber.cfg.FieldResultConfig;import com.caucho.amber.cfg.SqlResultSetMappingConfig;import com.caucho.amber.entity.Entity;import com.caucho.amber.entity.EntityItem;import com.caucho.amber.expr.AmberExpr;import com.caucho.amber.expr.ArgExpr;import com.caucho.amber.expr.LoadEntityExpr;import com.caucho.amber.query.AbstractQuery;import com.caucho.amber.query.ResultSetImpl;import com.caucho.amber.query.SelectQuery;import com.caucho.amber.query.UserQuery;import com.caucho.amber.type.CalendarType;import com.caucho.amber.type.EntityType;import com.caucho.amber.type.UtilDateType;import com.caucho.ejb.EJBExceptionWrapper;import com.caucho.util.L10N;import javax.persistence.FlushModeType;import javax.persistence.LockModeType;import javax.persistence.NonUniqueResultException;import javax.persistence.NoResultException;import javax.persistence.Query;import javax.persistence.TemporalType;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.Types;import java.util.*;import java.util.logging.Level;import java.util.logging.Logger;/** * The EJB query */public class QueryImpl implements Query {  private static final L10N L = new L10N(QueryImpl.class);  private static final Logger log    = Logger.getLogger(QueryImpl.class.getName());  private AbstractQuery _query;  private UserQuery _userQuery;  private AmberConnection _aConn;  private int _firstResult;  private int _currIndex;  private FlushModeType _flushMode;  // Constructor queries.  private Class _primitiveColumns[];  // Native queries.  private String _nativeSql;  private PreparedStatement _nativeStmt;  private SqlResultSetMappingConfig _sqlResultSetMapping;  private int _currEntityResult;  private int _currColumnResult;  /**   * Creates a manager instance.   */  QueryImpl(AbstractQuery query, AmberConnection aConn)  {    _query = query;    _aConn = aConn;    _userQuery = new UserQuery(query);    _userQuery.setSession(_aConn);  }  /**   * Creates a manager instance.   */  QueryImpl(AmberConnection aConn)  {    _aConn = aConn;  }  /**   * Execute the query and return as a List.   */  public List getResultList()  {    ResultSet rs = null;    try {      // jpa/0y1b      if (_aConn.isInTransaction())        _aConn.flush();      Class constructorClass = null;      if (isSelectQuery()) {        if (! isNativeQuery()) {          SelectQuery selectQuery = (SelectQuery) _query;          constructorClass = selectQuery.getConstructorClass();        }      }      else        throw new IllegalStateException(L.l("javax.persistence.Query.getResultList() can only be applied to a SELECT statement"));      Constructor constructor = null;      ArrayList results = new ArrayList();      rs = executeQuery();      ResultSetMetaData metaData = null;      int columnCount = -1;      int n = 0;      Object row[] = null;      ArrayList columns = new ArrayList();      while (rs.next()) {        Object object = null;        _currIndex = 1;        if (n == 0) {          try {            metaData = rs.getMetaData();            if (metaData != null)              columnCount = metaData.getColumnCount();          } catch (Exception ex) {            // Below, we work around if DB is not able            // to retrieve result set meta data. jpa/0t00            metaData = null;          }          if (columnCount <= 0)            columnCount = 10000;          for (int i=1; i <= columnCount; i++) {            int columnType = -1;            try {              columnType = metaData.getColumnType(i);            } catch (Exception ex) {            }            try {              if (isNativeQuery()) {                ArrayList<EntityResultConfig> entityResults                  = _sqlResultSetMapping.getEntityResults();                if (_currEntityResult == entityResults.size()) {                  ArrayList<ColumnResultConfig> columnResults                    = _sqlResultSetMapping.getColumnResults();                  if (_currColumnResult == columnResults.size())                    break;                }                object = getInternalNative(rs);              }              else {                object = getInternalObject(rs, columnType);              }              columns.add(object);            } catch (IndexOutOfBoundsException ex1) {              break;            }            // catch (Exception ex2) {            //  break;            // }          }          n = columns.size();          row = columns.toArray();          if (constructorClass != null) {            _primitiveColumns = new Class[row.length];            StringBuilder argValues = new StringBuilder();            try {              // jpa/11a4, jpa/11a5              boolean isFirst = true;              for (int i=0; i < n; i++) {                if (isFirst)                  isFirst = false;                else                  argValues.append(", ");                argValues.append(row[i]);              }              Constructor ctors[] = constructorClass.getDeclaredConstructors();              ArrayList<Constructor> validConstructors                = new ArrayList<Constructor>();              for (int j=0; j < ctors.length; j++) {                Class paramTypes[] = ctors[j].getParameterTypes();                if (paramTypes.length != row.length)                  continue;                boolean isValid = true;                for (int k=0; k < paramTypes.length; k++) {                  Class columnClass = row[k].getClass();                  if (! paramTypes[k].isAssignableFrom(columnClass)) {                    if (! paramTypes[k].isPrimitive()) {                      isValid = false;                      break;                    }                    Class primitiveType                      = (Class) columnClass.getDeclaredField("TYPE").get(null);                    if (paramTypes[k].isAssignableFrom(primitiveType)) {                      // jpa/11a5                      _primitiveColumns[k] = primitiveType;                    }                    else {                      isValid = false;                      break;                    }                  }                }                if (isValid)                  validConstructors.add(ctors[j]);              }              constructor = validConstructors.get(0);            } catch (Exception ex) {              throw error(L.l("Unable to find constructor {0}. Make sure there is a public constructor for the given argument values ({1})", constructorClass.getName(), argValues));            }          }        }        else {          row = new Object[n];          for (int i=0; i < n; i++) {            int columnType = -1;            try {              columnType = metaData.getColumnType(i + 1);            } catch (Exception ex) {            }            if (isNativeQuery())              row[i] = getInternalNative(rs);            else              row[i] = getInternalObject(rs, columnType);          }        }        if (constructor == null) {          if (n == 1)            results.add(row[0]);          else            results.add(row);        }        else {          try {            for (int i=0; i < row.length; i++) {              Class primitiveType = _primitiveColumns[i];              if (primitiveType == null)                continue;              // jpa/11a5              if (primitiveType == Boolean.TYPE)                row[i] = ((Boolean) row[i]).booleanValue();              else if (primitiveType == Byte.TYPE)                row[i] = ((Byte) row[i]).byteValue();              else if (primitiveType == Character.TYPE)                row[i] = ((Character) row[i]).charValue();              else if (primitiveType == Double.TYPE)                row[i] = ((Double) row[i]).doubleValue();              else if (primitiveType == Float.TYPE)                row[i] = ((Float) row[i]).floatValue();              else if (primitiveType == Integer.TYPE)                row[i] = ((Integer) row[i]).intValue();              else if (primitiveType == Long.TYPE)                row[i] = ((Long) row[i]).longValue();              else if (primitiveType == Short.TYPE)                row[i] = ((Short) row[i]).shortValue();            }            object = constructor.newInstance(row);          } catch (Exception ex) {            StringBuilder argTypes = new StringBuilder();            boolean isFirst = true;            for (int i=0; i < row.length; i++) {              if (isFirst)                isFirst = false;              else                argTypes.append(", ");              if (row[i] == null)                argTypes.append("null");              else                argTypes.append(row[i].toString()); // .getClass().getName());            }            throw error(L.l("Unable to instantiate {0} with parameters ({1}).", constructorClass.getName(), argTypes));          }          results.add(object);        }      }      if (log.isLoggable(Level.FINER)) {        if (results != null) {          log.log(Level.FINER, L.l("query result list size: {0}", results.size()));          java.util.Iterator it = results.iterator();          while (it.hasNext()) {            Object o = it.next();            if (o == null)              log.log(Level.FINER, L.l("  result entry: null"));            else              log.log(Level.FINER, L.l("  result entry: {0}", o.getClass().getName()));          }        }      }      // jpa/0h19, jpa/1160      if (! _aConn.isActiveTransaction())        _aConn.detach();      return results;    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      throw EJBExceptionWrapper.createRuntime(e);    } finally {      if (rs != null) {        try {          rs.close();        } catch (SQLException e) {          log.log(Level.FINE, e.toString(), e);        }      }    }  }  /**   * Returns a single result.   */  public Object getSingleResult()  {    ResultSet rs = null;    try {      if (! isSelectQuery())        throw new IllegalStateException(L.l("javax.persistence.Query.getSingleResult() can only be applied to a SELECT statement"));      rs = executeQuery();      Object value = null;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?