📄 platformimplbase.java
字号:
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 + -