2

Is there some way to check if a property in include fragment has been set? Example:

<include refid="myFilterLocation">
  <property name="model" value="model_name"/>
  ...
  ...
  ...
</include>

And then when this fragment is used:

<if test="....">
 AND ${model}= #{${param}.model,jdbcType=VARCHAR}
</if>

Is there some way to test if the property is not sent?. I want not send properties if I do not want to filter in my query.

Kind regards.

quark
  • 23
  • 5
  • You should avoid injection parameters `${param}` as much as you can. These can be vulnerable to SQL Injection. Use normal parameters `#{param}` by default. Resort to injection parameters only in very special cases. – The Impaler May 21 '20 at 15:51
  • param is another include property, its value depends on how I extract a register. Ex: “c.model” where c is the alias for table “car” for example. – quark May 21 '20 at 18:56

2 Answers2

1

When the property is not defined, ${model} is not replaced at all, so you may be able to write the condition as follows.

<if test='"${model}" != "\${model}"'>
  AND ${model}= #{${param}.model,jdbcType=VARCHAR}
</if>

Note the unusual usage of single/double quotes and the backslash before the second dollar sign.

(Longer explanation)

There are two variables ${model} in the test attribute value, however the second one is escaped using a leading backslash.
So, when the 'model' property is specified, the included if element will look as follows.

<if test='"model_name" != "${model}"'>

The condition is a simple two strings comparison and the result is true.
Note that the backslash used to escape the variable is removed (that's how MyBatis' variable escaping works).

Now, when the 'model' property is not specified, the variable is not replaced, so the if element looks as follows after the inclusion.

<if test='"${model}" != "${model}"'>

As you can see, the two strings are the same and the result of the condition is false.

And OGNL requires double quotes for string literal.
If you use single quotes, NumberFormatException may be thrown (OGNL recognizes it as a char, it seems).

ave
  • 3,244
  • 2
  • 14
  • 20
  • @quark Added a longer explanation. :) – ave Jun 02 '20 at 10:49
  • ooh, thank you, in fact is very simple, known that "\" scapes. – quark Jun 04 '20 at 17:01
  • I tried this but even though I can get the value of ${model} and use it inside my query, somehow the doesn't work – sikidhart Jun 18 '20 at 07:08
  • @sikidhart Then it may be a different problem. This Q&A is about `` specified inside ``, not the usual `${}` referencing runtime parameter. – ave Jun 18 '20 at 09:51
0

You can check if a parameter is not null using:

<if test="param != null">
  ...
</if>
The Impaler
  • 45,731
  • 9
  • 39
  • 76
  • That I want to test is if property named “model” is set. I want to avoid define properties that I do not want to use. That’s to say, I wold test something like but this does not work if property model is not defined. – quark May 21 '20 at 18:45
  • @quark I am not sure but I think you cannot identify if the parameter has been set or not in an include (I may be wrong). Since your question is highly specialized I would go to the root team and participate in the mailing list mybatis-user@googlegroups.com. Great minds will answer you there. – The Impaler May 21 '20 at 19:23