How to apply a method to a parameter in MyBatis - db2

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.

Related

MyBatis XML access to incoming array without casting from string

In below code I get PgArray as an array of PrimaryKeys to template table, from another select query (<collection ... select='selectTemplate'/>). But the solution below seems like a little messy way of doing it. isn't there a way to access the array directly, so I wouldn't need to cast?
Hint: Having #{_parameter} doesn't work.
<select id="selectTemplate" parameterType="org.postgresql.jdbc.PgArray" resultMap="templateResultMap">
SELECT *
FROM template
WHERE template.id = ANY ('${_parameter}'::int[])
</select>

MyBatis: How to map underscore result to camelcase for one specific statement only?

I have a statement in the mybatis mapper.xml file:
<select id="queryCorpAndDept" parameterType="java.util.HashMap" resultType="java.util.HashMap">
SELECT ORGAN_NAME, ORGAN_ID FROM PUB_ORGAN
</select>
The statement above will return a list of HashMap. The keys of the hashmap will be ORGAN_NAME, ORGAN_ID. I know MyBatis has a setting named mapUnderscoreToCamelCase to map undercase to camelcase.
But is there another way to map underscore to camelcase without defining a JAVA Bean ?
Sorry for my english.
You can use column aliases to be able to do selective camelCasing as shown below:
<select id="queryCorpAndDept" parameterType="java.util.HashMap"
resultType="java.util.HashMap">
SELECT ORGAN_NAME "organName", ORGAN_ID "organId" FROM PUB_ORGAN
</select>

Symfony2 Field Type Guessing: When is <textarea> chosen (over <input type="text">)?

Not declaring the field type brings the advantage that Symfony infers the required and maxlength attribute from validation rules, as explained here: http://symfony.com/doc/current/book/forms.html#field-type-options-guessing
However, I can't find a way to make Symfony 2.8.2 "guess" a <textarea> instead of an <input type="text"> :-(
My first idea was to increase the allowed length, but even with Length: max: 100000 in validation.yml, Symfony is unimpressed and just gives me <input type="text" maxlength="100000" />.
EDIT: #chalasr: I'm talking about an entity which is not mapped to the database. Sorry for not mentioning that earlier!
The FormBuilder guesses the field type by checking the type in the mapping of the corresponding property, in the entity.
Use text instead of string as type of your column mapping, and the FormBuilder will use a textarea instead of an input.
Example :
/**
* #ORM\Column(type="text")
*/
protected $field;
Output with $builder->add('field'); :
<textarea id="entity_field" name="entity[field]" required="required"></textarea>
For more info look at the Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser.
Update
So, you don't use a mapped class.
Look at the FormBuilder, as you can see, if there is no corresponding Guesser found, the form type will be a TextType (input text).
Otherwise, there is 3 different Guesser:
FormTypeGuesserChain
DoctrineORMTypeGuesser
ValidatorTypeGuesser
Because your class is not mapped, Symfony will use the ValidatorTypeGuesser to guess the type of your field.
This Guesser looks for constraints in your class.
For example, if your field has a Type constraint with type integer, the NumberType will be used and an input type number will be rendered.
My first idea was to use a Length constraint with a big min-length.
But, after many tries and looks in classes, it seems the TextareaType is never guessed, unless your class is mapped and your field has text as type (DoctrineTypeGuesser is used) .
So, without a mapped class, Symfony cannot create a textarea from type guessing.
For more informations look at the ValidatorTypeGuesser::guessTypeForConstraint.
See also the Form Type Guessing chapter of documentation, it shows how create your own TypeGuesser with a good example.

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>

Get the last element in list with helper

I am passing a list to my scala page and I have a form and I would like to set some default values to the last element in the list: Something like the below:
System Name: <input type="text" id="systemSourceName" name="systemSourceName" value="#configs[#configs.size() - 1].systemSourceName" >
But it throws an error at the second #:
identifier expected but '#' found.
Is there a way I can do this?
Use round brackets, square brackets are for type parameters
There is no need for second #, parser knows that he is already inside scala expression.
It is better to use built-in method of List class:
value="#configs.last.systemSourceName"
Scala doesn't access list elements via list[index] but via list(index).
So the following should work:
value="#configs(configs.size - 1).systemSourceName"
An easier solution would be
value="#configs.last.systemSourceName"