📄 platformimplbase.java
字号:
try {
return readModelFromDatabase(connection, name);
} finally {
returnConnection(connection);
}
}
/**
* {@inheritDoc}
*/
public Database readModelFromDatabase(Connection connection, String name)
throws DatabaseOperationException {
try {
Database model = getModelReader().getDatabase(connection, name);
postprocessModelFromDatabase(model);
return model;
} catch (SQLException ex) {
throw new DatabaseOperationException(ex);
}
}
/**
* {@inheritDoc}
*/
public Database readModelFromDatabase(String name, String catalog,
String schema, String[] tableTypes)
throws DatabaseOperationException {
Connection connection = borrowConnection();
try {
return readModelFromDatabase(connection, name, catalog, schema,
tableTypes);
} finally {
returnConnection(connection);
}
}
/**
* {@inheritDoc}
*/
public Database readModelFromDatabase(Connection connection, String name,
String catalog, String schema, String[] tableTypes)
throws DatabaseOperationException {
try {
JdbcModelReader reader = getModelReader();
Database model = reader.getDatabase(connection, name, catalog,
schema, tableTypes);
postprocessModelFromDatabase(model);
if ((model.getName() == null) || (model.getName().length() == 0)) {
model.setName(MODEL_DEFAULT_NAME);
}
return model;
} catch (SQLException ex) {
throw new DatabaseOperationException(ex);
}
}
/**
* Allows the platform to postprocess the model just read from the database.
*
* @param model
* The model
*/
protected void postprocessModelFromDatabase(Database model) {
// Default values for CHAR/VARCHAR/LONGVARCHAR columns have quotation
// marks
// around them which we'll remove now
for (int tableIdx = 0; tableIdx < model.getTableCount(); tableIdx++) {
Table table = model.getTable(tableIdx);
for (int columnIdx = 0; columnIdx < table.getColumnCount(); columnIdx++) {
Column column = table.getColumn(columnIdx);
if (TypeMap.isTextType(column.getTypeCode())
|| TypeMap.isDateTimeType(column.getTypeCode())) {
String defaultValue = column.getDefaultValue();
if ((defaultValue != null) && (defaultValue.length() >= 2)
&& defaultValue.startsWith("'")
&& defaultValue.endsWith("'")) {
defaultValue = defaultValue.substring(1, defaultValue
.length() - 1);
column.setDefaultValue(defaultValue);
}
}
}
}
}
/**
* Derives the column values for the given dyna properties from the dyna
* bean.
*
* @param properties
* The properties
* @param bean
* The bean
* @return The values indexed by the column names
*/
protected HashMap toColumnValues(SqlDynaProperty[] properties, DynaBean bean) {
HashMap result = new HashMap();
for (int idx = 0; idx < properties.length; idx++) {
result.put(properties[idx].getName(), bean == null ? null : bean
.get(properties[idx].getName()));
}
return result;
}
/**
* Sets a parameter of the prepared statement based on the type of the
* column of the property.
*
* @param statement
* The statement
* @param sqlIndex
* The index of the parameter to set in the statement
* @param dynaBean
* The bean of which to take the value
* @param property
* The property of the bean, which also defines the corresponding
* column
*/
protected void setObject(PreparedStatement statement, int sqlIndex,
DynaBean dynaBean, SqlDynaProperty property) throws SQLException {
int typeCode = property.getColumn().getTypeCode();
Object value = dynaBean.get(property.getName());
setStatementParameterValue(statement, sqlIndex, typeCode, value);
}
/**
* This is the core method to set the parameter of a prepared statement to a
* given value. The primary purpose of this method is to call the
* appropriate method on the statement, and to give database-specific
* implementations the ability to change this behavior.
*
* @param statement
* The statement
* @param sqlIndex
* The parameter index
* @param typeCode
* The JDBC type code
* @param value
* The value
* @throws SQLException
* If an error occurred while setting the parameter value
*/
protected void setStatementParameterValue(PreparedStatement statement,
int sqlIndex, int typeCode, Object value) throws SQLException {
if (value == null) {
statement.setNull(sqlIndex, typeCode);
} else if (value instanceof String) {
String str = (String) value;
if (str.length() > 2 * 1024) {
StringReader reader = new StringReader(str);
statement.setCharacterStream(sqlIndex, reader, str.length());
} else {
statement.setString(sqlIndex, (String) value);
}
} else if (value instanceof byte[]) {
statement.setBytes(sqlIndex, (byte[]) value);
} else if (value instanceof Boolean) {
statement.setBoolean(sqlIndex, ((Boolean) value).booleanValue());
} else if (value instanceof Byte) {
statement.setByte(sqlIndex, ((Byte) value).byteValue());
} else if (value instanceof Short) {
statement.setShort(sqlIndex, ((Short) value).shortValue());
} else if (value instanceof Integer) {
statement.setInt(sqlIndex, ((Integer) value).intValue());
} else if (value instanceof Long) {
statement.setLong(sqlIndex, ((Long) value).longValue());
} else if (value instanceof BigDecimal) {
// setObject assumes a scale of 0, so we rather use the typed setter
statement.setBigDecimal(sqlIndex, (BigDecimal) value);
} else if (value instanceof Float) {
statement.setFloat(sqlIndex, ((Float) value).floatValue());
} else if (value instanceof Double) {
statement.setDouble(sqlIndex, ((Double) value).doubleValue());
} else {
statement.setObject(sqlIndex, value, typeCode);
}
}
/**
* Helper method esp. for the {@link ModelBasedResultSetIterator} class that
* retrieves the value for a column from the given result set. If a table
* was specified, and it contains the column, then the jdbc type defined for
* the column is used for extracting the value, otherwise the object
* directly retrieved from the result set is returned.<br/> The method is
* defined here rather than in the {@link ModelBasedResultSetIterator} class
* so that concrete platforms can modify its behavior.
*
* @param resultSet
* The result set
* @param columnName
* The name of the column
* @param table
* The table
* @return The value
*/
protected Object getObjectFromResultSet(ResultSet resultSet,
String columnName, Table table) throws SQLException {
Column column = (table == null ? null : table.findColumn(columnName,
isDelimitedIdentifierModeOn()));
Object value = null;
if (column != null) {
int originalJdbcType = column.getTypeCode();
int targetJdbcType = getPlatformInfo().getTargetJdbcType(
originalJdbcType);
int jdbcType = originalJdbcType;
// in general we're trying to retrieve the value using the original
// type
// but sometimes we also need the target type:
if ((originalJdbcType == Types.BLOB)
&& (targetJdbcType != Types.BLOB)) {
// we should not use the Blob interface if the database doesn't
// map to this type
jdbcType = targetJdbcType;
}
if ((originalJdbcType == Types.CLOB)
&& (targetJdbcType != Types.CLOB)) {
// we should not use the Clob interface if the database doesn't
// map to this type
jdbcType = targetJdbcType;
}
value = extractColumnValue(resultSet, columnName, 0, jdbcType);
} else {
value = resultSet.getObject(columnName);
}
return resultSet.wasNull() ? null : value;
}
/**
* Helper method for retrieving the value for a column from the given result
* set using the type code of the column.
*
* @param resultSet
* The result set
* @param column
* The column
* @param idx
* The value's index in the result set (starting from 1)
* @return The value
*/
protected Object getObjectFromResultSet(ResultSet resultSet, Column column,
int idx) throws SQLException {
int originalJdbcType = column.getTypeCode();
int targetJdbcType = getPlatformInfo().getTargetJdbcType(
originalJdbcType);
int jdbcType = originalJdbcType;
Object value = null;
// in general we're trying to retrieve the value using the original type
// but sometimes we also need the target type:
if ((originalJdbcType == Types.BLOB) && (targetJdbcType != Types.BLOB)) {
// we should not use the Blob interface if the database doesn't map
// to this type
jdbcType = targetJdbcType;
}
if ((originalJdbcType == Types.CLOB) && (targetJdbcType != Types.CLOB)) {
// we should not use the Clob interface if the database doesn't map
// to this type
jdbcType = targetJdbcType;
}
value = extractColumnValue(resultSet, null, idx, jdbcType);
return resultSet.wasNull() ? null : value;
}
/**
* This is the core method to retrieve a value for a column from a result
* set. Its primary purpose is to call the appropriate method on the result
* set, and to provide an extension point where database-specific
* implementations can change this behavior.
*
* @param resultSet
* The result set to extract the value from
* @param columnName
* The name of the column; can be <code>null</code> in which
* case the <code>columnIdx</code> will be used instead
* @param columnIdx
* The index of the column's value in the result set; is only
* used if <code>columnName</code> is <code>null</code>
* @param jdbcType
* The jdbc type to extract
* @return The value
* @throws SQLException
* If an error occurred while accessing the result set
*/
protected Object extractColumnValue(ResultSet resultSet, String columnName,
int columnIdx, int jdbcType) throws SQLException {
boolean useIdx = (columnName == null);
Object value;
switch (jdbcType) {
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
value = useIdx ? resultSet.getString(columnIdx) : resultSet
.getString(columnName);
break;
case Types.NUMERIC:
case Types.DECIMAL:
value = useIdx ? resultSet.getBigDecimal(columnIdx) : resultSet
.getBigDecimal(columnName);
break;
case Types.BIT:
value = new Boolean(useIdx ? resultSet.getBoolean(columnIdx)
: resultSet.getBoolean(columnName));
break;
case Types.TINYINT:
case Types.SMALLINT:
case Types.INTEGER:
value = new Integer(useIdx ? resultSet.getInt(columnIdx)
: resultSet.getInt(columnName));
break;
case Types.BIGINT:
value = new Long(useIdx ? resultSet.getLong(columnIdx) : resultSet
.getLong(columnName));
break;
case Types.REAL:
value = new Float(useIdx ? resultSet.getFloat(columnIdx)
: resultSet.getFloat(columnName));
break;
case Types.FLOAT:
case Types.DOUBLE:
value = new Double(useIdx ? resultSet.getDouble(columnIdx)
: resultSet.getDouble(columnName));
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
value = useIdx ? resultSet.getBytes(columnIdx) : resultSet
.getBytes(columnName);
break;
case Types.DATE:
value = useIdx ? resultSet.getDate(columnIdx) : resultSet
.getDate(columnName);
break;
case Types.TIME:
value = useIdx ? resultSet.getTime(columnIdx) : resultSet
.getTime(columnName);
break;
case Types.TIMESTAMP:
value = useIdx ? resultSet.getTimestamp(columnIdx) : resultSet
.getTimestamp(columnName);
break;
case Types.CLOB:
Clob clob = useIdx ? resultSet.getClob(columnIdx) : resultSet
.getClob(columnName);
if (clob == null) {
value = null;
} else {
long length = clob.length();
if (length > Integer.MAX_VALUE) {
value = clob;
} else if (length == 0) {
// the javadoc is not clear about whether Clob.getSubString
// can be used with a substring length of 0
// thus we do the safe thing and handle it ourselves
value = "";
} else {
value = clob.getSubString(1l, (int) length);
}
}
break;
case Types.BLOB:
Blob blob = useIdx ? resultSet.getBlob(columnIdx) : resultSet
.getBlob(columnName);
if (blob == null) {
value = null;
} else {
long length = blob.length();
if (length > Integer.MAX_VALUE) {
value = blob;
} else if (length == 0) {
// the javadoc is not clear about whether Blob.getBytes
// can be used with for 0 bytes to be copied
// thus we do the safe thing and handle it ourselves
value = new byte[0];
} else {
value = blob.getBytes(1l, (int) length);
}
}
break;
case Types.ARRAY:
value = useIdx ? resultSet.getArray(columnIdx) : resultSet
.getArray(columnName);
break;
case Types.REF:
value = useIdx ? resultSet.getRef(columnIdx) : resultSet
.getRef(columnName);
break;
default:
// special handling for Java 1.4/JDBC 3 types
if (Jdbc3Utils.supportsJava14JdbcTypes()
&& (jdbcType == Jdbc3Utils.determineBooleanTypeCode())) {
value = new Boolean(useIdx ? resultSet.getBoolean(columnIdx)
: resultSet.getBoolean(columnName));
} else {
value = useIdx ? resultSet.getObject(columnIdx) : resultSet
.getObject(columnName);
}
break;
}
return resultSet.wasNull() ? null : value;
}
/**
* Creates an iterator over the given result set.
*
* @param model
* The database model
* @param resultSet
* The result set to iterate over
* @param queryHints
* The tables that were queried in the query that produced the
* given result set (optional)
* @return The iterator
*/
protected ModelBasedResultSetIterator createResultSetIterator(
Database model, ResultSet resultSet, Table[] queryHints) {
return new ModelBasedResultSetIterator(this, model, resultSet,
queryHints, true);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -