Mybatis3.5.1源码分析
- Mybatis-SqlSessionFactoryBuilder,XMLConfigBuilder,XPathParser源码解析
- Mybatis-Configuration源码解析
- Mybatis-事务对象源码解析
- Mybatis-数据源源码解析
- Mybatis缓存策略源码解析
- Mybatis-DatabaseIdProvider源码解析
- Mybatis-TypeHandler源码解析
- Mybatis-Reflector源码解析
- Mybatis-ObjectFactory,ObjectWrapperFactory源码分析
- Mybatis-Mapper各类标签封装类源码解析
- Mybatis-XMLMapperBuilder,XMLStatmentBuilder源码分析
- Mybatis-MapperAnnotationBuilder源码分析
- [Mybatis-MetaObject,MetaClass源码解析]https://www.jianshu.com/p/f51fa552f30a)
- Mybatis-LanguageDriver源码解析
- Mybatis-SqlSource源码解析
- Mybatis-SqlNode源码解析
- Mybatis-KeyGenerator源码解析
- Mybatis-Executor源码解析
- Mybatis-ParameterHandler源码解析
- Mybatis-StatementHandler源码解析
- Mybatis-DefaultResultSetHandler(一)源码解析
- Mybatis-DefaultResultSetHandler(二)源码解析
- Mybatis-ResultHandler,Cursor,RowBounds 源码分析
- Mybatis-MapperProxy源码解析
- Mybatis-SqlSession源码解析
- Mybatis-Interceptor源码解析
LanguageDriver
/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.scripting;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.Configuration;
/**
* 语言驱动
*/
public interface LanguageDriver {
/**
* Creates a {@link ParameterHandler} that passes the actual parameters to the the JDBC statement.
* 创建 {@link ParameterHandler} 通过JDBC的实际参数
* @param mappedStatement The mapped statement that is being executed 映射的正在执行语句
* @param parameterObject The input parameter object (can be null) 输入的参数对象(可以为空)
* @param boundSql The resulting SQL once the dynamic language has been executed. 生成的SQL,一旦动态语言被执行
* @return
* @author Frank D. Martinez [mnesarco]
* @see DefaultParameterHandler
*/
ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql);
/**
* Creates an {@link SqlSource} that will hold the statement read from a mapper xml file.
* It is called during startup, when the mapped statement is read from a class or an xml file.
* 创建一个{@link SqlSource} 读取映射XML文件
* @param configuration The MyBatis configuration MyBatis配置
* @param script XNode parsed from a XML file
* @param parameterType input parameter type got from a mapper method or specified in the parameterType xml attribute. Can be null.
* 输入参数类型从一个xml类型映射器参数中指定的方法或属性。可以为空。;
* @return
*/
SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType);
/**
* Creates an {@link SqlSource} that will hold the statement read from an annotation.
* It is called during startup, when the mapped statement is read from a class or an xml file.
* 创建一个{@link SqlSource} 从一个字解里,它在启动期间,当映射语句从一个类或读取一个xml文件被调用。;
* @param configuration The MyBatis configuration
* @param script The content of the annotation
* @param parameterType input parameter type got from a mapper method or specified in the parameterType xml attribute. Can be null.
* 输入参数类型从一个xml类型映射器参数中指定的方法或属性。可以为空。;
* @return
*/
SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType);
}
XMLLanguageDriver
/**
* Copyright 2009-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.scripting.xmltags;
import org.apache.ibatis.builder.xml.XMLMapperEntityResolver;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.parsing.PropertyParser;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.scripting.defaults.RawSqlSource;
import org.apache.ibatis.session.Configuration;
/**
* XML语言驱动
* <p>
* Mybatis默认XML驱动类为XMLLanguageDriver,其主要作用于解析select|update|insert|delete节点为完整的SQL语句。
* </p>
* @author Eduardo Macarron
*/
public class XMLLanguageDriver implements LanguageDriver {
@Override
public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
return new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
}
@Override
public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {
XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType);
/***
* 当sql中包含有${}时,就认为是动态SQL
* 或者 当DML标签存在动态SQL标签名,如<if>,<trim>等,就认为是动态SQL
* ,如果是动态返回 {@link DynamicSqlSource} ,否则 {@link RawSqlSource}
*/
return builder.parseScriptNode();
}
@Override
public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
// issue #3 此处兼容XML方式的解析,条件以<script>为头结点
if (script.startsWith("<script>")) {
XPathParser parser = new XPathParser(script, false, configuration.getVariables(), new XMLMapperEntityResolver());
return createSqlSource(configuration, parser.evalNode("/script"), parameterType);
} else {
// issue #127
/**
* 解析Configuration#variable变量,将有${...}形式的字符串转换成对应字符串,
* eg: '${first_name},${initial},${last_name}' => 'James,T,Kirk'
*/
script = PropertyParser.parse(script, configuration.getVariables());
TextSqlNode textSqlNode = new TextSqlNode(script);
//根据TextSqlNode的内部属性isDynamic来进行解析帮助类的分配
if (textSqlNode.isDynamic()) {
return new DynamicSqlSource(configuration, textSqlNode);
} else {
return new RawSqlSource(configuration, script, parameterType);
}
}
}
}
XMLScriptBuilder
/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.scripting.xmltags;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.builder.BaseBuilder;
import org.apache.ibatis.builder.BuilderException;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.scripting.defaults.RawSqlSource;
import org.apache.ibatis.session.Configuration;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* XML脚本构建器
* @author Clinton Begin
*/
public class XMLScriptBuilder extends BaseBuilder {
/**
* DML标签
*/
private final XNode context;
/**
* 是否是动态SQL脚本.
* <ol style='margin-top:0px'>
* <li>当sql中包含有${}时,就认为是动态SQL</li>
* <li>当DML标签存在动态SQL标签名,如<if>,<trim>等,就认为是动态SQL</li>
* </ol>
*/
private boolean isDynamic;
/**
* DML标签的参数类型
*/
private final Class<?> parameterType;
/**
* 标签节点处理映射,key=动态SQL标签名,如<if>,<trim>等,value=动态SQL标签处理类实例
*/
private final Map<String, NodeHandler> nodeHandlerMap = new HashMap<>();
/**
*
* @param configuration mybatis全局配置
* @param context DML标签
*/
public XMLScriptBuilder(Configuration configuration, XNode context) {
this(configuration, context, null);
}
/**
*
* @param configuration mybatis全局配置
* @param context DML标签
* @param parameterType 参数类型
*/
public XMLScriptBuilder(Configuration configuration, XNode context, Class<?> parameterType) {
super(configuration);
this.context = context;
this.parameterType = parameterType;
initNodeHandlerMap();
}
/**
* 将所有的动态SQL标签处理器添加到 {@link #nodeHandlerMap}
*/
private void initNodeHandlerMap() {
nodeHandlerMap.put("trim", new TrimHandler());
nodeHandlerMap.put("where", new WhereHandler());
nodeHandlerMap.put("set", new SetHandler());
nodeHandlerMap.put("foreach", new ForEachHandler());
nodeHandlerMap.put("if", new IfHandler());
nodeHandlerMap.put("choose", new ChooseHandler());
nodeHandlerMap.put("when", new IfHandler());
nodeHandlerMap.put("otherwise", new OtherwiseHandler());
nodeHandlerMap.put("bind", new BindHandler());
}
/**
* 解析脚本标签节点
* @return
* 当sql中包含有${}时,就认为是动态SQL
* 或者 当DML标签存在动态SQL标签名,如<if>,<trim>等,就认为是动态SQL
* ,如果是动态返回 {@link DynamicSqlSource} ,否则 {@link RawSqlSource}
*/
public SqlSource parseScriptNode() {
//解析DML标签下的子节点,封装成MixedSqlNode
MixedSqlNode rootSqlNode = parseDynamicTags(context);
SqlSource sqlSource;
if (isDynamic) {
//只创建DynamicSqlSource对象。完整可执行的sql,需要在调用getBoundSql(Parameter)方法时才能组装完成。
sqlSource = new DynamicSqlSource(configuration, rootSqlNode);
} else {
/**
* 调用 SqlSourceBuilder类将"#{xxx}“ 替换为占位符”?",并绑定ParameterMapping,
* 最后返回的RawSqlSource中持有一个由SqlSourceBuilder构建的SqlSource对象。
*/
sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType);
}
return sqlSource;
}
/**
* 解析动态SQL标签,对 {@code node} 的子节点和文本节点进行解析,
* 这里会检测是否属于动态就会对isDynamic设置对应的值
* @param node DML标签或者是动态SQL标签
* @return 混合着 {@code node} 的子节点的MixedSqlNode实例
*/
protected MixedSqlNode parseDynamicTags(XNode node) {
List<SqlNode> contents = new ArrayList<>();
NodeList children = node.getNode().getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
/**
* XNode.newXNode(Node node):新建一个XNode,XNode只是mybatis对Node实例的封装,用于方便操作。
* 并不是添加node节点的功能
*/
XNode child = node.newXNode(children.item(i));
/**
* Node.CDATA_SECTION_NODE:代表文档中的 CDATA 部(不会由解析器解析的文本)
* Node.TEXT_NODE:代表元素或属性中的文本内容
*/
if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE || child.getNode().getNodeType() == Node.TEXT_NODE) {
//获取文本节点的文本内容
String data = child.getStringBody("");
//文本SQL节点。用传入的实际参数对象中的属性值对${}进行直接替换,并且不会进行任何检查!
TextSqlNode textSqlNode = new TextSqlNode(data);
//当sql中包含有${}时,就认为是动态SQL.下面就是根据是否是动态SQL来添加对应SqlNode类型
if (textSqlNode.isDynamic()) {
contents.add(textSqlNode);
isDynamic = true;
} else {
//StaticTextSqlNode:静态文本SQL节点,其apply方法使得只是将存储的文本内容直接添加到DynamicContext对象中
contents.add(new StaticTextSqlNode(data));
}
} else if (child.getNode().getNodeType() == Node.ELEMENT_NODE) { // issue #628 Node.ELEMENT_NODE:代表元素
String nodeName = child.getNode().getNodeName();
//根据标签名找到对应的NodeHandler
NodeHandler handler = nodeHandlerMap.get(nodeName);
if (handler == null) {
throw new BuilderException("Unknown element <" + nodeName + "> in SQL statement.");
}
handler.handleNode(child, contents);
isDynamic = true;
}
}
return new MixedSqlNode(contents);
}
/**
* 标签节点处理器,解析标签节点,封装到对应sqlNode中
*/
private interface NodeHandler {
/**
* 解析标签节点,封装到对应sqlNode中,并将sqlNode添加到 {@code targetContents}
* @param nodeToHandle 动态SQL标签名,如<if>,<trim>等
* @param targetContents 解析完 {@code nodeToHandle}SqlNode后,
*/
void handleNode(XNode nodeToHandle, List<SqlNode> targetContents);
}
/**
* <bind>处理器:元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文
* <p>如:</p>
* <p>
* <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
* </p>
*/
private class BindHandler implements NodeHandler {
public BindHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
//获取bind标签的name属性值
final String name = nodeToHandle.getStringAttribute("name");
//获取bind标签的value属性值
final String expression = nodeToHandle.getStringAttribute("value");
//OGNL解析
final VarDeclSqlNode node = new VarDeclSqlNode(name, expression);
targetContents.add(node);
}
}
/**
* trim标签处理器
*/
private class TrimHandler implements NodeHandler {
public TrimHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
//解析trim标签下的字节点,封装成MixedSqlNode
MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);
//获取trim标签的prefix属性,给sql语句拼接的前缀
String prefix = nodeToHandle.getStringAttribute("prefix");
/**
* 获取trim标签的prefixOverrides属性
* 去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,
* 假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
*/
String prefixOverrides = nodeToHandle.getStringAttribute("prefixOverrides");
//获取trim标签的suffix属性,给sql语句拼接的后缀
String suffix = nodeToHandle.getStringAttribute("suffix");
//获取trim标签的suffixOverride,去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
String suffixOverrides = nodeToHandle.getStringAttribute("suffixOverrides");
//Trim标签的功能逻辑交给TrimSqlNode
TrimSqlNode trim = new TrimSqlNode(configuration, mixedSqlNode, prefix, prefixOverrides, suffix, suffixOverrides);
targetContents.add(trim);
}
}
/**
* where标签处理器
*/
private class WhereHandler implements NodeHandler {
public WhereHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
//解析where标签下的字节点,封装成MixedSqlNode
MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);
//where标签的功能逻辑交给whereSqlNode处理
WhereSqlNode where = new WhereSqlNode(configuration, mixedSqlNode);
targetContents.add(where);
}
}
/**
* Set标签处理器
*/
private class SetHandler implements NodeHandler {
public SetHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
//解析set标签下的子节点,封装成MixedSqlNode
MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);
//set标签的功能逻辑交给whereSqlNode处理
SetSqlNode set = new SetSqlNode(configuration, mixedSqlNode);
targetContents.add(set);
}
}
/**
* forEach标签接收处理器
*/
private class ForEachHandler implements NodeHandler {
public ForEachHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
///解析forEach标签下的子节点,封装成MixedSqlNode
MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);
//获取foreach标签的collection属性,循环的集合对象名
String collection = nodeToHandle.getStringAttribute("collection");
//获取foreach标签的item属性,集合对象的元素名
String item = nodeToHandle.getStringAttribute("item");
//获取foreach标签的index属性,在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
String index = nodeToHandle.getStringAttribute("index");
//获取foreach标签的open属性,foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选。
String open = nodeToHandle.getStringAttribute("open");
//获取foreach标签的close属性,foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
String close = nodeToHandle.getStringAttribute("close");
/**
* 获取foreach标签的separator属性,元素之间的分隔符,例如在in()的时候,
* separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选
*/
String separator = nodeToHandle.getStringAttribute("separator");
ForEachSqlNode forEachSqlNode = new ForEachSqlNode(configuration, mixedSqlNode, collection, index, item, open, close, separator);
targetContents.add(forEachSqlNode);
}
}
/**
* if标签接收处理器
*/
private class IfHandler implements NodeHandler {
public IfHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
//解析if标签下的子节点,封装成MixedSqlNode
MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);
//获取if标签的test属性,ognl表达式
String test = nodeToHandle.getStringAttribute("test");
IfSqlNode ifSqlNode = new IfSqlNode(mixedSqlNode, test);
targetContents.add(ifSqlNode);
}
}
/**
* otherwise标签,当 when 元素中的条件都不生效,就可以使用 otherwise 元素的默认文本。
*/
private class OtherwiseHandler implements NodeHandler {
public OtherwiseHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
//解析otherwise标签下的子节点,封装成MixedSqlNode
MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);
/**
* 因为otherwise标签的应用情况是由choose标签控制,而且应用otherwise标签不过是
* 应用otherwise标签的所有子节点对应sqlNode,所有otherwise不需要对应的sqlNode
*/
targetContents.add(mixedSqlNode);
}
}
/**
* choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。
* 当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。
* 类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
*/
private class ChooseHandler implements NodeHandler {
public ChooseHandler() {
// Prevent Synthetic Access
}
@Override
public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
List<SqlNode> whenSqlNodes = new ArrayList<>();
List<SqlNode> otherwiseSqlNodes = new ArrayList<>();
//接收处理when标签和otherwise标签
handleWhenOtherwiseNodes(nodeToHandle, whenSqlNodes, otherwiseSqlNodes);
//获取otherwise标签
SqlNode defaultSqlNode = getDefaultSqlNode(otherwiseSqlNodes);
ChooseSqlNode chooseSqlNode = new ChooseSqlNode(whenSqlNodes, defaultSqlNode);
targetContents.add(chooseSqlNode);
}
/**
* 接收处理when标签和otherwise标签
* @param chooseSqlNode choose标签
* @param ifSqlNodes when标签集合
* @param defaultSqlNodes otherwise标签集合
*/
private void handleWhenOtherwiseNodes(XNode chooseSqlNode, List<SqlNode> ifSqlNodes, List<SqlNode> defaultSqlNodes) {
List<XNode> children = chooseSqlNode.getChildren();
for (XNode child : children) {
String nodeName = child.getNode().getNodeName();
NodeHandler handler = nodeHandlerMap.get(nodeName);
if (handler instanceof IfHandler) {//when标签的处理器是IfHandler
//handleNode方法会将child添加到ifSqlNodes集合中
handler.handleNode(child, ifSqlNodes);
} else if (handler instanceof OtherwiseHandler) {//Otherwise标签
//handleNode方法会将child添加到defaultSqlNodes集合中
handler.handleNode(child, defaultSqlNodes);
}
}
}
/**
* 获取otherwise标签
* @param defaultSqlNodes otherwise标签集合
* @return 返回集合的第一个元素, {@code defaultSqlNodes} 只能存在一个元素或者没有元素,
* 超过一个都会抛出BuilderException
*/
private SqlNode getDefaultSqlNode(List<SqlNode> defaultSqlNodes) {
SqlNode defaultSqlNode = null;
if (defaultSqlNodes.size() == 1) {
defaultSqlNode = defaultSqlNodes.get(0);
} else if (defaultSqlNodes.size() > 1) {
throw new BuilderException("Too many default (otherwise) elements in choose statement.");
}
return defaultSqlNode;
}
}
}
RawLanguageDriver
/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.scripting.defaults;
import org.apache.ibatis.builder.BuilderException;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
/**
* 这是一个简单的语言驱动,只能针对静态SQL的处里,如果出现动态SQL标签会抛出异常
* As of 3.2.4 the default XML language is able to identify static statements
* and create a {@link RawSqlSource}. So there is no need to use RAW unless you
* want to make sure that there is not any dynamic tag for any reason.
* 默认XML语言是能够识别静态语句并创建一个{@link RawSqlSource},所以没有需要使用原始的,除非你想确保没有任何动态标记任何理由。
* @since 3.2.0
* @author Eduardo Macarron
*/
public class RawLanguageDriver extends XMLLanguageDriver {
@Override
public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {
SqlSource source = super.createSqlSource(configuration, script, parameterType);
checkIsNotDynamic(source);
return source;
}
@Override
public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
SqlSource source = super.createSqlSource(configuration, script, parameterType);
checkIsNotDynamic(source);
return source;
}
private void checkIsNotDynamic(SqlSource source) {
if (!RawSqlSource.class.equals(source.getClass())) {
throw new BuilderException("Dynamic content is not allowed when using RAW language");
}
}
}