Montag, 28. Mai 2012

What's new in mybatis 3.1

The latest mybatis release 3.1.1 brings a lot of cool new features and important bug fixes. I'd like to point out some of the most interesting ones which I have personally been looking forward to:

Multi DB vendor support

You can now write different versions of the same query for multiple database vendors. Thus you no longer need to change all the code when a new database is to be used. To do so you just write several mapper statements of the same name, but with different "databaseId" attribute. You can also configure the way in which mybatis finds out which database it is currently talking to by registering your own DataBaseIdProvider. 
This only works for XML-based mappers, though.

Auto discovery

Mybatis can now automatically search packages not only for mappers, but also for type handlers and type aliases. This is especially useful in component based applications where each component wants to add its own type handlers. With auto discovery you no longer have to make a specialized database module for each component. Instead you just make a convention to put all type handlers in a certain package.
Type aliases are marked by the @Alias annotation. Type handlers are marked by @MappedTypes

Reduced scope of local session cache

The local session cache is used to avoid loops in nested selects. But it can also lead to subtle bugs where it returns instances which have changed in the meantime. To get around this, its scope can now be reduced to "per statement" in the configuration. This should be a no-brainer option for most projects!

Support for Oracle generated keys

Oracle likes to be different from everyone else for no good reason. It seems to be the only vendor that does not properly support JDBC3 auto generated keys. Mybatis is now able to work around this by querying generated keys by row index. Querying them by column name does not work on Oracle return resultsets. All you need to do is to specify the name of the key column and mybatis will figure out the index.

Generic return types

Annotation based mappers can now return generic types like Map<String, Object>, reducing the need for casting and compiler warnings in client code. Also, mybatis now supports not only List and Map, but different kinds of Sets and Arrays as return types.

Improved performance

The handling of resultsets has been improved and will now cache things like column names, property mappings and type handlers. This is a very noticeable change on large result sets like the ones I'm used to in my current project (between 60K and 1M rows).

What I'm still missing

ResultHandlers on annotation mappers

I'd really love to be able to use result handlers with annotation based mappers. Currently this is not possible as mybatis has no way of telling the correct type to be instantiated. This is because the method return type has to be void when using a ResultHandler. 
To fix this, either the ResultHandler interface would need to be generic or a new return type annotation would be necessary. I would prefer the former as then I would also no longer need to cast the result object to the correct type.

Compound Types

Compound types are types where several database columns are mapped onto a single Java property. Take for instance a financial transaction which contains a Money object that consists of an amount and a currency. In order to make the database searchable it would be a good idea to store amount and currency in different columns. But on the java side, I would want to have them combined into one object.