예제 #1
0
  public int bulkUpdateByPrimaryKey(
      final String entityName, final Map<String, ?> updateValues, final List<Long> keys) {
    int result = 0;

    if ((entityName == null)
        || (updateValues == null)
        || updateValues.isEmpty()
        || (keys == null)
        || keys.isEmpty()) {
      return 0;
    }

    try {
      final GenericHelper entityHelper = delegatorInterface.getEntityHelper(entityName);
      final ModelEntity modelEntity = delegatorInterface.getModelEntity(entityName);

      final List<String> pks = modelEntity.getPkFieldNames();
      if (pks.size() != 1) {
        throw new DataAccessException(
            "BulkUpdateByPrimaryKey only works for single column keys at this moment.");
      }
      final String pkName = pks.get(0);

      final Updater updater =
          new Updater(
              ModelFieldTypeReader.getModelFieldTypeReader(entityHelper.getHelperName()),
              entityName);
      final List<Updater.Value> params = new ArrayList<Updater.Value>();

      final StringBuilder updateSql = new StringBuilder("UPDATE ");

      updateSql.append(modelEntity.getTableName(entityHelper.getHelperName()));
      updateSql.append(" SET ");
      // generate the update sql
      for (final Iterator<String> iterator = updateValues.keySet().iterator();
          iterator.hasNext(); ) {
        final String column = iterator.next();
        updateSql.append(" ");
        final ModelField field = modelEntity.getField(column);
        updateSql.append(field.getColName());
        updateSql.append(" = ");
        params.add(updater.create(field, updateValues.get(column)));
        updateSql.append("? ");
        if (iterator.hasNext()) {
          updateSql.append(", ");
        }
      }

      // generate the where clause
      updateSql.append(" WHERE ");

      // batch the update
      final int batchSize = getQueryBatchSize();

      int currentIndex = 0;

      while (currentIndex < keys.size()) {
        int i = 0;
        final StringBuilder idClause = new StringBuilder();
        final ArrayList<Long> idParams = new ArrayList<Long>();
        for (final Iterator<Long> iterator = keys.subList(currentIndex, keys.size()).iterator();
            iterator.hasNext() && (i < batchSize);
            i++) {
          final Long key = iterator.next();
          idClause.append(" ");
          idClause.append(pkName);
          idClause.append(" = ");
          idParams.add(key);
          idClause.append("? ");

          if (iterator.hasNext() && ((i + 1) < batchSize)) {
            idClause.append(" or ");
          }
        }

        final SQLProcessor processor = new AutoCommitSQLProcessor(entityHelper.getHelperName());
        processor.prepareStatement(updateSql.toString() + idClause.toString());
        for (final Updater.Value param : params) {
          param.setValue(processor);
        }
        for (final Long idParam : idParams) {
          processor.setValue(idParam);
        }

        try {
          result = processor.executeUpdate();
        } finally {
          processor.close();
        }
        currentIndex += i;
      }
    } catch (final GenericEntityException e) {
      throw new DataAccessException(e);
    } catch (final SQLException e) {
      throw new DataAccessException(e);
    } catch (final NoClassDefFoundError e) {
      // under JDK 1.3 unit tests - javax.sql.XADataSource cannot be found.
      // this shouldn't affect runtime - application servers should ship the jar
    }
    return result;
  }
