Spring中带有Sql Builder和注释的MyBatis

时间:2018-12-12 21:57:40

标签: java spring mybatis

我在春季用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] oaccC [。[。[/]。[dispatcherServlet]:Servlet [dispatcherServlet]的Servlet.service()在路径为[]的上下文中引发异常[请求处理失败;嵌套异常是org.mybatis.spring.MyBatisSystemException:嵌套异常是org.apache.ibatis.builder.BuilderException:调用SqlProvider方法时出错(br.com.andre.springmvcuser.mapper.sqlbuilder.UserSqlBuilder.buildFindByDynamicFilter)。原因: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.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(本机方法)〜[na:1.8.0_191]       在太阳下反射.....

这些参数是什么[名称,param3,param1,电子邮件,用户名,param2]]?

我做SqlBuilder的方式还需要其他吗?

1 个答案:

答案 0 :(得分:3)

发生此问题是因为mybatis无法将参数从映射器方法传递给生成器。

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

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]是映射器方法的参数。每个参数都有两个键,第一个是mapper方法参数上@Param批注的值,第二个只是前缀为param的参数的序号(索引从零开始并且第一个被跳过,因为映射器方法的第一个参数是隐式this)。 Mybatis尝试显示带有可用参数列表的合理错误消息,但是如果没有可用的方法参数信息,则会造成混淆。

在构建器中,如果不存在@Param批注,则使用反射来获取方法参数。如果-parameters javac选项未包含方法参数信息,则参数名称为arg0arg1,依此类推。