Сопоставить тип базы данных с конкретным классом Java - PullRequest
4 голосов
/ 09 марта 2011

Фон

Сопоставить тип данных столбца с соответствующим ему классом Java.

Проблема

Запрос возвращает метаинформацию из базы данных:

SELECT
  rb.object_schema,
  rb.object_name,
  rb.column_name
FROM
  dictionary.resource_bundle rb

Например, этот запрос возвращает (самоссылочный):

dictionary, resource_bundle, column_name

Где 'dictionary' - это имя схемы, 'resource_bundle' - это имя_объекта, а '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 сопоставлен с на java.lang.String.

Вопросы

  1. Как в PostgreSQL определить, какой тип используется для хранения данных, учитывая имя схемы, имя объекта (гарантированно будет таблицей или представлением) и имя столбца?
  2. Каким образом вы определяете отображение, которое база данных использует для данного типа данных, нейтральным по отношению к базе данных (используя JDBC)?

Ответы [ 2 ]

15 голосов
/ 10 марта 2011

Решение

Ответ более сложен, чем использование метода 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;
    }
}

Обратите внимание, что разные базы данных могут иметь разные вариации в отображении.

3 голосов
/ 09 марта 2011

JDBC предоставляет средства для анализа метаинформации базы данных.

Из JDBC-соединения вызовите getMetaData и getColumns , чтобы получить информацию для схем, таблиц и столбцов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...