Search code examples
javaspring-mvcspring-bootmybatisspring-mybatis

Mybatis - parameter mapping in QueryBuilder class


I am fairly comfortable at using mybatis as an ORM tool. But i am not able to understand how parameter mapping works in mybatis.

say i have a mybatis mapper interface defined that has a method to fetch the user details.

And I have my Querybuilder class defined, which has the select query.

public interface UserMapper {

    @SelectProvider(type = UserQueryBuilder.class, method = "getUserId")
    Long getUserId(@Param("first") String firstName, @Param("last") String lastName, @Param("location") String location);

}


public class UserQueryBuilder(){

    public String getUserId(String firstName, String lastName, String location) {
        return new SQL() {{
            SELECT("USER_TABLE.USER_ID");
            FROM("USER_TABLE");
            WHERE("USER_TABLE.FIRST_NAME" + " = #{first}");
            WHERE("USER_TABLE.LAST_NAME" + " = #{last}");
            WHERE("USER_TABLE.LOCATION" + " = #{location}");

        }}.toString();
    }

}

In the above mentioned QueryBuilder, how the SQL query parameters were able to get mapped to "first" and "last" param values, defined in the 'userMapper' interface.


Solution

  • MyBatis builds an dynamic proxy for mapper like Spring AOP Proxy, for MyBatis is using MapperProxyFactory to create the proxy instance MapperProxy with the proxy interface(UserMapper).

    So when invoke the getUserId, MapperProxy will catch the target method and parameters by:

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    

    this will invoke the correspond MapperMethod to execute the sql with converted args to parameters by:

    Object param = method.convertArgsToSqlCommandParam(args);
    result = sqlSession.selectOne(command.getName(), param);
    

    Since method.convertArgsToSqlCommandParam actually will generated named parameters by @Param annotations.

    and also need to replace placeholder(#{first}) to ask and with correspond parameters, after this it will create BoundSql that own the raw sql and parameters, these will hand to jdbc dirver to execute like we use the jdbcTemplate directly.