2015-02-03 2 views
2

Я работаю с очень плохо спроектированной базой данных, и перед тем, как писать свои запросы, мне нужно переформатировать таблицы.Переформатирование таблицы

Вот мои общие проблемы:

  • метки времени были разбиты более двух столбцов (по одному на сегодняшний день, другой на время).
  • некоторые столбцы строки также разделены на несколько столбцов.
  • большинство строк имеет фиксированную длину & пустые прокладки, поэтому мне нужно обрезать их.

В первую очередь я думаю об адаптации выхода генератора Jooq. Но, глядя на метод createField(...), он добавляет к fields0(), который является приватным для пакета. Что делает SELECT *, запрашивая все (и только) «сырые» поля, а не переформатированные.

Что это лучший способ объявить статически (т.е. класс/член) или динамически (т.е. код) такой модели?

+0

В идеале вы будете писать представление непосредственно в базе данных. Это вариант? –

+0

Конечно, это должно быть. Но, к сожалению, административные операции довольно сложны в моей среде. Более того, определение запроса очень изменчиво и со временем изменится. – LoganMzz

+1

Я знаю это чувство. Просто проверяю :) –

ответ

1

Наконец-то я получил результат, используя следующие классы (я проигнорировал обработку схемы, привязка & преобразования для упрощения).

Однако он полагается на инъекцию пользовательского класса внутри пакетов jOOQ. & повторное использование внутреннего кода. Это может привести к безопасности (если JARs/пакеты запечатаны) и проблемы с ремонтопригодностью. Это то, почему я не считаю его действительным, но возможный ответ на вопрос

jOOQ взломать:

package org.jooq.impl 
public abstract class Projection<R extends Record> extends TableImpl<R> { 

    public static final <R extends Record, T> TableField<R, T> newField(String name, DataType<T> type, Table<R> table) { 
    return newField(name, type, table, null, null, null); 
    } 
    public static final <R extends Record, T, X, U> TableField<R, U> newField(String name, DataType<T> type, Table<R> table, String comment, Converter<X, U> converter, Binding<T, X> binding) { 
    final Binding<T, U> actualBinding = DefaultBinding.newBinding(converter, type, binding); 
    @SuppressWarnings("unchecked") 
    final DataType<U> actualType = 
     converter == null && binding == null 
     ? (DataType<U>) type 
     : type.asConvertedDataType(actualBinding); 

    final TableFieldImpl<R, U> tableField = new TableFieldImpl<R, U>(name, actualType, table, comment, actualBinding); 

    return tableField; 
    } 

    protected Projection(String name) { 
    this(name, null); 
    } 
    protected Projection(String name, Table<R> aliased) { 
    super(name, null, aliased); 
    } 

    protected <T> TableField<R,T> field(String name, DataType<T> type) { 
    return newField(name, type, this); 
    } 
    protected <T,F extends Field<T>> F add(F field) { 
    fields0().add(field); 
    return field; 
    } 
    protected Fields<R> getFields() { 
    return fields0(); 
    } 
} 

Моя абстракция для общих проблем:

package com.company.model.jooq; 
public abstract class MyProjection<R extends Record> extends Projection<R> { 
    /** 
    * Unique version identifier for serialization. 
    */ 
    private static final long serialVersionUID = 1L; 

    protected Field<String> trimmed(String name) { 
    return DSL.trim(newField(name, SQLDataType.VARCHAR, this)).as(name); 
    } 
    protected Field<String> joined(String name, String... names) { 
    @SuppressWarnings("unchecked") 
    Field<String>[] fields = new Field[names.length]; 
    for (int i = 0; i < names.length; i++) { 
     fields[i] = newField(names[i], SQLDataType.VARCHAR, this); 
    } 
    return DSL.trim(DSL.concat(fields)).as(name); 
    } 
    protected Field<Timestamp> timestamp(String suffix) { 
    return DSL.function("timestamp", SQLDataType.TIMESTAMP, 
     newField("DT_" + suffix, SQLDataType.DATE, this), 
     newField("TI_" + suffix, SQLDataType.TIME, this) 
    ).as("TS_" + suffix); 
    } 

    protected MyProjection(String name) { 
    super(name); 
    } 
    protected MyProjection(String name, Table<R> aliased) { 
    super(name, aliased); 
    } 
} 

модели таблицы, например:

package com.company.model.jooq; 
public class MyProjectedTable extends MyProjection<Record> { 
    public final TableField<Record, Integer> ID  = add(field("ID", SQLDataType.INTEGER)); 
    public final Field<Timestamp>   TS_CREATE = add(timestamp("CREATE")); 
    public final Field<Timestamp>   TS_UPDATE = add(timestamp("UPDATE")); 
    public final TableField<Record, String> NAME  = add(field("NAME", SQLDataType.VARCHAR)); 
    public final Field<String>    LABEL  = add(trimmed("LABEL")); 
    public final Field<String>    COMMENT = add(joined("COMMENT", "COMMENT1", "COMMENT2", "COMMENT3")); 
} 
+1

Интересно. Вы по существу внедрили аннотацию '@ Formula' Hibernate, более или менее ... –

+0

Да, я знаю, что она разрывает jQQ-идиому, поскольку это не SQL.Но я искал библиотеку, которая находится где-то между jOOQ и ORM для: - Определение запроса - Генерация SQL (с очень хорошим контролем над ней) - Летий выборка (итерация, поскольку мне нужно просматривать записи 500 тыс.) - Модель нестатического вывода (т.е. объект) Я уверен, что мои потребности ближе к jOOQ, чем ORM. Итак, я начал играть с jOOQ. Я также должен был написать простой запрос (используя полный DSL API capabilitiy), но построение запроса должно было быть довольно нечистым из-за количества столбцов (> 100) и таблиц/suqueries (> 8). – LoganMzz

+0

На самом деле, он не нарушает «jOOQ idiom». jOOQ имеет ['CustomTable'] (http://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-queryparts/) и другие типы для подобных случаев использования. Только сейчас эти вещи довольно низкоуровневые. У нас есть [запросы функций для просмотров, написанных в jOOQ »] (https://github.com/jOOQ/jOOQ/issues/1969). Я напишу ответ об этом позже. –

1

В JPA, то, что вы пытаетесь сделать, смоделировано с использованием @Embedded аннотация. Или в Hibernate - немного более изощренно, аннотация @Formula. jOOQ имеет аналогичные характеристики на дорожной карте:

As jOOQ 3.5, вам придется реализовать эту поддержку самостоятельно. approach that you've chosen yourself выглядит вполне (повторно) полезным.

Смежные вопросы