Как работает замена параметра mybatis в @SelectProvider

Я унаследовал некоторый код, который я пытаюсь понять, и любой поиск, который я делаю, чтобы найти что-то на @SelectProvider, ничего не дает.

DAO для Java

@SelectProvider(type = CategoryDaoSelectProvider.class, method = "findByParentIdAndName")
Category findByParentIdAndName(@Param("parentId") Long parentId, @Param("name") String name);

Выберите поставщика

public class CategoryDaoSelectProvider {
    public static String findByParentIdAndName(Map<String, Object> params) {
        Long parentId = (Long)params.get("parentId");  // WHY IS THIS HERE???

        StringBuffer buffer = new StringBuffer();
        buffer.append("SELECT COUNT(id) FROM Category ");

        if (parentId == null) {
            buffer.append("WHERE parentId IS NULL ");
        } else {
            buffer.append("WHERE parentId = #{parentId} ");
        }

        buffer.append("AND LOWER(name) = LOWER(#{name}) ");

        return buffer.toString();
    }
}

Какой цели служит параметр parentId в этом коде? Насколько я могу судить, на самом деле он никогда ничего не делает, если только каким-то волшебным образом #{parentId} не заменяется значением. Этот параметр просто не используется в этой ситуации? Где mybatis на самом деле делает инъекции в запрос?


person kasdega    schedule 18.01.2012    source источник


Ответы (2)


SelectProviders получают параметры двумя способами: как элементы в аргументе params Map и как #{parentId} (в вашем примере). Код показывает, что parentId проверяется до того, как он будет использован в операторе select. Переменная parentId необходима, потому что вы не можете запросить #{parentId}.

Кстати, это не лучшая реализация SelectProviders, вы должны использовать SELECT(), WHERE() и SQL() в конце, чтобы вернуть скомпилированный оператор. Я думаю, ваш пример тоже работает.

person slippytoad    schedule 10.04.2012
comment
Я понимаю, о чем вы говорите... Просто хочу указать всем, кто читает это, что строка, о которой я спрашивал, ничего не делает. Мы получаем значение для parentId, но ничего с ним не делаем. В этом коде эта строка кода не имеет смысла. - person kasdega; 01.07.2016

Вы могли бы переписать этот фрагмент кода следующим образом, что, возможно, будет немного понятнее? Фактическое значение parentId действительно не обязательно, но требуется информация о том, присутствует ли параметр.

 // ...
 boolean hasIdParam = params.containsKey("parentId");

 StringBuffer buffer = new StringBuffer();
 buffer.append("SELECT COUNT(id) FROM Category ");

 if (!hasIdParam) {
    buffer.append("WHERE parentId IS NULL ");
 } else {
    buffer.append("WHERE parentId = #{parentId} ");
 }
 // ...
person sgdesmet    schedule 13.07.2018