|
|||||
|
|||||
Integrate IBatis With Legacy System
This article shows a real scenario where dimple helped a lot. BackgroundA legacy system uses a ConnectionManager class to manage connections: public class ConnectionManager { public static Connection checkOut(); public static void checkIn(Connection connection); } Client code is required to call ConnectionManager.checkIn(connection) to release a connection. To Integrate iBatisThings all work fine until an architect tries to bring in iBatis to handle persistence. The best way to integrate the legacy system with iBatis is to implement a javax.sql.DataSource and a com.ibatis.sqlmap.engine.datasource.DataSourceFactory. In order to implement DataSource, the Connection object checked out should be wrapped so that the "close" method calls ConnectionManager.checkIn(). Here goes pseudo code that does not compile: class LegacyConnection implements Connection { private boolean closed = false; private final Connection realConnection; public void close() { if(closed) return; ConnectionManager.checkIn(realConnection); closed = true; } public boolean isClosed() { return closed; } //All other methods delegate to realConnection. } class LegacyDataSource implements DataSource { public Connection getConnection() { return new LegacyConnection(ConnectionManager.checkOut()); } public PrintWriter getLogWriter() { return null;// do not support tracing } public int getLoginTimeout() { return 0; // do not support timeout } //All other methods throw UnsupportedOperationException } public class LegacyDataSourceFactory implements DataSourceFactory { public void initialize(Map props) {} public DataSource getDataSource() { return new LegacyDataSource(); } }
The ibatis config file can then be configured using the "transactionManager" as: <transactionManager type="JDBC"> <dataSource type="com.mycompany.mylegacysystem.LegacyDataSourceFactory"/> </transactionManager> However, obviously the pseudo code doesn't compile because the "All other methods" in Connection interface and DataSource interface need yet to be implemented. One could use the IDE's code generation support to "Generate Delegate Methods" for LegacyConnection and to "Implement/Override Methods" for LegacyDataSource. This technique works but has some serious drawbacks:
Dimple SolutionUsing dimple, we can be rid of versioning problem and deprecated method problem. The code will become: class LegacyConnection /*implements Connection*/ { private boolean closed = false; private final Connection realConnection; public void close() { if(closed) return; ConnectionManager.checkIn(realConnection); closed = true; } public boolean isClosed() { return closed; } } class LegacyDataSource /*implements DataSource*/ { public Connection getConnection() { Connection realConnection = ConnectionManager.checkOut(); return Implementor.proxy(Connection.class, new LegacyConnection(realConnection), realConnection); } public PrintWriter getLogWriter() { return null;// do not support tracing } public int getLoginTimeout() { return 0; // do not support timeout } } public class LegacyDataSourceFactory implements DataSourceFactory { public void initialize(Map props) {} public DataSource getDataSource() { return Implementor.proxy(DataSource.class, new LegacyDataSource()); } }
Created by benyu |
|||||
|
Copyright 2003-2006 - The Codehaus. All rights reserved unless otherwise noted.
Powered by Atlassian Confluence
|
|||||