I recently had to do some iBatis SqlMap integration in a Spring project. It turned out not to be relevant after all, but I thought I'd share it in case anybody else could use it.
Basically, the problem was that I had to do some type conversion in code. For this, iBatis has the TypeHandler concept, where a handler can be registered on a specific Java type, and when this type is encountered in a SqlMap, the handler is called. Usually, the handlers are configured in the main SqlMap config file by referring to the class name in XML. However, in my case, the handlers had to be Spring-managed beans (they needed some beans to be injected), so the static configuration didn't work. The solution was to extend the SqlMapClientFactoryBean class to do some extra wiring:
-
public class SqlMapTemplateFactoryBean extends SqlMapClientFactoryBean {
-
-
private Map<String,TypeHandlerCallback> handlers;
-
-
@SuppressWarnings("deprecation")
-
@Override
-
public Object getObject() {
-
ExtendedSqlMapClient client = (ExtendedSqlMapClient) super.getObject();
-
if (handlers != null) {
-
for (Iterator<?> i = client.getDelegate().getResultMapNames(); i.hasNext(); ) {
-
String name = (String) i.next();
-
ResultMap map = client.getDelegate().getResultMap(name);
-
-
for (ResultMapping rm : map.getResultMappings()) {
-
if (rm.getJavaType() != null &&
-
handlers.containsKey(rm.getJavaType().getName())) {
-
rm.setTypeHandler(new CustomTypeHandler(handlers.get(rm.getJavaType().getName())));
-
}
-
}
-
}
-
}
-
return client;
-
}
-
-
@Override
-
public Class<SqlMapClientTemplate> getObjectType() {
-
return SqlMapClientTemplate.class;
-
}
-
-
public void setTypeHandlers(Map<String, TypeHandlerCallback> handlers) {
-
this.handlers = handlers;
-
}
-
}
This FactoryBean can then be used as a replacement for the regular SqlMapClientFactoryBean, and by setting the typeHandlers property, TypeHander instances can be injected:
-
<bean id="sqlmap" class="dk.test.SqlMapTemplateFactoryBean">
-
<property name="dataSource" ref="dataSource" />
-
<property name="configLocation" value="classpath:sqlmap.xml" />
-
<property name="typeHandlers">
-
<map>
-
<entry>
-
<key><value>dk.test.SomeVO</value></key>
-
<bean class="dk.test.SomeTypeHandler">
-
<property name="dao" ref="someDAO" />
-
</bean>
-
</entry>
-
</map>
-
</property>
-
</bean>



