emacarron / mybatis

Automatically exported from code.google.com/p/mybatis
0 stars 0 forks source link

Problem with String substitution and multiple parameters #71

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What version of the MyBatis are you using?

3.0.1

Please describe the problem.  Unit tests are best!

If I have a mapper function with multiple parameters e.g. 
selectObject(String val1, String Val2) 
Declaring the sqlmap parameter as hashmap and referencing the 
parameters in the sql as #{0} and #{1} works OK. However If I try to 
reference the parameters as ${0} or ${1} I get 0 and 1 substituted 
instead of the actual parameter values.

Also, there is an error in the documentation regarding parameters. On 
page 56 it says: 

You can pass multiple parameters to a mapper method. If you do, they 
will be named by their position in the parameter list by default, for 
example: #{1}, #{2} etc 

This is misleading as the parameters are actually #{0}, #{1} etc

Original issue reported on code.google.com by pstockl...@gmail.com on 23 Jul 2010 at 2:59

GoogleCodeExporter commented 9 years ago
Any chance of getting a fix for this? 

Original comment by pstockl...@gmail.com on 7 Sep 2010 at 9:22

GoogleCodeExporter commented 9 years ago
I did some digging into this one.  The problem lies in OGNL - MyBatis uses OGNL 
to do these string substitutions and OGNL assumes that 0, 1, 2, etc. are 
constants - not property names.

So this is not trivial to fix.  I think that we will not support this because 
we don't want to mess with OGNL too much and there is a relatively simple 
workaround (name the parameters).

Original comment by jeffgbut...@gmail.com on 30 Dec 2010 at 12:28

GoogleCodeExporter commented 9 years ago
And why not name the parameters with names like param0, param1, instead of 
0,1,etc...
It is clearly a showstopper to force the usage of annotations to name the 
parameters.

Original comment by pnav...@gmail.com on 7 Dec 2011 at 8:03

GoogleCodeExporter commented 9 years ago
It is even not necessary to descend to OGNL level, simply changing a single 
line in the method setupMethodSignature() of MapperMethod.java works for me: 

String paramName = "param" + String.valueOf(paramPositions.size());

Obviously after this change, the parameters are named param0, param1, and so 
on...

I attach the patched file.

Original comment by pnav...@gmail.com on 7 Dec 2011 at 10:23

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
What about this? We may register params like param1, param2 and so on:

String paramName = "param" + String.valueOf(paramPositions.size() + 1);

And also add them with their cardinal position 0, 1... for backward 
compatibility

Map<String, Object> param = new HashMap<String, Object>();
for (int i = 0; i < paramCount; i++) {
  param.put(paramNames.get(i), args[paramPositions.get(i)]);
  param.put(String.valueOf(i), args[paramPositions.get(i)]); // compatibility with 3.0.x (issue #71)
}
return param;

All test pass and it does not look a risky change.

Jeff, are you fine with this?

Original comment by eduardo.macarron on 13 Jan 2012 at 6:01

GoogleCodeExporter commented 9 years ago
I think this is a good idea.

Original comment by jeffgbut...@gmail.com on 13 Jan 2012 at 12:35

GoogleCodeExporter commented 9 years ago
Ok! I will write a test for it and commit the change this weekend.

Original comment by eduardo.macarron on 13 Jan 2012 at 1:16

GoogleCodeExporter commented 9 years ago
Change applied in r4560.

Param names are param1, param2...

If anyone prefer param0, param1 please say it after 3.1.0 release!! :)

Original comment by eduardo.macarron on 13 Jan 2012 at 5:38

GoogleCodeExporter commented 9 years ago

Original comment by eduardo.macarron on 13 Jan 2012 at 5:38

GoogleCodeExporter commented 9 years ago

Original comment by eduardo.macarron on 5 Feb 2012 at 6:56