Набор генераторов MyBatisDistinct(true)

Я пытаюсь использовать setDistinct(true), как это описано в руководстве: http://mybatis.github.io/generator/generatedobjects/exampleClassUsage.html

Я написал таким образом:

testExample ae = new testExample();    
testExample.Criteria criteriatest = ae.createCriteria(); 
ae.setDistinct(true); 
criteriatest.andIDENTLAVEqualTo(Long.parseLong(cert.getCODINDIVID())); 
ae.or(criteriatest); 
List<test> listtest = testMapper.selectByExample(ae);

но setDistinct(true) не влияет на результаты.

Где я должен добавить строку setDistinct?


person DarkCoffee    schedule 04.07.2014    source источник


Ответы (1)


Похоже, что указанная вами ссылка относится к очень старой версии 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
comment
Я понимаю. Я использую mybatis-3.2.7, mybatis-spring-1.2.2 и mybatis-generator-1.3.2. Спасибо за ответ. - person DarkCoffee; 08.07.2014
comment
Я отлаживал код и обнаружил, что есть проверка setDistinct. - person DarkCoffee; 11.07.2014
comment
Добавлена ​​дополнительная информация для ответа. - person khampson; 12.07.2014