mybatis provider:SQL类源码分析(SQL语句构建器)

  • Post author:
  • Post category:其他


SQL类是mybatis官方提供的一个sql构建器,官网上也有一些具体的使用案例:

https://mybatis.org/mybatis-3/zh/statement-builders.html

public String listUserWithRole(UserInfoDto userInfoDto) {
        return new SQL(){
            {
                SELECT("tui.id, tui.name, tui.age, tui.address, tr.role_name roleName");
                FROM("tb_user_info tui");
                LEFT_OUTER_JOIN("tb_user_role tur on tui.id = tur.user_id");
                LEFT_OUTER_JOIN("tb_role tr on tur.role_id = tr.id");
                //也可以用下面这种写法
                //LEFT_OUTER_JOIN("tb_user_role tur on tui.id = tur.user_id", "tb_role tr on tur.role_id = tr.id");

                if(userInfoDto.getAddress() != null) {
                    WHERE("address = #{userInfoDto.address}");
                }

                if(userInfoDto.getName() != null) {
                    WHERE("name = #{userInfoDto.name}");
                }
            }
        }.toString();
    }

SQL本身的结构比较简单,继承自抽象类AbstractSQL

主要的逻辑还是放在了AbstractSQL这个类里面。

UPDATE、SET以及下面的SELECT等,就是我们在匿名类中执行的方法。可以看出,我们给这些方法传入的参数,都被收集了起来,放入了SQLStatement这个内部类对象里,也就是sql对象。

SQLStatement内部类相当于一个大的容器,收集我们传入的参数

比如我们执行下面的语句时,会被SQL构建器做一个拆分

update tb_user set name = 'admin', age = 18 where id = 18

tb_user                                     放入                tables集合中

name = ‘admin’  以及  age=18 放入                set集合中

id = 18                                      放入                where集合中。

下面我们来完整的过一下流程,看看sql是如何构建的:

进入SELECT方法的内部

确实是一个拆分过程,将我们传入的参数,收集到sql集合中。

接下来就是 FROM、LEFT_OUTER_JOIN等语句的收集过程,最后调用toString方法。

这里的toString不太一样,它是整个sql构建过程的最终按钮,builder模式的最后build。

进入sql方法

传入sql方法的是StringBuilder,进入方法后,被装饰成了SafeAppendable。其实就是多了个非空检查,源码就不贴了。

SQL语句被简单地拆分成了四种类型:增删改查,按照分类传入不同的方法进行处理。

我们当前debug的语句是SELECT,所以进入selectSQL(builder)方法:

先检查是否有distinct关键字,随后按照语句执行的顺序,调用sqlClause:

比如我们的语句是:

............where name = 'admin' and  age = 18............

where集合里就有两个数据 name = ‘admin’ 以及 age = 18,传入sqlClause就是对应的List<String>parts。

拼装的逻辑如下:

1、先是关键字加上左边界符(keyword + open):

where(

2、再加上parts集合中的第一个元素

where( name = ‘admin’

3、i = 1 进入第二次循环时,会加上分隔符(conjunction),“where”操作的分隔符是 “AND”(见 SqlClause的最后一个参数)

where(name = ‘admin’ AND age = 18

4、最后结尾的时候,加上右边界符

where(name = ‘admin’ AND age = 18 )

where语句就这么组装完成了。

其他的关键字流程也差不多,不赘述。



版权声明:本文为qq_37855749原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。