[MyBatis]SQL拼接过程

1,306 阅读2分钟

之前说得太抽象,现在补充完整一点。

之所以我们在继承了baseMapper之后,就拥有了selectByPrimarykey()、insert()、updateByPrimarykeySelective()这些方法,是因为baseMapper继承了分别对应增删改查的四个mapper


以baseSelectMapper为例,它继承了其他几个有比较具体的select方法的mapper

public interface BaseSelectMapper<T> extends SelectOneMapper<T>, SelectMapper<T>, SelectAllMapper<T>, SelectCountMapper<T>, SelectByPrimaryKeyMapper<T> {
}

以selectOneMapper为例,它里面使用了 SelectProvider 注解,它的意思是selectOne方法的sql语句交由BaseSelectProvider.class来完成

public interface SelectOneMapper<T> {
    @SelectProvider(
        type = BaseSelectProvider.class,
        method = "dynamicSQL"
    )
    T selectOne(T var1);
}

@SelectProvider注解用于生成查询用的sql语句,有别于@Select注解,@SelectProvide指定一个Class及其方法,并且通过调用Class上的这个方法来获得sql语句。


最后在BaseSelectProvider里的selectOne()方法,接受了一个MappedStatement.class类作为参数,拼接成sql语句返回。

MappedStatement.class 的位置在org.apache.ibatis.mapping包下,里面包含了执行操作所需的详细信息。

public String selectOne(MappedStatement ms) {
    Class entityClass = this.getEntityClass(ms);
    boolean isMl = EntityHelper.getEntityTable(entityClass).isSupportMultiLanguage();
    this.setResultType(ms, entityClass);
    StringBuilder sql = new StringBuilder();
    if(isMl) {                                                                             //判断是否是多语言字段
        sql.append(SqlHelper.selectAllColumns_TL(entityClass));
        sql.append(SqlHelper.fromTable_TL(entityClass, this.tableName(entityClass)));
        sql.append(SqlHelper.whereAllIfColumns_TL(entityClass, this.isNotEmpty()));
    } else {
        sql.append(SqlHelper.selectAllColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, this.tableName(entityClass)));
        sql.append(SqlHelper.whereAllIfColumns(entityClass, this.isNotEmpty()));             //如果有dto参数,则解析成where条件
    }

    return sql.toString();
}

注意这里的 EntityHelper ,用作实体类和数据库表之间的转换,在另外一篇提到的Condition注解,以及多语言注解等等都是在这个类里面进行解析的。

EntityHelper中解析的所有注解:

  1. Condition 在另一篇里面详细说过了
  2. MultiLanguage 多语言,在另一篇里面详细说过了
  3. NameStyle 命名方式,驼峰、大小写
  4. Table 主要用于设定表名
  5. ExtensionAttribute 设置成false的话,就不会在sql里用到额外的15个attr
  6. Column 用在属性上,这个功能特别多,但是我测试了一下,似乎没有作用,后面继续补充
  7. ColumnType jdbcType 也还没测
  8. OrderBy 设置在属性上,有“ASC”和“DES”两种可选
  9. SequenceGenerator
  10. GeneratedValue 有["UUID","JDBC","SEQUENCE","IDENTITY"]四种
  11. Id 作用在行上,用于设置id

另外值得一提的是 whereAllIfColumns() 方法。

它是根据传入的参数拼凑成where语句,通配符和模糊查询都由之前提到的condition注解来控制。有兴趣的可以看看这两个类的代码。

**补充说明:**

mapper调用自带的方法的作用过程为(比如selectByPrimaryKey()):


1、 调用common.base包下面的相应mapper


2、 mapper指向provider包下面的相应provider


3、 provider调用mapperhelper包下面的不同功能的helper,来组成mapper.xml类似的语句,用到的最主要的helper就是SqlHelper