iBatis Java Mapper is a new extension for iBatis and Spring which allows you to use Java classes and interfaces instead of XML for the object-SQL mapping. Basically, Java Mapper does for iBatis what JPA did for Hibernate. It is inspired by the idea of type safety as demonstrated in Guice , Seam and Spring 2.5+ , and the idea of convention over configuration as implemented in Google Web Toolkit .

iBatis Java Mapper is currently in early Alpha. The API may change and new features will be added according to the community feedback. Please use the forum to write suggestions, requests, bug report and general feedback.

Download iBatis Java Mapper

The current available features are:

Project roadmap (may change according to feedback):

How to use iBatis Java Mapper

This is a brief overview of the Java Mapper features. For further reference please read the manual .

iBatis Java Mapper's central class is JavaSqlMapClientFactoryBean, which extends and replaces Spring's SqlMapClientFactoryBean class. This new factory class can receive a collection of classes which contain object-SQL mappings. A typical Spring context XML configuration would look like this:

...

<bean id="sqlMapClient" class="net.sf.javamapper.factory.JavaSqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:sql-map-config.xml" />
        <property name="dataSource" ref="dataSource" />
        <property name="mapperClasses">
                <list>
                        <value>net.sf.javamapper.jpetstore.dao.ibatis.mapperclasses.AccountMapper</value>
                </list>
        </property>
</bean>

...

Each class in the mappedClasses collection is scanned for mapping annotations. Here is an example of the same select statement mapping with iBatis XML mapping and with Java Mapper:

iBatis XML mapping:

<select id="getUsernameList" resultClass="java.lang.String">
        select username as value from signon
</select>

Java Mapper:

@Select("select username as value from signon")
public abstract String getUsernameList();

The statement ID is the same as the method name and the result class is the same as the method return type. The mapping of insert, update and delete statements is similar.

It is also possible to use a class or an interface to define a result map. To do that we mark a class with the @ResultMap annotation and its getter methods with the @Result annotation. It is possible to use the actual domain classes/interfaces as mappers of themselves, to map subclasses/subinterfaces of the domain or to map classes/interfaces which are unrelated to the domain but have the same getter methods. The last option is not recommended because unlike the first two options there is no compile-time guarantee that the mapped properties really exist on the domain classes. Here is an example of a result map definition with iBatis XML mapping and with Java Mapper using a subclass of a domain class:

iBatis XML mapping:

<resultMap id="result" class="org.springframework.samples.jpetstore.domain.Account">
        <result property="username" column="userid"/>
        <result property="email" column="email"/>
</resulrMap>

Java Mapper:

@ResultMap(resultClass=Account.class)
public abstract class AccountMapper extends Account { 

        @Override
        @Result(column="userid")
        public abstract String getUsername();
        
        @Override
        @Result(column="email")
        public abstract String getEmail();
}