【问题标题】:Map database type to concrete Java class将数据库类型映射到具体的 Java 类
【发布时间】:2011-03-09 19:31:34
【问题描述】:

背景

将列数据类型映射到其对应的 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 中,如果给定架构名称、对象名称(保证为表或视图)和列名称,您如何确定用于存储数据的类型?
  2. 以与数据库无关的方式(利用 JDBC),您如何确定数据库用于给定数据类型的映射?

【问题讨论】:

    标签: java sql postgresql jdbc metadata


    【解决方案1】:

    解决方案

    答案比使用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;
        }
    }
    

    请注意,不同的数据库在映射上可能有不同的变化。

    【讨论】:

      【解决方案2】:

      JDBC 提供了自省数据库元信息的方法。

      从 JDBC 连接调用 getMetaDatagetColumns 从那里向下钻取以获取架构、表和列的信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-08
        • 1970-01-01
        • 1970-01-01
        • 2018-11-16
        • 2020-03-07
        • 2014-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多