⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 platformimplbase.java

📁 OBPM是一个开源
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
					statement.setObject(paramIdx, arg);
				}
			}
			resultSet = statement.executeQuery();
			answer = createResultSetIterator(model, resultSet, queryHints);
			return answer;
		} catch (SQLException ex) {
			throw new DatabaseOperationException(
					"Error while performing a query", ex);
		} finally {
			// if any exceptions are thrown, close things down
			// otherwise we're leaving it open for the iterator
			if (answer == null) {
				closeStatement(statement);
				returnConnection(connection);
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql)
			throws DatabaseOperationException {
		return fetch(model, sql, (Table[]) null, 0, -1);
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql, Table[] queryHints)
			throws DatabaseOperationException {
		return fetch(model, sql, queryHints, 0, -1);
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql, int start, int end)
			throws DatabaseOperationException {
		return fetch(model, sql, (Table[]) null, start, end);
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql, Table[] queryHints,
			int start, int end) throws DatabaseOperationException {
		Connection connection = borrowConnection();
		Statement statement = null;
		ResultSet resultSet = null;
		List result = new ArrayList();

		try {
			statement = connection.createStatement();
			resultSet = statement.executeQuery(sql);
			
			int rowIdx = 0;

			for (Iterator it = createResultSetIterator(model, resultSet,
					queryHints); ((end < 0) || (rowIdx <= end)) && it.hasNext(); rowIdx++) {
				if (rowIdx >= start) {
					result.add(it.next());
				}
				else {
					it.next();
				}
			}
		} catch (SQLException ex) {
			throw new DatabaseOperationException(
					"Error while fetching data from the database", ex);
		} finally {
			// the iterator should return the connection automatically
			// so this is usually not necessary (but just in case)
			closeStatement(statement);
			returnConnection(connection);
		}
		return result;
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql, Collection parameters)
			throws DatabaseOperationException {
		return fetch(model, sql, parameters, null, 0, -1);
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql, Collection parameters,
			int start, int end) throws DatabaseOperationException {
		return fetch(model, sql, parameters, null, start, end);
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql, Collection parameters,
			Table[] queryHints) throws DatabaseOperationException {
		return fetch(model, sql, parameters, queryHints, 0, -1);
	}

	/**
	 * {@inheritDoc}
	 */
	public List fetch(Database model, String sql, Collection parameters,
			Table[] queryHints, int start, int end)
			throws DatabaseOperationException {
		Connection connection = borrowConnection();
		PreparedStatement statement = null;
		ResultSet resultSet = null;
		List result = new ArrayList();

		try {
			statement = connection.prepareStatement(sql);

			int paramIdx = 1;

			for (Iterator iter = parameters.iterator(); iter.hasNext(); paramIdx++) {
				Object arg = iter.next();

				if (arg instanceof BigDecimal) {
					// to avoid scale problems because setObject assumes a scale
					// of 0
					statement.setBigDecimal(paramIdx, (BigDecimal) arg);
				} else {
					statement.setObject(paramIdx, arg);
				}
			}
			resultSet = statement.executeQuery();

			int rowIdx = 0;

			for (Iterator it = createResultSetIterator(model, resultSet,
					queryHints); ((end < 0) || (rowIdx <= end)) && it.hasNext(); rowIdx++) {
				if (rowIdx >= start) {
					result.add(it.next());
				} else {
					it.next();
				}
			}
		} catch (SQLException ex) {
			// any other exception comes from the iterator which closes the
			// resources automatically
			closeStatement(statement);
			returnConnection(connection);
			throw new DatabaseOperationException(
					"Error while fetching data from the database", ex);
		}
		return result;
	}

	/**
	 * Creates the SQL for inserting an object of the given type. If a concrete
	 * bean is given, then a concrete insert statement is created, otherwise an
	 * insert statement usable in a prepared statement is build.
	 * 
	 * @param model
	 *            The database model
	 * @param dynaClass
	 *            The type
	 * @param properties
	 *            The properties to write
	 * @param bean
	 *            Optionally the concrete bean to insert
	 * @return The SQL required to insert an application of the class
	 */
	protected String createInsertSql(Database model, SqlDynaClass dynaClass,
			SqlDynaProperty[] properties, DynaBean bean) {
		Table table = model.findTable(dynaClass.getTableName());
		HashMap columnValues = toColumnValues(properties, bean);

		return _builder.getInsertSql(table, columnValues, bean == null);
	}

	/**
	 * Creates the SQL for querying for the id generated by the last insert of
	 * an object of the given type.
	 * 
	 * @param model
	 *            The database model
	 * @param dynaClass
	 *            The type
	 * @return The SQL required for querying for the id, or <code>null</code>
	 *         if the database does not support this
	 */
	protected String createSelectLastInsertIdSql(Database model,
			SqlDynaClass dynaClass) {
		Table table = model.findTable(dynaClass.getTableName());

		return _builder.getSelectLastIdentityValues(table);
	}

	/**
	 * {@inheritDoc}
	 */
	public String getInsertSql(Database model, DynaBean dynaBean) {
		SqlDynaClass dynaClass = model.getDynaClassFor(dynaBean);
		SqlDynaProperty[] properties = dynaClass.getSqlDynaProperties();

		if (properties.length == 0) {
			_log.info("Cannot insert application. of type " + dynaClass
					+ " because it has no properties");
			return null;
		}

		return createInsertSql(model, dynaClass, properties, dynaBean);
	}

	/**
	 * Returns all properties where the column is not non-autoincrement and for
	 * which the bean either has a value or the column hasn't got a default
	 * value, for the given dyna class.
	 * 
	 * @param model
	 *            The database model
	 * @param dynaClass
	 *            The dyna class
	 * @param bean
	 *            The bean
	 * @return The properties
	 */
	private SqlDynaProperty[] getPropertiesForInsertion(Database model,
			SqlDynaClass dynaClass, final DynaBean bean) {
		SqlDynaProperty[] properties = dynaClass.getSqlDynaProperties();

		Collection result = CollectionUtils.select(Arrays.asList(properties),
				new Predicate() {
					public boolean evaluate(Object input) {
						SqlDynaProperty prop = (SqlDynaProperty) input;

						if (bean.get(prop.getName()) != null) {
							// we ignore properties for which a value is present
							// in the bean
							// only if they are identity and identity override
							// is off or
							// the platform does not allow the override of the
							// auto-increment
							// specification
							return !prop.getColumn().isAutoIncrement()
									|| (isIdentityOverrideOn() && getPlatformInfo()
											.isIdentityOverrideAllowed());
						} else {
							// we also return properties without a value in the
							// bean
							// if they ain't auto-increment and don't have a
							// default value
							// in this case, a NULL is inserted
							return !prop.getColumn().isAutoIncrement()
									&& (prop.getColumn().getDefaultValue() == null);
						}
					}
				});

		return (SqlDynaProperty[]) result.toArray(new SqlDynaProperty[result
				.size()]);
	}

	/**
	 * Returns all identity properties whose value were defined by the database
	 * and which now need to be read back from the DB.
	 * 
	 * @param model
	 *            The database model
	 * @param dynaClass
	 *            The dyna class
	 * @param bean
	 *            The bean
	 * @return The columns
	 */
	private Column[] getRelevantIdentityColumns(Database model,
			SqlDynaClass dynaClass, final DynaBean bean) {
		SqlDynaProperty[] properties = dynaClass.getSqlDynaProperties();

		Collection relevantProperties = CollectionUtils.select(Arrays
				.asList(properties), new Predicate() {
			public boolean evaluate(Object input) {
				SqlDynaProperty prop = (SqlDynaProperty) input;

				// we only want those identity columns that were really
				// specified by the DB
				// if the platform allows specification of values for identity
				// columns
				// in INSERT/UPDATE statements, then we need to filter the
				// corresponding
				// columns out
				return prop.getColumn().isAutoIncrement()
						&& (!isIdentityOverrideOn()
								|| !getPlatformInfo()
										.isIdentityOverrideAllowed() || (bean
								.get(prop.getName()) == null));
			}
		});

		Column[] columns = new Column[relevantProperties.size()];
		int idx = 0;

		for (Iterator propIt = relevantProperties.iterator(); propIt.hasNext(); idx++) {
			columns[idx] = ((SqlDynaProperty) propIt.next()).getColumn();
		}
		return columns;
	}

	/**
	 * {@inheritDoc}
	 */
	public void insert(Connection connection, Database model, DynaBean dynaBean)
			throws DatabaseOperationException {
		SqlDynaClass dynaClass = model.getDynaClassFor(dynaBean);
		SqlDynaProperty[] properties = getPropertiesForInsertion(model,
				dynaClass, dynaBean);
		Column[] autoIncrColumns = getRelevantIdentityColumns(model, dynaClass,
				dynaBean);

		if ((properties.length == 0) && (autoIncrColumns.length == 0)) {
			_log.warn("Cannot insert application. of type " + dynaClass
					+ " because it has no usable properties");
			return;
		}

		String insertSql = createInsertSql(model, dynaClass, properties, null);
		String queryIdentitySql = null;

		if (_log.isDebugEnabled()) {
			_log.debug("About to execute SQL: " + insertSql);
		}

		if (autoIncrColumns.length > 0) {
			if (!getPlatformInfo().isLastIdentityValueReadable()) {
				_log
						.warn("The database does not support querying for auto-generated column values");
			} else {
				queryIdentitySql = createSelectLastInsertIdSql(model, dynaClass);
			}
		}

		boolean autoCommitMode = false;
		PreparedStatement statement = null;

		try {
			if (!getPlatformInfo()
					.isAutoCommitModeForLastIdentityValueReading()) {
				autoCommitMode = connection.getAutoCommit();
				connection.setAutoCommit(false);
			}

			beforeInsert(connection, dynaClass.getTable());

			statement = connection.prepareStatement(insertSql);

			for (int idx = 0; idx < properties.length; idx++) {
				setObject(statement, idx + 1, dynaBean, properties[idx]);
			}
			int count = statement.executeUpdate();

			afterInsert(connection, dynaClass.getTable());

			if (count != 1) {
				_log.warn("Attempted to insert a single row " + dynaBean
						+ " in table " + dynaClass.getTableName()
						+ " but changed " + count + " row(s)");
			}
		} catch (SQLException ex) {
			throw new DatabaseOperationException(
					"Error while inserting into the database: "
							+ ex.getMessage(), ex);
		} finally {
			closeStatement(statement);
		}
		if (queryIdentitySql != null) {
			Statement queryStmt = null;
			ResultSet lastInsertedIds = null;

			try {
				if (getPlatformInfo()
						.isAutoCommitModeForLastIdentityValueReading()) {
					// we'll commit the statement(s) if no auto-commit is
					// enabled because
					// otherwise it is possible that the auto increment hasn't
					// happened yet
					// (the db didn't actually perform the insert yet so no
					// triggering of
					// sequences did occur)
					if (!connection.getAutoCommit()) {
						connection.commit();
					}
				}

				queryStmt = connection.createStatement();
				lastInsertedIds = queryStmt.executeQuery(queryIdentitySql);

				lastInsertedIds.next();

				for (int idx = 0; idx < autoIncrColumns.length; idx++) {
					// we're using the index rather than the name because we
					// cannot know how
					// the SQL statement looks like; rather we assume that we
					// get the values
					// back in the same order as the auto increment columns
					Object value = getObjectFromResultSet(lastInsertedIds,
							autoIncrColumns[idx], idx + 1);

					PropertyUtils.setProperty(dynaBean, autoIncrColumns[idx]
							.getName(), value);
				}
			} catch (NoSuchMethodException ex) {
				// Can't happen because we're using dyna beans
			} catch (IllegalAccessException ex) {
				// Can't happen because we're using dyna beans
			} catch (InvocationTargetException ex) {
				// Can't happen because we're using dyna beans
			} catch (SQLException ex) {
				throw new DatabaseOperationException(
						"Error while retrieving the identity column value(s) from the database",
						ex);
			} finally {
				if (lastInsertedIds != null) {
					try {
						lastInsertedIds.close();
					} catch (SQLException ex) {
						// we ignore this one
					}
				}
				closeStatement(statement);
			}
		}
		if (!getPlatformInfo().isAutoCommitModeForLastIdentityValueReading()) {
			try {
				// we need to do a manual commit now
				connection.commit();
				connection.setAutoCommit(autoCommitMode);
			} catch (SQLException ex) {
				throw new DatabaseOperationException(ex);
			}
		}
	}

⌨️ 快捷键说明

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