Mybatis - QueryBuilder 中的参数映射 class
Mybatis - parameter mapping in QueryBuilder class
我很擅长使用 mybatis 作为 ORM 工具。
但是我无法理解参数映射在mybatis中是如何工作的。
假设我定义了一个 mybatis 映射器接口,它有一个获取用户详细信息的方法。
我定义了 Querybuilder
class,其中有 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();
}
}
在上面提到的 QueryBuilder
中,SQL 查询 参数如何能够映射到 "first" 和 "last"参数值,定义在'userMapper'接口.
MyBatis 使用 代理接口构建一个 dynamic proxy for mapper like Spring AOP Proxy, for MyBatis is using MapperProxyFactory to create the proxy instance MapperProxy(UserMapper
).
因此,当调用 getUserId
时,MapperProxy
将通过以下方式捕获 目标方法 和 参数 :
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
这将调用相应的 MapperMethod 来执行 sql 并将 args 转换为参数 通过:
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
因为method.convertArgsToSqlCommandParam
实际上会通过@Param注释生成命名参数。
并且还需要将placeholder(#{first}
)替换为ask并使用相应的参数,之后它将创建BoundSql 拥有 原始 sql 和 参数 ,这些将交给 jdbc dirver 就像我们直接使用 jdbcTemplate 一样执行。
重要的是 UserQueryBuilder
没有获取 UserMapper
接口中定义的参数。
有几个组件参与查询执行:
- 映射器的客户端
- 映射器接口
- 查询生成器
- spring-mybatis库
- mybatis 库
映射器接口的用途是:
- 指定要使用的查询
- 指定查询需要的参数
- 定义实际的java接口
Mapper 可以直接使用注释定义查询,如 @Select
,隐式使用 xml 映射中定义的查询或通过 @SelectProvider
使用查询构建器。构建器的目的与 @Select
或 xml 映射相同,即 provide the query text
映射器。
映射器的实际实现由spring-mybatis
提供。该实现是基于映射器 class 动态创建的。实现是这样工作的:当调用映射器上的方法时,它使用反射来调用适当的方法(如 selectOne
或 selectList
基于映射器方法中定义的 return 类型) mybatis SqlSession
.为此,它需要查询文本和参数。查询文本取自 builder/annotation/xml。参数可用作映射器方法调用的参数。然后 SqlSessoin
本身使用查询和参数使用 JDBC API.
执行查询
我很擅长使用 mybatis 作为 ORM 工具。 但是我无法理解参数映射在mybatis中是如何工作的。
假设我定义了一个 mybatis 映射器接口,它有一个获取用户详细信息的方法。
我定义了 Querybuilder
class,其中有 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();
}
}
在上面提到的 QueryBuilder
中,SQL 查询 参数如何能够映射到 "first" 和 "last"参数值,定义在'userMapper'接口.
MyBatis 使用 代理接口构建一个 dynamic proxy for mapper like Spring AOP Proxy, for MyBatis is using MapperProxyFactory to create the proxy instance MapperProxy(UserMapper
).
因此,当调用 getUserId
时,MapperProxy
将通过以下方式捕获 目标方法 和 参数 :
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
这将调用相应的 MapperMethod 来执行 sql 并将 args 转换为参数 通过:
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
因为method.convertArgsToSqlCommandParam
实际上会通过@Param注释生成命名参数。
并且还需要将placeholder(#{first}
)替换为ask并使用相应的参数,之后它将创建BoundSql 拥有 原始 sql 和 参数 ,这些将交给 jdbc dirver 就像我们直接使用 jdbcTemplate 一样执行。
重要的是 UserQueryBuilder
没有获取 UserMapper
接口中定义的参数。
有几个组件参与查询执行:
- 映射器的客户端
- 映射器接口
- 查询生成器
- spring-mybatis库
- mybatis 库
映射器接口的用途是:
- 指定要使用的查询
- 指定查询需要的参数
- 定义实际的java接口
Mapper 可以直接使用注释定义查询,如 @Select
,隐式使用 xml 映射中定义的查询或通过 @SelectProvider
使用查询构建器。构建器的目的与 @Select
或 xml 映射相同,即 provide the query text
映射器。
映射器的实际实现由spring-mybatis
提供。该实现是基于映射器 class 动态创建的。实现是这样工作的:当调用映射器上的方法时,它使用反射来调用适当的方法(如 selectOne
或 selectList
基于映射器方法中定义的 return 类型) mybatis SqlSession
.为此,它需要查询文本和参数。查询文本取自 builder/annotation/xml。参数可用作映射器方法调用的参数。然后 SqlSessoin
本身使用查询和参数使用 JDBC API.