美文网首页
【mybatis】@SelectProvider 源码解析

【mybatis】@SelectProvider 源码解析

作者: 天还下着毛毛雨 | 来源:发表于2020-12-15 18:49 被阅读0次

目前,向mybatis提供我们需要执行的sql
除了最常用的xml文件,和
@Select之类的注解,
还有一种@SelectProvider注解,可以利用Java类的某个方法来返回一段需要执行的sql

@SelectProvider使用示例
public interface UserMapper  {

    @SelectProvider(type = MySelectProvider.class, method = "findUser")
    List<User> findUser(@Param("id") int id);

}
public class MySelectProvider {

    public String findUser(Map<String, Object> param) {
        return new SQL() {{
            SELECT("*");
            FROM("USER");
            WHERE("id="+param.get("id"));
        }}.toString();
    }
}

执行UserMapper的findUser方法时,会调用MySelectProvider的findUser方法回去sql。

使用场景:

感觉不太常用,看个人喜好吧,有人喜欢java代码里写sql,会更灵活点?(xml其实也挺灵活的)

有一些mybatis的工具框架里会用到,比如通用mapper,Mapper接口集成父类接口的那些通用方法其实都是用@SelectProvider生成的,有兴趣的话可以自己去看一下。

源码分析

解析该注解的流程和解析@Select @Insert @Update @Delete 这几个注解的差不多,都是解析接口方法上面的注解,封装成MapperStatement对象,加入到Configuration的容器中。大体的流程可以看看 https://www.jianshu.com/p/94490cbd694e 这篇文章。

不同的地方在于构建SQLSource的地方。

创建ProviderSqlSource


image

这方法感觉没啥看的,就是一些收集工作,并将信息设置为
ProviderSqlSource的对应属性上

image

直接看创建后的ProviderSqlSource的属性值

image

这里并没有直接调用提供Java类的方法来创建SqlSource,而是重写了getBoundSql方法,类似于懒加载,等调用到mapper方法时,再调用getBoundSql()来创建具体的SqlSource。

image
写个test类,调用Mapper方法测试一下。

写个测试方法,UserMapper和SelectProvider的代码就是最开始的示例代码

@SpringBootTest
@RunWith(SpringRunner.class)
public class MapperTest {

    @Autowired
    private UserMapper userMapper;

    @org.junit.Test
    public void testProvider() {
        System.out.println(userMapper.findUser(2));
    }
}

启动,断点打到从MappedStatement获取BoundSql对象的地方


image

调用ProviderSqlSource的getBoundSql()来获取BoundSql

image image

哈哈,接下来肯定是反射Provider类的对应方法,获取返回值啦

image image

获取到这个SQL


image

最后创建了个RawSqlSource,并返回BoundSql

image image

相关文章

网友评论

      本文标题:【mybatis】@SelectProvider 源码解析

      本文链接:https://www.haomeiwen.com/subject/tznwgktx.html