首先翻阅官网文档,(https://mybatis.org/mybatis-3/dynamic-sql.html)这页文档首先描述了Mybatis的动态SQL是多么牛逼,解决了哪些问题,又讲了如何使用,而我们想知道他是如何实现的,所以这不是我们想要的。
Dynamic SQL
One of the most powerful features of MyBatis has always been its Dynamic SQL capabilities. If you have any experience with JDBC or any similar framework, you understand how painful it is to conditionally concatenate strings of SQL together, making sure not to forget spaces or to omit a comma at the end of a list of columns. Dynamic SQL can be downright painful to deal with.
While working with Dynamic SQL will never be a party, MyBatis certainly improves the situation with a powerful Dynamic SQL language that can be used within any mapped SQL statement.
现在,我们去找mybatis源码(https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.4)
首先,在Mybatis中,首先从可以看到LanguageDriver接口中的createSqlSource方法,该类其中有2个方法,和2个实现类XMLLanguageDriver和RawLanguageDriver,他们的关系如下:
接下来我们可以看到该接口的其中2个方法:
1.通过解析XML文件为XNode数据
/** * 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. * * @param configuration The MyBatis configuration * @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. * @return */ SqlSource createSqlSource(Configuration configuration, XNode script, Class> parameterType);
2.通过解析注解内容
/** * 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. * * @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. * @return */ SqlSource createSqlSource(Configuration configuration, String script, Class> parameterType);
这两种方式都是为了获得SqlSource对象,第一个方法就是我们常规的通过XML配置SQL语句的方式创建,而第二种是在数据访问层通过对方法加对应注解(eg:@Select)的方式创建。
而XMLLanguageDriver类实现了这两个方法
@Override public SqlSource createSqlSource(Configuration configuration, XNode script, Class> parameterType) { XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType); return builder.parseScriptNode(); } @Override public SqlSource createSqlSource(Configuration configuration, String script, Class> parameterType) { // issue #3 if (script.startsWith("