MyBatis весной с Sql Builder и аннотацией - PullRequest
0 голосов
/ 13 декабря 2018

Я провожу некоторые тесты с MyBatis весной, и я решил протестировать два способа создания SQL-запросов с использованием аннотаций, но один из них не работает, и мне нужна помощь, чтобы понять проблему.

Работает:

@Select("<script> "
    + "SELECT * FROM user "
    + "<where>"
    + "<if test=\"username != null\"> OR username LIKE '%' #{username} '%' </if>"
    + "<if test=\"name != null\"> OR name LIKE '%' #{name} '%' </if>"
    + "<if test=\"email != null\"> OR email LIKE '%' #{email} '%' </if>"
    + "</where>"
    + " </script>")
public List<User> findByDynamicFilter(@Param("username") String username, 
        @Param("name") String name, @Param("email") String email);

Тот, который не работает:

Mapper

@SelectProvider(type = UserSqlBuilder.class, method = "buildFindByDynamicFilter")
public List<User> findByDynamicFilter(@Param("username") String username, 
        @Param("name") String name, @Param("email") String email);

Класс SqlBuilder

public class UserSqlBuilder {

    public static String buildFindByDynamicFilter(final String username, final String name, final String email) {
        return new SQL() {
            {
                SELECT("*");
                FROM("user");
                if (name != null) {
                    OR().WHERE("name like #{name} || '%'");
                }
                if (username != null) {
                    OR().WHERE("username like #{username}");
                }
                if (email != null) {
                    OR().WHERE("email like #{email} || '%'");
                }
            }
        }.toString();
    }

}

Ошибка:

2018-12-12 19: 47: 12.935 ОШИБКА 7454 --- [nio-8080-exec-1] oaccC [. [. [/]. [DispatcherServlet]: Servlet.service () длясервлет [dispatcherServlet] в контексте с путем [] вызвал исключение [Ошибка обработки запроса;вложенное исключение - org.mybatis.spring.MyBatisSystemException: вложенное исключение - org.apache.ibatis.builder.BuilderException: ошибка при вызове метода SqlProvider (br.com.andre.springmvcuser.mapper.sqlbuilder.UserSqlBuilder.buildFB).Причина: org.apache.ibatis.binding.BindingException: параметр 'arg0' не найден.Доступные параметры: [имя, param3, param1, адрес электронной почты, имя пользователя, param2]] с основной причиной

org.apache.ibatis.binding.BindingException: параметр 'arg0' не найден.Доступные параметры: [имя, param3, param1, адрес электронной почты, имя пользователя, param2] в org.apache.ibatis.binding.MapperMethod $ ParamMap.get (MapperMethod.java:204) ~ [mybatis-3.4.6.jar: 3.4.6] в org.apache.ibatis.builder.annotation.ProviderSqlSource.extractProviderMethodArguments (ProviderSqlSource.java:156) ~ [mybatis-3.4.6.jar: 3.4.6] в org.apache.ibatis.builder.annotation.ProviderSreSSQ(ProviderSqlSource.java:120) ~ [mybatis-3.4.6.jar: 3.4.6] в org.apache.ibatis.builder.annotation.ProviderSqlSource.getBoundSql (ProviderSqlSource.java:102) ~ [mybatis-3.4.6.jar: 3.4.6] в org.apache.ibatis.mapping.MappedStatement.getBoundSql (MappedStatement.java:292) ~ [mybatis-3.4.6.jar: 3.4.6] в org.apache.ibatis.executor.CachingExecutor.query (CachingExecutor.java:81) ~ [mybatis-3.4.6.jar: 3.4.6] в org.apache.ibatis.session.defaults.DefaultSqlSession.selectList (DefaultSqlSession.java:148) ~ [mybatis-3.4.6.jar: 3.4.6] at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList (DefaultSqlSession.java: 141) ~ [mybatis-3.4.6.jar: 3.4.6] в sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) ~ [na: 1.8.0_191] в sun.reflect .....

Что это за параметры [имя, param3, param1, электронная почта, имя пользователя, param2]]?

Нужно ли что-то еще для SqlBuilder?

1 Ответ

0 голосов
/ 13 декабря 2018

Проблема возникает из-за того, что mybatis не может передать параметры из метода mapper в конструктор.

Необходимо либо аннотировать параметры в компоновщике:

public static String buildFindByDynamicFilter(
   final @Param("username") String username,
   final @Param("name") String name,
   final @Param("email") String email) {

, либо удалить параметры, которые не используются в сигнатуре метода компоновщика (в вашем случае все они могут быть удалены как ни одиниз них используется в компоновщике):

public static String buildFindByDynamicFilter() {
    ...
} 

или включите имена параметров метода в скомпилированные классы и убедитесь, что параметры в методе компоновщика названы так же, как параметры в преобразователеmethod.

Mybatis Java API, который создает запрос (такие функции, как SELECT, FROM, WHERE и т. д.), не нуждается в параметрах сам по себе.Цель компоновщика - сгенерировать текст SQL-запроса.Связывание параметров происходит позже, когда mybatis извлек текст запроса из компоновщика (или @Select аннотация или xml mapper), и запрос выполняется с использованием подготовленных операторов JDBC.

[name, param3, param1, email, username, param2] - параметры метода mapper.Каждый параметр доступен под двумя ключами, первый - это значение аннотации @Param в аргументе метода mapper, а второй - просто порядковый номер аргумента с префиксом param (индекс равен нулю, а первыйпропускается, потому что первый параметр метода сопоставления неявный this).Mybatis пытается показать разумное сообщение об ошибке со списком доступных параметров, но если информация о параметрах метода недоступна, это сбивает с толку.

В компоновщике, если нет аннотации @Param, отражение используется дляполучить параметр метода.Если информация о параметрах метода не включена в -parameters опцию javac, тогда имена аргументов будут arg0, arg1 и т. Д.

...