java - 将数据库类型映射到具体的 Java 类

标签 java sql postgresql jdbc metadata

背景

将列数据类型映射到其对应的 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发现varcharmappedjava.lang.String

问题

  1. 在 PostgreSQL 中,给定架构名称、对象名称(保证是表或 View )和列名称,如何确定用于存储数据的类型?
  2. 以与数据库无关的方式(利用 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/

相关文章:

sql - 对聚合函数的输入进行排序

sql比较今天的日期时间

sql - POSTGRESQL 数组不包含值

postgresql - haskell postgresql-简单不兼容类型_int8和Int64(和整数)

mysql - 从 MySQL 到 Postgres : Last Quarter Hour

Java过滤器-根据请求有条件地更改响应主体

c# - 如何在c#中的sql表中的单词后插入换行符

java - 调用wait()时发生IllegalMonitorStateException

java - 为什么 Joda Time 序列化表单如此之大,该怎么办?

java - GWT 代码卡在reactToMessages 上