예제 #2
0
  public int bulkCopyColumnValuesByAnd(
      final String entityName, final Map updateColumns, final Map criteria) {
    int result = 0;

    if ((entityName == null) || (updateColumns == null) || updateColumns.isEmpty()) {
      return 0;
    }

    try {
      final ModelEntity modelEntity = delegatorInterface.getModelEntity(entityName);

      final GenericHelper entityHelper = delegatorInterface.getEntityHelper(entityName);

      final ModelFieldTypeReader modelFieldTypeReader =
          ModelFieldTypeReader.getModelFieldTypeReader(entityHelper.getHelperName());

      final ArrayList<EntityConditionParam> params = new ArrayList<EntityConditionParam>();

      // generate the update sql
      final StringBuilder updateSql = new StringBuilder("UPDATE ");

      updateSql.append(modelEntity.getTableName(entityHelper.getHelperName()));
      updateSql.append(" SET ");

      if (!modelEntity.areFields(updateColumns.keySet())) {
        throw new GenericModelException(
            "At least one of the passed fields for update is not valid: "
                + updateColumns.keySet().toString());
      }

      if (!modelEntity.areFields(updateColumns.values())) {
        throw new GenericModelException(
            "At least one of the passed fields for update is not valid: "
                + updateColumns.values().toString());
      }

      for (final Iterator iterator = updateColumns.keySet().iterator(); iterator.hasNext(); ) {
        final String column = (String) iterator.next();
        updateSql.append(" ");
        final ModelField toModelField = modelEntity.getField(column);
        updateSql.append(toModelField.getColName());
        updateSql.append(" = ");
        final ModelField fromModelField = modelEntity.getField((String) updateColumns.get(column));
        updateSql.append(fromModelField.getColName());
        if (iterator.hasNext()) {
          updateSql.append(", ");
        }
      }

      if ((criteria != null) && !criteria.isEmpty()) {
        if (!modelEntity.areFields(criteria.keySet())) {
          throw new GenericModelException(
              "At least one of the passed fields is not valid: " + criteria.keySet().toString());
        }

        // generate the where clause
        final EntityFieldMap entityCondition = new EntityFieldMap(criteria, EntityOperator.AND);

        final String entityCondWhereString = entityCondition.makeWhereString(modelEntity, params);

        if (entityCondWhereString.length() > 0) {
          updateSql.append(" WHERE ");
          updateSql.append(entityCondWhereString);
        }
      }

      final SQLProcessor processor = new AutoCommitSQLProcessor(entityHelper.getHelperName());
      final String sql = updateSql.toString();

      if (log.isDebugEnabled()) {
        log.debug("Running bulk update SQL: '" + sql + '\'');
      }

      processor.prepareStatement(sql);

      for (final EntityConditionParam conditionParam : params) {
        SqlJdbcUtil.setValue(
            processor,
            conditionParam.getModelField(),
            modelEntity.getEntityName(),
            conditionParam.getFieldValue(),
            modelFieldTypeReader);
      }

      try {
        result = processor.executeUpdate();
      } finally {
        processor.close();
      }
    } catch (final GenericEntityException e) {
      throw new DataAccessException(e);
    } catch (final NoClassDefFoundError e) {
      // under JDK 1.3 unit tests - javax.sql.XADataSource cannot be found.
      // this shouldn't affect runtime - application servers should ship the jar
    }

    return result;
  }
예제 #3
0
  public int removeByOr(final String entityName, final String entityId, final List<Long> ids)
      throws DataAccessException, GenericModelException {
    int result = 0;

    final ModelEntity modelEntity = delegatorInterface.getModelEntity(entityName);

    if (modelEntity == null) {
      throw new GenericModelException("The entityName passed in was not valid: " + entityName);
    } else if (!modelEntity.isField(entityId)) {
      throw new GenericModelException(
          "The entityId passed in was not valid for the given entity: " + entityId);
    }
    final ModelField modelField = modelEntity.getField(entityId);

    try {
      final GenericHelper entityHelper = delegatorInterface.getEntityHelper(entityName);
      // Generate SQL
      final StringBuilder removeSql = new StringBuilder("DELETE FROM ");

      removeSql.append(modelEntity.getTableName(entityHelper.getHelperName()));
      removeSql.append(" WHERE ");
      removeSql.append(modelField.getColName());
      removeSql.append(" IN (");

      final int idsSize = ids.size();
      final ArrayList<Long> idParams = new ArrayList<Long>();
      StringBuilder idClause = new StringBuilder();

      // batch the update
      final int batchSize = getQueryBatchSize();
      int batchIndex = 0;
      for (int i = 0; i < idsSize; i++) {
        idParams.add(ids.get(i));
        idClause.append("?");

        final boolean isEndOfBatch = (batchIndex == batchSize - 1);
        final boolean isEndOfIdList = (i == idsSize - 1);

        if (isEndOfBatch || isEndOfIdList) {
          final SQLProcessor processor = new AutoCommitSQLProcessor(entityHelper.getHelperName());
          // finish batch
          idClause.append(")");
          try {
            processor.prepareStatement(removeSql.toString() + idClause.toString());
            for (final Long idParam : idParams) {
              processor.setValue(idParam);
            }
            // execute update
            result += processor.executeUpdate();

            // clean-up for the next batch
            idParams.clear();
            idClause = new StringBuilder();
            batchIndex = 0;
          } finally {
            try {
              processor.close();
            } catch (final GenericDataSourceException e) {
              log.warn("Could not close the SQLProcessor", e);
            }
          }
        } else {
          // add to this batch
          idClause.append(", ");
          batchIndex++;
        }
      }
    } catch (final GenericEntityException e) {
      throw new DataAccessException(e);
    } catch (final SQLException e) {
      throw new DataAccessException(e);
    }

    return result;
  }