Я работаю с базой данных, которая очень плохо обрабатывает нулевые значения. Вместо использования строк, допускающих значение NULL, я хочу использовать фиксированное, очень редкое значение (по сути, UUID) в качестве заполнителя для значения NULL.
Моя цель состоит в том, чтобы использовать Необязательно вместо Строки для полей в Java, и всякий раз, когда я связываю Необязательный.empty() с инструкцией INSERT INTO, я хочу, чтобы jOOQ автоматически преобразовывал это в мой UUID, который я использую в качестве флага для пустого необязательного параметра. . Когда необязательный параметр имеет значение, я хочу, чтобы jOOQ использовал предоставленное значение как обычно.
Я попробовал настроить конвертер, но, похоже, он работает только во время операций SELECT, а не на этапе вставки. Я подозреваю, что могу что-то упустить.
Вот что у меня есть на данный момент:
package com.res.jooq.neo4j;
public class Neo4jOptionalUtils {
public static final String EMPTY_STRING = "empty-string-optional-ac4ea8cd-9128-4ee3-bb2c-48a1c239ffd2";
private Neo4jOptionalUtils() {
// private constructor to hide the implicit public one
}
public static String optional(String value) {
return value == null ? EMPTY_STRING : value;
}
public static String fromOptional(String optional) {
return EMPTY_STRING.equals(optional) ? null : optional;
}
}
Я использую этот служебный класс для преобразования нулевых значений в мой фиксированный UUID и наоборот.
Как я могу настроить jOOQ для автоматического применения этого преобразования во время операций INSERT?
Есть ли способ гарантировать, что операции SELECT и INSERT учитывают эту логику преобразования без преобразования каждого значения вручную?
Обновлено: благодаря ответу Лукаса мне удалось это сделать, вот суть https://gist.github.com/bonelli/9f3c24a30218be71c26a335c0ab17cc1
Спасибо, Эндрю, моей первой попыткой было попытаться создать преобразователь из String в String, чтобы преобразовать нулевые значения в мой токен с нулевым значением и наоборот. Хотя он работал с SELECT при потоковой передаче результатов, он не делал ничего для привязки параметров INSERT INTO, и я не знаю, почему
«он не сделал ничего для привязки параметров INSERT INTO, и я не знаю, почему». Возможно, лучше задать вопрос об этом, но убедитесь, что проблема, с которой вы столкнулись, воспроизводима.
если бы я был уверен, что это проблема, я бы разместил ее на GitHub JOOQ. В данном случае я прошу помощи, потому что я не эксперт в настройке JOOQ, в чем тут дело? Разве это не сайт, где можно попросить помощи по сложным вопросам программирования?
В любом случае, поскольку кажется, что вы очень хорошо осведомлены о JOOQ @LukasEder, не могли бы вы указать мне правильную страницу документа? Здесь показаны только примеры с SELECT: jooq.org/doc/3.19/manual/sql-execution/fetching/… И это вообще не показывает ни одного примера запроса: jooq.org/doc/3.19/manual /sql-building/queryparts/… хотя я считаю, что мне нужен второй
Федерико, я не ставил тебе минус. Я просто хотел указать вам правильное направление. Ваш вопрос не показывает мне, почему в вашем случае что-то не работает. Конвертеры работают «из коробки» для всех операций. Но в вашем случае этого не происходит. Я не понимаю, почему они этого не делают в вашем случае. Итак, я намекнул на обновление вашего вопроса (или задать новый), показав, что именно вы делаете, потому что в противном случае я действительно не смогу вам помочь. Имеет ли это смысл? Я не уверен, нужна ли вам «правильная страница документа». Нет ничего особенного в использовании преобразованных типов данных в операторах INSERT
.
Итак, этот вопрос, похоже, предполагает, что есть разница между использованием ссылок Field<U>
в INSERT
или SELECT
(где U
— преобразованный пользовательский тип):
Я попробовал настроить конвертер, но, похоже, он работает только во время операций SELECT, а не на этапе вставки. Я подозреваю, что могу что-то упустить.
Как я могу настроить jOOQ для автоматического применения этого преобразования во время операций INSERT?
Ответ здесь такой: нет, ничего особенного делать не нужно. Преобразованные поля работают везде, «из коробки». Вероятно, вы просто не использовали преобразованное поле. Предполагая, что вы используете генератор кода jOOQ, просто используйте это поле везде:
List<MyType> list =
ctx.select(T.CONVERTED)
.from(T)
.fetch(T.CONVERTED);
ctx.insertInto(T)
.columns(T.CONVERTED)
.values(new MyType()) // Works out of the box
.execute();
Я буду рад ответить на дополнительный вопрос о том, что конкретно вы сделали, чтобы помочь вам найти, где вы ошиблись.
После того, как вы заверили меня, что конвертеры действительно являются подходящим инструментом для этой работы, я написал полный класс песочницы со своими точными настройками и после небольшой настройки понял, в чем у меня возникли проблемы. Вот суть кода, который мне удалось собрать: gist.github.com/bonelli/9f3c24a30218be71c26a335c0ab17cc1 Наконец, моей проблемой был частный случай экспериментального драйвера JDBC Neo4j, который не переводит некоторые операторы SQL в правильные запросы Cypher. . Спасибо за помощь, Лукас.
Использование необязательного поля в качестве поля спорно , поэтому, возможно, было бы лучше/чище реализовать свой собственный тип. Это должно помочь.