-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL parameter substitution functionality differs substantially from string substitution functionality #206
Labels
enhancement
Improve a feature or add a new feature
Comments
Does it exist a workaround for last issue? How can I set actual value in following statement? <foreach item="c" collection="filter.getFilter()" separator=" AND " open="(" close=")">
<bind name="column" value="_parameter.mappingWhere(c.colCode)"/>
<bind name="operator" value="_parameter.conditionOperator(c.condition)"/>
<bind name="value" value="_parameter.conditionValue(c.condition, c.value)"/>
${column} ${operator} #{value}
</foreach> I've tried static methods, not static methods,..., but nothing works :-( |
Help! I have the exactly the same problem! How to use bind in foreach. Thanks. |
See #575 |
harawata
added a commit
to harawata/mybatis-3
that referenced
this issue
Dec 17, 2022
Also related to mybatis#206 mybatis#575
harawata
added a commit
to harawata/mybatis-3
that referenced
this issue
Dec 17, 2022
…phase - Evaluated param values are stored in `ParameterMapping` and later used in DefaultParameterHandler - There is no change when processing RawSqlSource - Removed unused `injectionFilter` from TextSqlNode (mybatisgh-117) This should fix mybatis#2754 . This might also fix mybatis#206 and mybatis#575 , but with this patch, it still is not possible to invoke a method with parameter inside a parameter reference like `#{_parameter.mymethod(_parameter.value)}`. It might be possible to accept OGNL expression in a param reference (e.g. `#{${_parameter.mymethod(_parameter.value)}}`), but I'm not sure if that's a good idea.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In both the user guide (http://mybatis.github.io/mybatis-3/sqlmap-xml.html#Parameters) and the GitHub FAQ (https://github.com/mybatis/mybatis-3/wiki/FAQ), the
#{}
syntax and the${}
syntax are treated as being identical, with the exception that${}
performs a direct string substitution and#{}
inserts the value as a parameter to a prepared statement.However, in practice, the #{} syntax limits the expressions that can be used in unexpected ways.
First, the
#{}
syntax cannot retrieve a value from a map when any syntax other than map.key is used. This is the deal-breaker that first brought this issue to my attention. Given:This will work; however, none of the below will work:
Null is used to set the parameter in each case, despite each expression evaluating correctly if used with
${}
syntax instead.Additionally, functions may not be used in parameter bindings. Given an object mapWrapper with a method
name()
passed as a parameter:This results in an error. (Using
${}
syntax, obviously, does not.)Finally, attempting to use
<bind>
to overcome these limitations results in unexpected behavior. Consider the following:This works as expected, which is great. However, let's say we have a list of columns (name, title, favorite_cookie_variety), and a map of columns to values (name => "Bob", title => "Senior Cookie Tester", favorite_cookie_variety => "Mint Chocolate"). We want to include these columns and values in our WHERE clause, subject to some arbitrary criteria which we don't want to work out beforehand.
If you're familiar with the order in which MyBatis performs operations, you already see what's going to happen here. We re-bind "actualParameter" to a different value every iteration through the loop, but because parameter setting occurs after the script parsing has been completed, each parameter in the SQL query will be bound to the same value: the last value assigned to actualParameter.
While these examples may seem silly and contrived, I believe that the difference between
${}
syntax and#{}
syntax is unexpected and confusing. The available documentation does not describe or even hint at these limitations. Clarifying the documentation might be helpful, but I believe the usefulness of MyBatis will be enhanced by enabling users to leverage all the power available to them in${}
expressions in#{}
expressions as well.I would propose that the script driver be modified to parse
#{}
expressions as OGNL expressions the same as${}
expressions are. The result value could be stored in a new temporary variable, and that temporary variable be used in the parameter-setting stage.The text was updated successfully, but these errors were encountered: