Как работает замена параметра mybatis в @SelectProvider - PullRequest
4 голосов
/ 18 января 2012

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

Java DAO

@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();
    }
}

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

Ответы [ 2 ]

5 голосов
/ 11 апреля 2012

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

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

0 голосов
/ 13 июля 2018

Вы могли бы переписать этот кусок кода следующим образом, что, возможно, немного яснее? Фактическое значение 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} ");
 }
 // ...
...