简体   繁体   中英

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 .

The important thing is that UserQueryBuilder does not get parameters defines in UserMapper interface.

There are several components participating in query execution:

  1. the client of the mapper
  2. mapper interface
  3. query builder
  4. spring-mybatis library
  5. mybatis library

The mapper interface purpose is:

  1. to specify the query that would be used
  2. to specify parameters that query require
  3. to define actual java interface

Mapper may define the query directly using annotation like @Select , implicitly using the query defined in xml mapping or using the query builder via @SelectProvider . The purpose of the builder is the same as of @Select or xml mapping, namely to provide the query text to mapper.

The actual implementation of the mapper is provided by the spring-mybatis . That implementation is created dynamically based on the mapper class. The implementation works like this: when a method on the mapper is invoked it uses reflection to invoke appropriate methods (like selectOne or selectList based on the return type defined in the mapper method) on mybatis SqlSession . In order to do that it needs query text and parameters. Query text is taken from builder/annotation/xml. Parameters are available as parameters to mapper method invocation. Then SqlSessoin itself uses the query and parameters to execute the query using JDBC API.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM