网上的解释都太肤浅,难以辨别真假,就自己跟了一下Mybatis源码
下面是过程记录,不详细,有空补全分析
$ :
进来是$
org.apache.ibatis.scripting.xmltags.DynamicSqlSource
org.apache.ibatis.scripting.xmltags.TextSqlNode 直接替换参数
#:
org.apache.ibatis.scripting.xmltags.DynamicSqlSource
进来是?
org.apache.ibatis.scripting.defaults.RawSqlSource
org.apache.ibatis.builder.StaticSqlSource
org.apache.ibatis.type.BaseTypeHandler
org.apache.ibatis.type.UnknownTypeHandler
org.apache.ibatis.type.TypeHandlerRegistry
org.apache.ibatis.mapping.BoundSql 有占位符的解释
org.apache.ibatis.parsing.GenericTokenParser 是mybatis关键解析类,它的openToken为#
org.apache.ibatis.builder.SqlSourceBuilder 中的handleToken 将SQL中井号参数记到parameterMappings,并将#换为?
总而言之,
Mybatis的SQL对占位符的解析阶段是在运行中。
$的SQL会直接换成参数,无引号;
#的SQL会先把#换成?、记录参数列表,在后续解析过程中,根据参数的类型,调用对应的TypeHandler进行值的set,无类型的默认为String,带引号设置进去,其他如IntegerTypeHandler也会转为对应的SQL形式。
两种占位符都是走的PreparedStatementHandler。