问题
下面给mapper接口中的方法selectManyUsers
传两个参数(type 和homeTown
),在sql provider类UserSqlBuilder
的方法中直接引用#{type}、#{homeTown}
报错:
package com.thb.mapper;
import java.util.HashMap;
import java.util.List;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.jdbc.SQL;
import com.thb.model.User;
public interface UserMapper {
@Results(value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "userName", column = "user_name"),
@Result(property = "homeTown", column = "home_town"),
@Result(property = "type", column = "type"),
})
@SelectProvider(type = UserSqlBuilder.class, method = "selectManyUsers")
List<User> selectManyUsers(int type , String homeTown);
public static class UserSqlBuilder {
public static String selectManyUsers(final int type, final String homeTown) {
return new SQL() {{
SELECT("id, user_name, home_town, type");
FROM("user");
WHERE("type = #{type}");
WHERE("home_town = #{homeTown}");
//OFFSET(rowBounds.getOffset());
//LIMIT(rowBounds.getLimit());
}}.toString();
}
}
}
运行报错:
意思是没有发现type这个参数,可用的参数是[arg1, arg0, param1, param2]。
解决方法一(不推荐):在代码中用param1、param2这样的名字来引用
在代码中引用的时候使用#{param1}、#{param2}
这样的名字,这样是正确的。并且,mapper接口中定义的参数和sql provider中对应方法的参数必须对应,即,mapper接口中如果定义了2个参数,那么sql provider中对应方法也必须是2个参数,不能少。
显然,这种处理方法的缺点是不直观,所以不建议用。
例如,下面的代码:
现在运行就正确了:
解决方法二(推荐):在mapper接口方法中使用Param注解
在mapper接口方法中使用Param注解,指定参数的名字,在代码中就可以用参数的名字来引用了。
采用这种处理方法,sql provider方法参数的个数可以比mapper接口方法中参数的个数少。例如,mapper接口方法中定义了2个参数,在sql provider方法中可以用1个参数、2个参数。
package com.thb.mapper;
import java.util.HashMap;
import java.util.List;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.jdbc.SQL;
import com.thb.model.User;
public interface UserMapper {
@Results(value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "userName", column = "user_name"),
@Result(property = "homeTown", column = "home_town"),
@Result(property = "type", column = "type"),
})
@SelectProvider(type = UserSqlBuilder.class, method = "selectManyUsers")
List<User> selectManyUsers(@Param("type")int type, @Param("homeTown")String homeTown);
public static class UserSqlBuilder {
public static String selectManyUsers(@Param("type")final int type, @Param("homeTown")final String homeTown) {
return new SQL() {{
SELECT("id, user_name, home_town, type");
FROM("user");
WHERE("type = #{type}");
WHERE("home_town = #{homeTown}");
}}.toString();
}
}
}
下面的代码也是正确的(在sql provider的方法中只用到了1个参数):
package com.thb.mapper;
import java.util.HashMap;
import java.util.List;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.jdbc.SQL;
import com.thb.model.User;
public interface UserMapper {
@Results(value = {
@Result(property = "id", column = "id", id = true),
@Result(property = "userName", column = "user_name"),
@Result(property = "homeTown", column = "home_town"),
@Result(property = "type", column = "type"),
})
@SelectProvider(type = UserSqlBuilder.class, method = "selectManyUsers")
List<User> selectManyUsers(@Param("type")int type, @Param("homeTown")String homeTown);
public static class UserSqlBuilder {
public static String selectManyUsers(@Param("type")final int type) {
return new SQL() {{
SELECT("id, user_name, home_town, type");
FROM("user");
WHERE("type = #{type}");
}}.toString();
}
}
}