Checking property existence of include fragment in MyBatis - mybatis

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.

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).

You can check if a parameter is not null using:
<if test="param != null">
...
</if>

Related

Pause interpolation of template string in FTL

I want to pass a dynamic string to FTL Macro. But I don't want the template string to be interpolated when I am calling the macro from FTL. I want the template string to be interpolated inside Macro only. So that I can make the Macro reusable by sending dynamic Template strings as parameter. As I am new to Apache FTL so I don't have much idea how to proceed.
Not sure what do you want to achieve, but I guess something like this:
<#macro m s>
<#local parsedS = s?interpret>
<#list ['John Doe', 'Jane Doe'] as name>
<p><#parsedS />
</#list>
</#macro>
<#m r"Hello ${name}!" />
which will print:
<p>Hello John Doe!
<p>Hello Jane Doe!
Some notes:
I haven't just used the parameter as a string with an interpolation,
but as an template fragment (so that auto-escaping, if you use it,
will be applied, also you could use #if and such in the value of
s).
As the template fragment is evaluated for multiple types in my
example, I have assigned the result of ?interpret to a local
variable, otherwise you could just write <#s?interpret />.
As of
the r before the string literal, that tells FreeMarker that ${}
(and \ escapes) must not be interpreted.

How to remove leading zero from string in SAPUI5 applications in XML view?

I have an integer number in SAPDB but it has to be store as NUMERIC for some reason and numeric values are stored as string in SAP DB.
Thus OData service returns 0000000001 instead of 1.
SO the question is how can I remove leading zero in XML View. The problem is that I can not use Javascript for formatting when I use XML View.
The only solution that I found is to use a code like this:
<Text text="{path:'ZId', type:'sap.ui.model.odata.type.ODataType', oConstraints:{isDigitSequence: true}}" />
But I don't know why it does not remove the leading zeros while it has been said in its references:
if true, the value is handled as a sequence of digits; while formatting leading zeros are removed from the value and while parsing the value is enhanced with leading zeros (if a maxLength constraint is given) or leading zeros are removed from the value (if no maxLength constraint is given); this constraint is supported since 1.35.0. To make this type behave as ABAP type NUMC, use oConstraints.isDigitSequence=true together with oConstraints.maxLength.
The references that I found some related data were in the following links:
https://archive.sap.com/discussions/thread/3681816
https://openui5.hana.ondemand.com/docs/api/symbols/sap.ui.model.odata.type.String.html
https://openui5.hana.ondemand.com/docs/api/symbols/sap.ui.model.type.Integer.html
https://openui5.hana.ondemand.com/docs/api/symbols/sap.ui.core.format.NumberFormat.html
You are neither using the correct type implementation nor the correct binding syntax for setting the constraints. Please check the documentation:
<Text text="{
path : 'ZId',
type : 'sap.ui.model.odata.type.String',
constraints: {
isDigitSequence : true,
maxLength : 10
}
}"/>
Try this code for leading the zeros:
<ObjectNumber number="{= parseFloat(${ZId}) }"/>
or
<Text text="{= parseFloat(${ZId}) }"/>

Alias in OGNL inside MyBatis

I'm programming with MyBatis and I have this code
<if test="#mypackage.verylongname.utilities.MyBatisUtilities#isNotEmpty(recipient)">
and DOCUMENTS.recipient = #{recipient}
</if>
I'd like to have a way to avoid to use the full pathname of my class MyBatisUtilities. Is it there?
Adding an Alias to the mybatis-config file doesn't work
<typeAlias alias="MyBatisUtilities" type="mypackage.verylongname.utilities.MyBatisUtilities"/>
Don't think there is a way no, not unless mybatis provides some special extended functionality for OGNL.
That doesn't mean it ~couldn't~ be done within OGNL somehow with changes to the core library, just don't believe it does currently. (my memory may be bad, but pretty certain #fullclassname#methodname is the only way OGNL knows of to resolve static method invocations)
"bind" lets you make a variable out of an OGNL expression. For more info see : http://mybatis.github.io/mybatis-3/dynamic-sql.html
<select id="selectBlogsLike" parameterType="Blog" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>

Check if property has been set in phing

How to check if property ${foo} has been set?
Bonus question: how to escape $ sign in <echo> so I could output ${foo} string (not the foo variable substitution)?
PS: tried to google and read documentation, but couldn't find the answers. It's likely I'm missing something
You need to place an isset element inside the if element.
<if>
<isset property="foo" />
The manual is available here.
If you just need to fail the build if a property is defined or not, check out the fail task:
http://www.phing.info/docs/guide/stable/FailTask.html

How to apply a method to a parameter in MyBatis

After reading about Mapper XMLs I can't help to wonder how one might go about appling some common transforms to a parameter. For example...
<select id="selectPerson" parameterType="String" resultType="hashmap">
<!-- #{name} should always be upper case and have a trailing % -->
SELECT * FROM PERSON WHERE FIRST_NAME like #{name}
</select>
After reading this and this I can make some observations.
Using SQL functions such as upper or concat or '||' or '+' to do transforms kills performance in DB2
I could always wrap the the mapper or expose the details in the service layer but that seems messy
What I want is to be able to do something like...
<select id="selectPerson" parameterType="String" resultType="hashmap">
<!-- #{name} should always be upper case and have a trailing % -->
SELECT * FROM PERSON WHERE FIRST_NAME like #{name.upperCase() + '%'}
</select>
Is something like this possible or what is the second best solution?
Update: it appears that MyBatis uses OGNL for some expression evaluation. For example, if and ${} expressions use OGNL but #{} does NOT appear to unless there is some way to trick it.
Bind
MyBatis allows for creating values from method and properties in the context using <bind/>.
Bind creates a new variable in the scope of the current statement. The OGNL statement that binds the value can use the passed in _parameter object to compute a new bound value that can then used by MyBatis to construct the prepared statement.
Example
Your example using bind:
<select id="selectPerson" parameterType="String" resultType="hashmap">
<!-- #{name} should always be upper case and have a trailing % -->
<bind name="nameStartsWith" value="_parameter.getName().upperCase() + '%'"/>
SELECT * FROM PERSON WHERE FIRST_NAME like #{nameStartsWith}
</select>
Source
MyBatis Dynamic SQL Documentation
I ran through the same problem too. But I didn't find any solution for this. So I had to preprocess the #{name} parameter from the calling function.