Похоже, что указанная вами ссылка относится к очень старой версии MyBatis. На этой странице указано следующее:
Версия: 1.3.3-СНИМОК
Последняя версия:
mybatis-3.3.0-СНИМОК
Поиск кода 3.x для setDistinct
ничего не возвращает: https://github.com/mybatis/mybatis-3/search?q=setDistinct
Я удивлен, что вы не получаете ошибку времени компиляции о том, что метод не найден. Вы используете версию 1.3.3 (или 1.x)?
Я бы рекомендовал делать DISTINCT
прямо в запросе. Поскольку MyBatis, как правило, является своего рода структурой сопоставления типа близкой к SQL-металлу, я думаю, что лучше добавить ее в сам запрос файла сопоставления. К тому же, таким образом, вы можете выбрать конкретно, что DISTINCT
использовать. Метод setDistinct
, по-видимому, не предоставляет никакого способа указать цель.
Я думаю, что для MyBatis 3 аналогичный стиль запроса будет таким:
http://mybatis.github.io/mybatis-3/statement-builders.html
Это похоже на jOOQ-стиль DSL. Он имеет метод SELECT_DISTINCT
. Лично мне легче кодировать/читать чистый SQL с некоторой разметкой XML, необходимой для динамического SQL в файле отображения, но это безусловно, жизнеспособный вариант в MyBatis 3.
Изменить:
Итак, я еще немного покопался, и причина, по которой я не смог найти код в репозитории MyBatis3 git, заключается в том, что setDistinct
находится в базе кода mybatis-generator.
Я думаю, что часть проблемы здесь может быть связана с тем, что является частью описания Mybatis-Generator на GitHub:
MBG стремится оказать существенное влияние на большой процент операций с базами данных, которые являются простыми CRUD (создание, извлечение, обновление, удаление).
Таким образом, он позволяет выполнять простые DISTINCT
, но с ограниченным контролем.
Код находится в методе addClassElements
класса ProviderSelectByExampleWithoutBLOBsMethodGenerator
. Поиск setDistinct
не будет отображаться в поиске Github, так как это автоматически сгенерированный сеттер.
Это соответствующий фрагмент кода:
boolean distinctCheck = true;
for (IntrospectedColumn introspectedColumn : getColumns()) {
if (distinctCheck) {
method.addBodyLine("if (example != null && example.isDistinct()) {"); //$NON-NLS-1$
method.addBodyLine(String.format("%sSELECT_DISTINCT(\"%s\");", //$NON-NLS-1$
builderPrefix,
escapeStringForJava(getSelectListPhrase(introspectedColumn))));
method.addBodyLine("} else {"); //$NON-NLS-1$
method.addBodyLine(String.format("%sSELECT(\"%s\");", //$NON-NLS-1$
builderPrefix,
escapeStringForJava(getSelectListPhrase(introspectedColumn))));
method.addBodyLine("}"); //$NON-NLS-1$
} else {
method.addBodyLine(String.format("%sSELECT(\"%s\");", //$NON-NLS-1$
builderPrefix,
escapeStringForJava(getSelectListPhrase(introspectedColumn))));
}
distinctCheck = false;
}
Итак, по сути, это выглядит так, как будто он обертывает метод SELECT_DISTINCT
, о котором я упоминал изначально, и пытается проанализировать столбцы и применить DISTINCT
ко всем тем, которые он возвращает.
Копнув немного глубже, он в конечном итоге вызывает этот код для получения столбцов:
/**
* Returns all columns in the table (for use by the select by primary key
* and select by example with BLOBs methods)
*
* @return a List of ColumnDefinition objects for all columns in the table
*/
public List<IntrospectedColumn> getAllColumns() {
List<IntrospectedColumn> answer = new ArrayList<IntrospectedColumn>();
answer.addAll(primaryKeyColumns);
answer.addAll(baseColumns);
answer.addAll(blobColumns);
return answer;
}
Таким образом, это, безусловно, принцип «все или ничего» DISTINCT
(тогда как сам Postgres допускает DISTINCT
только для определенных столбцов).
Попробуйте переместить setDistinct
в самую последнюю строку перед вызовом объекта ae
. Возможно, последующие вызовы влияют на набор столбцов (хотя из кода это не похоже на то, что должно быть — в основном, когда столбцы установлены, setDistinct
должен их использовать).
Другая вещь, которая была бы интересна, это посмотреть, какой SQL он на самом деле генерирует с setDistinct
и без него.
Проверьте эту ссылку для получения более подробной информации об отладке/регистрации:
http://mybatis.github.io/generator/reference/logging.html
Я бы порекомендовал, возможно, попробовать определения файла сопоставления на основе XML, которые чередуют теги SQL с тегами XML для динамичности. ИМО, гораздо проще следовать приведенному выше фрагменту кода Mybatis Generator. Я полагаю, что это один из основных компромиссов с генератором - его легче создать изначально, но его сложнее читать/обслуживать позже.
Для супердинамических запросов я мог бы увидеть еще несколько преимуществ, но тогда это противоречит их собственному описанию, что это для простых операций CRUD.
person
khampson
schedule
08.07.2014