mybatis中动态sql执行原理
- SqlResource 该接口含义是作为sql对象的来源,通过该接口可以获取sql对象。其唯一的实现类是XmlSqlResource,表示通过xml文件生成sql对象。
- Sql 该接口可以生成sql语句和获取sql相关的上下文环境(如ParameterMap、ResultMap等),有三个实现类: RawSql表示为原生的sql语句,在初始化即可确定sql语句;SimpleDynamicSql表示简单的动态sql,即sql语句中参数通过方式指定,参数在sql生成过程中会被替换,不作为sql执行参数;DynamicSql表示动态sql,即sql描述文件中包含isNotNull等条件标签。
- SqlChild 该接口表示sql抽象语法树的一个节点,包含sql语句的片段信息。该接口有两个实现类: SqlTag表示动态sql片段,即配置文件中的一个动态标签,内含动态sql属性值(如prepend、property值等);SqlText表示静态sql片段,即为原生的sql语句。每条动态sql通过SqlTag和SqlText构成相应的抽象语法树。
- SqlTagHandler 该接口表示SqlTag(即不同的动态标签)对应的处理方式。比如实现类IsEmptyTagHandler用于处理标签,IsEqualTagHandler用于处理标签等。
- SqlTagContext 用于解释sql抽象语法树时使用的上下文环境。通过解释语法树每个节点,将生成的sql存入SqlTagContext。最终通过SqlTagContext获取完整的sql语句。
从设计上看,dynamic sql的实现主要涉及三个模式:
解释器模式: 初始化过程中构建出抽象语法树,请求处理时根据参数对象解释语法树,生成sql语句。
工厂模式: 为动态标签的处理方式创建工厂类(SqlTagHandlerFactory),根据标签名称获取对应的处理方式。
策略模式: 将动态标签处理方式抽象为接口,针对不同标签有相应的实现类。解释抽象语法树时,定义统一的解释流程,再调用标签对应的处理方式完成解释中的各个子环节