我在春季用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的方式还需要其他吗?
答案 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(诸如SELECT
,FROM
,WHERE
等功能)本身不需要参数。构建器的目的是生成sql查询文本。当mybatis从构建器(或@Select
批注或xml映射器)中检索查询文本,并使用JDBC准备的语句执行查询时,将进行参数绑定。
[name, param3, param1, email, username, param2]
是映射器方法的参数。每个参数都有两个键,第一个是mapper方法参数上@Param
批注的值,第二个只是前缀为param
的参数的序号(索引从零开始并且第一个被跳过,因为映射器方法的第一个参数是隐式this
)。 Mybatis尝试显示带有可用参数列表的合理错误消息,但是如果没有可用的方法参数信息,则会造成混淆。
在构建器中,如果不存在@Param
批注,则使用反射来获取方法参数。如果-parameters
javac选项未包含方法参数信息,则参数名称为arg0
,arg1
,依此类推。