Kilokahn
Kilokahn

Reputation: 2311

Mybatis spring transforming parameters

I wanted to know what is the best way to transform method params when using mybatis with spring integration. The reason for the transformation could be for various reasons - for e.g. inability of mybatis to handle java.util.Set as a param input.

Concretely, say I have a DAO interface method as :

List<Foo> getFooForUniqueIds(Set<Long> ids);

and the corresponding XML as:

<select id="getFooForUniqueIds" parameterType="java.util.Set" resultMap="foo">
    SELECT f.*
      FROM foo f
     WHERE f.id IN <foreach collection="list" item="item" separator="," close=")" open="(">
            #{item}
           </foreach>
</select>

I need a way to transform the Set<Long> ids into a List<Long> ids that the mybatis XML fragment can interpret. I understand that we can give a concrete class which deals with the SqlSessionFactory directly, but I like the abstraction that the Spring integration provides where I don't worry about non-interesting stuff like getting sessions and closing them.

One might also argue that DAO's should be dumb and probably the transformation should happen at the service layer. However, the transformation in this case was because of a nuance of the mapper framework and the service layer doing something to offset it seemed incorrect.

Open to suggestions and thanks in advance!

Upvotes: 1

Views: 2733

Answers (2)

Kilokahn
Kilokahn

Reputation: 2311

The specific example here could be solved by supplying a param name via @Param (rather than assuming it to be "list") and use that param name in the XML.

List<Foo> getFooForUniqueIds(@Param("set") Set<Long> ids);

with the XML as

<select id="getFooForUniqueIds" parameterType="java.util.Set" resultMap="foo">
SELECT f.*
  FROM foo f
 WHERE f.id IN <foreach collection="set" item="item" separator="," close=")" open="(">
        #{item}
       </foreach>
</select>

Reference: https://groups.google.com/forum/?fromgroups=#!topic/mybatis-user/BGjvVw1xx_c

Upvotes: 1

StrekoZ
StrekoZ

Reputation: 618

You can take a look at MyBatis typeHandlers. Create your own type handler and define it in your parameterMap - this can do a trick.

MyBatis accepts only List and Array types at foreach statement:

You can pass a List instance or an Array to MyBatis as a parameter object. When you do, MyBatis will automatically wrap it in a Map, and key it by name. List instances will be keyed to the name "list" and array instances will be keyed to the name "array".

Upvotes: 0

Related Questions