【问题标题】:MyBatis in Spring with Sql Builder and annotationSpring 中的 MyBatis 与 Sql Builder 和注释
【发布时间】:2018-12-12 21:57:40
【问题描述】:

我在 Spring 中使用 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);

不起作用的那个:

映射器

@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] o.a.c.c.C.[.[.[/].[dispatcherServlet]:Servlet.service() 用于 servlet [dispatcherServlet]在路径 [] 的上下文中抛出异常 [请求处理失败;嵌套异常是 org.mybatis.spring.MyBatisSystemException:嵌套异常是 org.apache.ibatis.builder.BuilderException:调用 SqlProvider 方法时出错(br.com.andre.springmvcuser.mapper.sqlbuilder.UserSqlBuilder.buildFindByDynamicFilter)。原因:org.apache.ibatis.binding.BindingException:找不到参数“arg0”。可用参数是 [name, param3, param1, email, username, param2]] 与根本原因

org.apache.ibatis.binding.BindingException:找不到参数“arg0”。可用参数为 [name, param3, param1, email, username, 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.ProviderSqlSource.createSqlSource(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] 在 org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141) ~[mybatis-3.4.6.jar:3.4.6] 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191] 在 sun.reflect .....

这些参数是什么[name, param3, param1, email, username, param2]]?

我做SqlBuilder的方式还需要别的吗?

【问题讨论】:

    标签: java spring mybatis


    【解决方案1】:

    问题出现是因为mybatis无法将mapper方法的参数传递给builder。

    您要么需要在构建器中注释参数:

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

    或从构建器方法签名中删除未使用的参数(在您的情况下,所有参数都可以删除,因为它们都没有在构建器中使用):

    public static String buildFindByDynamicFilter() {
        ...
    } 
    

    include method parameter names 到已编译的类中,并确保builder 方法中的参数与mapper 方法中的参数命名方式相同。

    构建查询的Mybatis java API(SELECTFROMWHERE等函数)本身不需要参数。构建器的目的是生成 sql 查询文本。当 mybatis 从构建器(或 @Select 注释或 xml 映射器)检索查询文本并使用 JDBC 准备语句执行查询时,稍后会发生参数绑定。

    [name, param3, param1, email, username, param2] 是映射器方法的参数。每个参数在两个键下可用,第一个是映射器方法参数上@Param 注释的值,第二个只是以param 为前缀的参数的序号(索引从零开始,第一个被跳过是因为 mapper 方法的第一个参数是隐式的this)。 Mybatis 尝试通过可用参数列表显示合理的错误消息,但如果没有可用的方法参数信息,则会令人困惑。

    如果没有@Param 注释,则在构建器中使用反射来获取方法参数。如果-parameters javac 选项中不包含方法参数信息,则参数名称为arg0arg1 等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多