背景
将列数据类型映射到其对应的 Java 类。
问题
查询从数据库返回元信息:
SELECT
rb.object_schema,
rb.object_name,
rb.column_name
FROM
dictionary.resource_bundle rb
例如,此查询返回(自引用):
dictionary, resource_bundle, column_name
其中“dictionary”是架构名称,“resource_bundle”是 object_name,“column_name”是 column_name。
做这样的事情会很棒:
SELECT
rb.object_schema,
rb.object_name,
rb.column_name,
rb.column_type
FROM
dictionary.resource_bundle rb
并让这个查询返回:
dictionary, resource_bundle, column_name, varchar
然后用JDBC发现varchar
是mapped到 java.lang.String
。
问题
- 在 PostgreSQL 中,给定架构名称、对象名称(保证是表或 View )和列名称,如何确定用于存储数据的类型?
- 以与数据库无关的方式(利用 JDBC),您如何确定数据库用于给定数据类型的映射?
最佳答案
解决方案
答案比使用getMetaData
方法更复杂,因为getMetaData
方法返回的整数类型与完整类名之间没有直接映射。此解决方案需要两段代码:
- 实现一种获取
java.sql.Types
常量整数值的方法。 - 创建一个方法将该值转换为类名。
Java 类型方法
以下方法检索元信息:
public String getJavaType( String schema, String object, String column )
throws Exception {
String fullName = schema + '.' + object + '.' + column;
DatabaseMetaData metaData = getConnection().getMetaData();
ResultSet columnMeta = metaData.getColumns( null, schema, object, column );
String javaType = null;
if( columnMeta.first() ) {
int dataType = columnMeta.getInt( "DATA_TYPE" );
javaType = SQLTypeMap.convert( dataType );
}
else {
throw new Exception( "Unknown database column " + fullName + '.' );
}
return javaType;
}
静态转换方法
常量整数值必须转换为类名。这可以通过以下方式完成:
import java.sql.Types;
/**
* Converts database types to Java class types.
*/
public class SQLTypeMap {
/**
* Translates a data type from an integer (java.sql.Types value) to a string
* that represents the corresponding class.
*
* @param type
* The java.sql.Types value to convert to its corresponding class.
* @return The class that corresponds to the given java.sql.Types
* value, or Object.class if the type has no known mapping.
*/
public static Class<?> toClass(int type) {
Class<?> result = Object.class;
switch (type) {
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
result = String.class;
break;
case Types.NUMERIC:
case Types.DECIMAL:
result = java.math.BigDecimal.class;
break;
case Types.BIT:
result = Boolean.class;
break;
case Types.TINYINT:
result = Byte.class;
break;
case Types.SMALLINT:
result = Short.class;
break;
case Types.INTEGER:
result = Integer.class;
break;
case Types.BIGINT:
result = Long.class;
break;
case Types.REAL:
case Types.FLOAT:
result = Float.class;
break;
case Types.DOUBLE:
result = Double.class;
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
result = Byte[].class;
break;
case Types.DATE:
result = java.sql.Date.class;
break;
case Types.TIME:
result = java.sql.Time.class;
break;
case Types.TIMESTAMP:
result = java.sql.Timestamp.class;
break;
}
return result;
}
}
请注意,不同的数据库在映射上可能有不同的变化。
关于java - 将数据库类型映射到具体的 Java 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5251140/