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; }
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; }
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; }