jOOQ выберите в POJO с сопоставлениями, указанными только для некоторых полей

Я использую jOOQ с простым SQL (не сгенерированный код). Я пытаюсь выбрать непосредственно в POJO, в котором есть поля типа enum.

MyType pojo = context.select().from(table("Table"))
            .where(field("ID").equal("1")).fetchOne()
            .into(MyType.class);

Мне кажется, что я могу указать только высокоуровневый картограф для всего моего POJO, например:

MyType pojo = context.select().from(table("Table"))
            .where(field("ID").equal("1")).fetchOne()
            .map(new RecordMapper<Record, MyType>() {
                @Override
                public MyType map(Record record) {
                    ...
                }
            });

Я не могу найти способ предоставить сопоставления или преобразователи только для некоторых полей. В частности, я хотел бы сказать jooq что-то вроде «конвертировать все поля в обычном режиме, кроме тех случаев, когда поле в моем POJO имеет тип MyEnum, и в этом случае используйте это отображение (или преобразователь)».

Как я могу указать сопоставители для одних полей, а не для других?

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


person Robert Mikes    schedule 11.01.2017    source источник


Ответы (1)


Есть разные способы решения этой проблемы:

1. Используйте генератор кода

Очевидно. Я знаю, что вы им не пользуетесь, но, возможно, кто-то, кто найдет этот вопрос, будет. В этом случае генератор кода либо:

  1. Автоматически генерировать типы перечислений (если вы используете перечисления MySQL или PostgreSQL)
  2. Разрешить вам использовать <forcedTypes/>, где вы можете реализовать свой собственный конвертеры и / или привязки

2. Используйте явный преобразователь / привязку также с простым SQL.

Даже если вы не используете генератор кода, вы можете воспользоваться настраиваемыми преобразователями / привязками, указав свой собственный _ 2_:

// Assuming that the enum type enumerates varchar values:
SQLDataType<MyEnum> myEnumType = 
    SQLDataType.VARCHAR.asConvertedDataType(new MyEnumConverter());

Теперь вы можете использовать этот тип в простых выражениях SQL Field, используя _ 5_

context.select(field("Column", myEnumType), ...)
       .from(table("Table"))

В этом случае больше не будет необходимости в явном преобразовании в вашем преобразователе записей, поскольку jOOQ Record уже будет содержать желаемый тип данных.

3. Используйте собственный RecordMapperProvider

Если вы используете любой из into(Class), по умолчанию методы DefaultRecordMapper < / a> используется. Он знает, как преобразовывать строки в перечисления, вызывая EnumClass.valueOf(stringValue). Если это не желаемое поведение (как следует из вашего вопроса), вы все равно можете переопределить поведение по умолчанию, указав свой собственный _ 12_.

Это также «высокоуровневый картограф», как вы его назвали, но вы можете зарегистрировать его глобально и повторно использовать в любое время, когда захотите отобразить в MyType.class.

(4. с помощью реестра конвертера)

Будущая версия jOOQ (пока не jOOQ 3.9) может поддерживать реестр преобразователя, который позволяет реализовать преобразования по умолчанию для любой пары типов <T, U>. Это проблема # 5713.

person Lukas Eder    schedule 12.01.2017
comment
Спасибо! Решение 3, а именно вызов значения по умолчанию EnumClass.valueOf(stringValue), кажется лучшим подходом. Я изменю свой код, чтобы разрешить работу valueOf (). - person Robert Mikes; 13.01.2017