实现ibatis的动态加载sqlmap配置文件
2010-11-07 19:04
791 查看
有人反馈SqlMapParserFactory不可视,自己看看ibatis或者spring的源代码,具体是哪个忘记了,这个类不是public的,自己改成public的就可以了,欢迎访问chenwenxuan.com
原创文章,转帖请注明出处:
http://blog.csdn.net/palm_civet/archive/2010/11/07/5993613.aspx
ibatis在开发的时候每次修改都需要重启应用服务器,所以一直想做一下ibatis的动态加载,加快开发速度。这里是基于2.3.4.726版本做的。
网上搜了一下,发现这个需求看是蛮多的。但是ibatis一直没有提供相应的api,分析了下源代码,有以下几个原因:
1. 同步问题。
ibatis内部保存sql使用的hashMap,并没有使用java5中的新类。此外,在ibatis的解析代码中还发现ibatis中的解析器对于一个sqlMapClient是不变的,同时在解析的时候引用了一个表示状态的变量,这个变量在并发解析的时候会存在同步问题。
2. sql引用的问题。这个比较复杂,各种引用关系如何处理在ibatis中如何处理都没有涉及。
通过以上分析,可以看出ibatis的作者根本没有考虑过动态加载的问题。做一个完全动态的ibatis看来是比较困难的。做一个用于开发使用的ibatis,在开发环境上使用还是可行的。
实现的大体思路是:
当用户使用sqlMapClient调用方法访问数据库的时候判断一下相应的配置文件是否已经改变,如果已经改变,那么就重新解析一遍,并且加载到sqlMap中
公司的项目使用的是spring和ibatis,结合这几个情况,我们需要实现几个类,并使用反射替换ibatis中的一些实现,完成动态加载
1. 继承spring的SqlMapClientFactoryBean,加载sqlMap。
2. 继承ibatis中的SqlMapClientImpl,对用户的访问请求作控制。
3. 继承ibatis中的SqlMapExecutorDelegate,目的同上。
4. 继承ibatis中的SqlMapParser,目的同上。发现ibatis在判读重复的sql的逻辑没有写在一个地方,所以不得不实现这个类了。
具体实现:
DySqlMapClientFactoryBean.java,用于spring加载ibatis,大部分代码都是spring的
DySqlMapClient.java,一个代理类
DySqlMapExecutorDelegate.java,最重要的实际处理的类
DySqlMapParser.java,重置处理sql节点的方法
补充一个漏掉的类
读取sqlmap文件的类
原创文章,转帖请注明出处:
http://blog.csdn.net/palm_civet/archive/2010/11/07/5993613.aspx
ibatis在开发的时候每次修改都需要重启应用服务器,所以一直想做一下ibatis的动态加载,加快开发速度。这里是基于2.3.4.726版本做的。
网上搜了一下,发现这个需求看是蛮多的。但是ibatis一直没有提供相应的api,分析了下源代码,有以下几个原因:
1. 同步问题。
ibatis内部保存sql使用的hashMap,并没有使用java5中的新类。此外,在ibatis的解析代码中还发现ibatis中的解析器对于一个sqlMapClient是不变的,同时在解析的时候引用了一个表示状态的变量,这个变量在并发解析的时候会存在同步问题。
2. sql引用的问题。这个比较复杂,各种引用关系如何处理在ibatis中如何处理都没有涉及。
通过以上分析,可以看出ibatis的作者根本没有考虑过动态加载的问题。做一个完全动态的ibatis看来是比较困难的。做一个用于开发使用的ibatis,在开发环境上使用还是可行的。
实现的大体思路是:
当用户使用sqlMapClient调用方法访问数据库的时候判断一下相应的配置文件是否已经改变,如果已经改变,那么就重新解析一遍,并且加载到sqlMap中
公司的项目使用的是spring和ibatis,结合这几个情况,我们需要实现几个类,并使用反射替换ibatis中的一些实现,完成动态加载
1. 继承spring的SqlMapClientFactoryBean,加载sqlMap。
2. 继承ibatis中的SqlMapClientImpl,对用户的访问请求作控制。
3. 继承ibatis中的SqlMapExecutorDelegate,目的同上。
4. 继承ibatis中的SqlMapParser,目的同上。发现ibatis在判读重复的sql的逻辑没有写在一个地方,所以不得不实现这个类了。
具体实现:
DySqlMapClientFactoryBean.java,用于spring加载ibatis,大部分代码都是spring的
package test.develop.ibatis; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.springframework.core.NestedIOException; import org.springframework.core.io.Resource; import org.springframework.orm.ibatis.SqlMapClientFactoryBean; import org.springframework.util.ObjectUtils; import com.ibatis.common.xml.NodeletException; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser; import com.ibatis.sqlmap.engine.builder.xml.SqlMapParser; public class DySqlMapClientFactoryBean extends SqlMapClientFactoryBean { private List<Resource> resourceList = new ArrayList<Resource>(); private SqlMapParser mapParser = null; public DySqlMapClientFactoryBean() { super(); } @Override public void setConfigLocation(Resource configLocation) { super.setConfigLocation(configLocation); if (configLocation != null && !resourceList.contains(configLocation)) { resourceList.add(configLocation); } } @Override public void setConfigLocations(Resource[] configLocations) { super.setConfigLocations(configLocations); for (int i = 0; i < configLocations.length; i++) { if (configLocations[i] != null && !resourceList.contains(configLocations[i])) { resourceList.add(configLocations[i]); } } } @Override protected SqlMapClient buildSqlMapClient(Resource[] configLocations, Resource[] mappingLocations, Properties properties) throws IOException { if (ObjectUtils.isEmpty(configLocations)) { throw new IllegalArgumentException( "At least 1 'configLocation' entry is required"); } SqlMapClient client = null; SqlMapConfigParser configParser = new SqlMapConfigParser(); for (int i = 0; i < configLocations.length; i++) { InputStream is = configLocations[i].getInputStream(); try { client = configParser.parse(is, properties); } catch (RuntimeException ex) { throw new NestedIOException("Failed to parse config resource: " + configLocations[i], ex.getCause()); } } mapParser = SqlMapParserFactory.createSqlMapParser(configParser); client = new DySqlMapClient(client, mapParser,configParser,configLocations); return client; } }
DySqlMapClient.java,一个代理类
package test.develop.ibatis; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.springframework.core.io.Resource; import test.develop.FileDesc; import com.ibatis.common.xml.NodeletException; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser; import com.ibatis.sqlmap.engine.builder.xml.SqlMapParser; import com.ibatis.sqlmap.engine.builder.xml.XmlParserState; import com.ibatis.sqlmap.engine.config.SqlMapConfiguration; import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient; import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl; import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate; public class DySqlMapClient extends SqlMapClientImpl { private SqlMapClient client = null; private SqlMapParser mapParser = null; private SqlMapConfigParser configParser = null; private Resource[] configLocations = null; private List <FileDesc> descList = null; private DySqlMapExecutorDelegate myDelegate = null; private Map<String, FileDesc> statementMap = null; private Map<FileDesc, List<String>> fileStatementMap = null; private DySqlMapClient(SqlMapExecutorDelegate delegate) { super(delegate); } public DySqlMapClient(SqlMapClient client, SqlMapParser mapParser, SqlMapConfigParser configParser, Resource[] configLocations) { super(new DySqlMapExecutorDelegate(((ExtendedSqlMapClient)client).getDelegate())); this.myDelegate = (DySqlMapExecutorDelegate) this.delegate; this.myDelegate.setClient(this); this.client = client; this.mapParser = mapParser; this.configParser = configParser; this.configLocations = configLocations; initFileDescList(); initStatementMap(); initState(); } public FileDesc getFileDescUseId(String id) { FileDesc fd = statementMap.get(id); return fd; } public void refreshFileDesc(String id, long tm) { FileDesc fd = getFileDescUseId(id); fd.setTm(tm); } public void reParseSqlMap(InputStream is) { try { this.mapParser.parse(is); is.close(); } catch (IOException e) { e.printStackTrace(); } catch (NodeletException e) { e.printStackTrace(); } } public void initState() { try { Field f = this.configParser.getClass().getDeclaredField("state"); f.setAccessible(true); XmlParserState state = (XmlParserState) f.get(this.configParser); Field configFiled = state.getClass().getDeclaredField("config"); configFiled.setAccessible(true); SqlMapConfiguration impl = (SqlMapConfiguration) configFiled.get(state); Field clientField = impl.getClass().getDeclaredField("client"); clientField.setAccessible(true); clientField.set(impl, this); Field delegateField = impl.getClass().getDeclaredField("delegate"); delegateField.setAccessible(true); delegateField.set(impl, this.myDelegate); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void initFileDescList() { descList = new ArrayList<FileDesc>(); for ( int i = 0; i < configLocations.length; i++) { try { String path = configLocations[i].getFile().getAbsolutePath(); descList.addAll(SqlMapConfigUtils.readSqlMapFileMapping(path)); } catch (IOException e) {} } } private void initStatementMap() { this.statementMap = new HashMap<String, FileDesc>(); this.fileStatementMap = new HashMap<FileDesc, List<String>>(); for ( Iterator <FileDesc> it = descList.listIterator(); it.hasNext(); ) { FileDesc desc = it.next(); List <String> list = SqlMapConfigUtils.readSqlMap(desc); for ( Iterator <String> i = list.listIterator(); i.hasNext(); ) { String id = i.next(); statementMap.put(id, desc); } this.fileStatementMap.put(desc, list); } } /*@Override public void flushDataCache() { this.client.flushDataCache(); } @Override public void flushDataCache(String cacheId) { this.client.flushDataCache(cacheId); } @Override public SqlMapSession getSession() { return this.client.getSession(); } @Override public SqlMapSession openSession() { return this.client.openSession(); } @Override public SqlMapSession openSession(Connection conn) { return this.client.openSession(conn); } @Override public int delete(String id) throws SQLException { return this.client.delete(id); } @Override public int delete(String id, Object parameterObject) throws SQLException { return this.client.delete(id, parameterObject); } @Override public int executeBatch() throws SQLException { return this.client.executeBatch(); } @Override public List executeBatchDetailed() throws SQLException, BatchException { return this.client.executeBatchDetailed(); } @Override public Object insert(String id) throws SQLException { return this.client.insert(id); } @Override public Object insert(String id, Object parameterObject) throws SQLException { return this.insert(id, parameterObject); } @Override public List queryForList(String id) throws SQLException { return this.client.queryForList(id); } @Override public List queryForList(String id, Object parameterObject) throws SQLException { return this.client.queryForList(id, parameterObject); } @Override public List queryForList(String id, int skip, int max) throws SQLException { return this.client.queryForList(id, skip, max); } @Override public List queryForList(String id, Object parameterObject, int skip, int max) throws SQLException { return this.client.queryForList(id, parameterObject, skip, max); } @Override public Map queryForMap(String id, Object parameterObject, String keyProp) throws SQLException { return this.client.queryForMap(id, parameterObject, keyProp); } @Override public Map queryForMap(String id, Object parameterObject, String keyProp, String valueProp) throws SQLException { return this.client.queryForMap(id, parameterObject, keyProp, valueProp); } @Override public Object queryForObject(String id) throws SQLException { return this.client.queryForObject(id); } @Override public Object queryForObject(String id, Object parameterObject) throws SQLException { return this.client.queryForObject(id, parameterObject); } @Override public Object queryForObject(String id, Object parameterObject, Object resultObject) throws SQLException { return this.client.queryForObject(id, parameterObject, resultObject); } @Override public PaginatedList queryForPaginatedList(String id, int pageSize) throws SQLException { return this.client.queryForPaginatedList(id, pageSize); } @Override public PaginatedList queryForPaginatedList(String id, Object parameterObject, int pageSize) throws SQLException { return this.client.queryForPaginatedList(id, parameterObject, pageSize); } @Override public void queryWithRowHandler(String id, RowHandler rowHandler) throws SQLException { this.client.queryWithRowHandler(id, rowHandler); } @Override public void queryWithRowHandler(String id, Object parameterObject, RowHandler rowHandler) throws SQLException { this.client.queryWithRowHandler(id, parameterObject, rowHandler); } @Override public void startBatch() throws SQLException { this.client.startBatch(); } @Override public int update(String id) throws SQLException { return this.client.update(id); } @Override public int update(String id, Object parameterObject) throws SQLException { return this.client.update(id, parameterObject); } @Override public void commitTransaction() throws SQLException { this.client.commitTransaction(); } @Override public void endTransaction() throws SQLException { this.client.endTransaction(); } @Override public Connection getCurrentConnection() throws SQLException { return this.client.getCurrentConnection(); } @Override public DataSource getDataSource() { return this.client.getDataSource(); } @Override public Connection getUserConnection() throws SQLException { return this.client.getUserConnection(); } @Override public void setUserConnection(Connection connnection) throws SQLException { this.client.setUserConnection(connnection); } @Override public void startTransaction() throws SQLException { this.client.startTransaction(); } @Override public void startTransaction(int transactionIsolation) throws SQLException { this.client.startTransaction(transactionIsolation); }*/ }
DySqlMapExecutorDelegate.java,最重要的实际处理的类
package test.develop.ibatis; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sql.DataSource; import test.develop.FileDesc; import com.ibatis.common.util.PaginatedList; import com.ibatis.sqlmap.client.SqlMapException; import com.ibatis.sqlmap.client.event.RowHandler; import com.ibatis.sqlmap.engine.cache.CacheModel; import com.ibatis.sqlmap.engine.exchange.DataExchangeFactory; import com.ibatis.sqlmap.engine.execution.BatchException; import com.ibatis.sqlmap.engine.execution.SqlExecutor; import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate; import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap; import com.ibatis.sqlmap.engine.mapping.result.ResultMap; import com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactory; import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement; import com.ibatis.sqlmap.engine.scope.SessionScope; import com.ibatis.sqlmap.engine.scope.StatementScope; import com.ibatis.sqlmap.engine.transaction.Transaction; import com.ibatis.sqlmap.engine.transaction.TransactionManager; import com.ibatis.sqlmap.engine.type.TypeHandlerFactory; @SuppressWarnings("deprecation") public class DySqlMapExecutorDelegate extends SqlMapExecutorDelegate { private SqlMapExecutorDelegate delegate = null; private DySqlMapClient client = null; public void setClient(DySqlMapClient client) { this.client = client; } public DySqlMapExecutorDelegate(SqlMapExecutorDelegate delegate) { super(); this.delegate = delegate; } protected void checkAndRefreshSqlMap(String id) { FileDesc fd = client.getFileDescUseId(id); if ( fd == null ) { return; } String path = fd.getPath(); File file = new File(path); if ( file.lastModified() > fd.getTm() ) { try { InputStream is = new FileInputStream(file); client.reParseSqlMap(is); client.refreshFileDesc(id, file.lastModified()); System.out.println(file.getName() + " has been reloaded"); } catch (FileNotFoundException e) { System.out.println(file.getName() + " reload failed! " + e.getMessage()); } } } @Override public void addCacheModel(CacheModel model) { this.delegate.addCacheModel(model); } @Override public void addMappedStatement(MappedStatement ms) { try { this.delegate.getMappedStatement(ms.getId()); Field f = this.delegate.getClass().getDeclaredField("mappedStatements"); f.setAccessible(true); Map map = (Map)f.get(this.delegate); if ( map.containsKey(ms.getId())) { map.remove(ms.getId()); } } catch (SqlMapException ignore) { } catch (Exception e) {} this.delegate.addMappedStatement(ms); } @Override public void addParameterMap(ParameterMap map) { this.delegate.addParameterMap(map); } @Override public void addResultMap(ResultMap map) { this.delegate.addResultMap(map); } @Override protected void autoCommitTransaction(SessionScope sessionScope, boolean autoStart) throws SQLException { try { Method m = this.delegate.getClass().getDeclaredMethod("autoCommitTransaction", SessionScope.class, Boolean.class); m.setAccessible(true); m.invoke(this.delegate, sessionScope, autoStart); } catch (Exception e) { if ( e instanceof SQLException) { throw (SQLException) e; } throw new RuntimeException(e); } } @Override protected void autoEndTransaction(SessionScope sessionScope, boolean autoStart) throws SQLException { try { Method m = this.delegate.getClass().getDeclaredMethod("autoEndTransaction", SessionScope.class, Boolean.class); m.setAccessible(true); m.invoke(this.delegate, sessionScope, autoStart); } catch (Exception e) { // TODO Auto-generated catch block if ( e instanceof SQLException) { throw (SQLException) e; } throw new RuntimeException(e); } } @Override protected Transaction autoStartTransaction(SessionScope sessionScope, boolean autoStart, Transaction trans) throws SQLException { try { Method m = this.delegate.getClass().getDeclaredMethod("autoStartTransaction", SessionScope.class, Boolean.class, Transaction.class); m.setAccessible(true); return (Transaction) m.invoke(this.delegate, sessionScope, autoStart); } catch (Exception e) { // TODO Auto-generated catch block if ( e instanceof SQLException) { throw (SQLException) e; } throw new RuntimeException(e); } } @Override protected SessionScope beginSessionScope() { try { Method m = this.delegate.getClass().getDeclaredMethod("beginSessionScope"); m.setAccessible(true); return (SessionScope) m.invoke(this.delegate); } catch (Exception e) { throw new RuntimeException(e); } } @Override protected StatementScope beginStatementScope(SessionScope sessionScope, MappedStatement mappedStatement) { try { Method m = this.delegate.getClass().getDeclaredMethod("beginSessionScope", SessionScope.class, MappedStatement.class); m.setAccessible(true); return (StatementScope) m.invoke(this.delegate, sessionScope, mappedStatement); } catch (Exception e) { throw new RuntimeException(e); } } @Override public void commitTransaction(SessionScope sessionScope) throws SQLException { this.delegate.commitTransaction(sessionScope); } @Override public int delete(SessionScope sessionScope, String id, Object param) throws SQLException { return this.delegate.delete(sessionScope, id, param); } @Override protected void endSessionScope(SessionScope sessionScope) { try { Method m = this.delegate.getClass().getDeclaredMethod("endSessionScope", SessionScope.class); m.setAccessible(true); m.invoke(this.delegate, sessionScope); } catch (Exception e) { throw new RuntimeException(e); } } @Override protected void endStatementScope(StatementScope statementScope) { try { Method m = this.delegate.getClass().getDeclaredMethod("endStatementScope", StatementScope.class); m.setAccessible(true); m.invoke(this.delegate, statementScope); } catch (Exception e) { throw new RuntimeException(e); } } @Override public void endTransaction(SessionScope sessionScope) throws SQLException { this.delegate.endTransaction(sessionScope); } @Override public boolean equals(Object obj) { return this.delegate.equals(obj); } @Override public int executeBatch(SessionScope sessionScope) throws SQLException { return this.delegate.executeBatch(sessionScope); } @Override public List executeBatchDetailed(SessionScope sessionScope) throws SQLException, BatchException { return this.delegate.executeBatchDetailed(sessionScope); } @Override public void flushDataCache() { this.delegate.flushDataCache(); } @Override public void flushDataCache(String id) { this.delegate.flushDataCache(id); } @Override public CacheModel getCacheModel(String id) { return this.delegate.getCacheModel(id); } @Override public Iterator getCacheModelNames() { return this.delegate.getCacheModelNames(); } @Override public DataExchangeFactory getDataExchangeFactory() { return this.delegate.getDataExchangeFactory(); } @Override public DataSource getDataSource() { return this.delegate.getDataSource(); } @Override public MappedStatement getMappedStatement(String id) { return this.delegate.getMappedStatement(id); } @Override public Iterator getMappedStatementNames() { return this.delegate.getMappedStatementNames(); } @Override public int getMaxTransactions() { return this.delegate.getMaxTransactions(); } @Override public ParameterMap getParameterMap(String id) { return this.delegate.getParameterMap(id); } @Override public Iterator getParameterMapNames() { return this.delegate.getParameterMapNames(); } @Override public ResultMap getResultMap(String id) { return this.delegate.getResultMap(id); } @Override public Iterator getResultMapNames() { return this.delegate.getResultMapNames(); } @Override public ResultObjectFactory getResultObjectFactory() { return this.delegate.getResultObjectFactory(); } @Override public SqlExecutor getSqlExecutor() { return this.delegate.getSqlExecutor(); } @Override public Transaction getTransaction(SessionScope sessionScope) { return this.delegate.getTransaction(sessionScope); } @Override public TransactionManager getTxManager() { return this.delegate.getTxManager(); } @Override public TypeHandlerFactory getTypeHandlerFactory() { return this.delegate.getTypeHandlerFactory(); } @Override public int hashCode() { return this.delegate.hashCode(); } @Override public Object insert(SessionScope sessionScope, String id, Object param) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.insert(sessionScope, id, param); } @Override public boolean isCacheModelsEnabled() { return this.delegate.isCacheModelsEnabled(); } @Override public boolean isEnhancementEnabled() { return this.delegate.isEnhancementEnabled(); } @Override public boolean isForceMultipleResultSetSupport() { return this.delegate.isForceMultipleResultSetSupport(); } @Override public boolean isLazyLoadingEnabled() { return this.delegate.isLazyLoadingEnabled(); } @Override public boolean isStatementCacheEnabled() { return this.delegate.isStatementCacheEnabled(); } @Override public boolean isUseColumnLabel() { return this.delegate.isUseColumnLabel(); } @Override public List queryForList(SessionScope sessionScope, String id, Object paramObject, int skip, int max) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.queryForList(sessionScope, id, paramObject, skip, max); } @Override public List queryForList(SessionScope sessionScope, String id, Object paramObject) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.queryForList(sessionScope, id, paramObject); } @Override public Map queryForMap(SessionScope sessionScope, String id, Object paramObject, String keyProp, String valueProp) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.queryForMap(sessionScope, id, paramObject, keyProp, valueProp); } @Override public Map queryForMap(SessionScope sessionScope, String id, Object paramObject, String keyProp) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.queryForMap(sessionScope, id, paramObject, keyProp); } @Override public Object queryForObject(SessionScope sessionScope, String id, Object paramObject, Object resultObject) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.queryForObject(sessionScope, id, paramObject, resultObject); } @Override public Object queryForObject(SessionScope sessionScope, String id, Object paramObject) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.queryForObject(sessionScope, id, paramObject); } @Override public PaginatedList queryForPaginatedList(SessionScope sessionScope, String id, Object paramObject, int pageSize) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.queryForPaginatedList(sessionScope, id, paramObject, pageSize); } @Override public void queryWithRowHandler(SessionScope sessionScope, String id, Object paramObject, RowHandler rowHandler) throws SQLException { checkAndRefreshSqlMap(id); this.delegate.queryWithRowHandler(sessionScope, id, paramObject, rowHandler); } @Override public void setCacheModelsEnabled(boolean cacheModelsEnabled) { this.delegate.setCacheModelsEnabled(cacheModelsEnabled); } @Override public void setEnhancementEnabled(boolean enhancementEnabled) { this.delegate.setEnhancementEnabled(enhancementEnabled); } @Override public void setForceMultipleResultSetSupport( boolean forceMultipleResultSetSupport) { this.delegate.setForceMultipleResultSetSupport(forceMultipleResultSetSupport); } @Override public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) { this.delegate.setLazyLoadingEnabled(lazyLoadingEnabled); } @Override public void setResultObjectFactory(ResultObjectFactory resultObjectFactory) { this.delegate.setResultObjectFactory(resultObjectFactory); } @Override public void setStatementCacheEnabled(boolean statementCacheEnabled) { this.delegate.setStatementCacheEnabled(statementCacheEnabled); } @Override public void setTxManager(TransactionManager txManager) { this.delegate.setTxManager(txManager); } @Override public void setUseColumnLabel(boolean useColumnLabel) { this.delegate.setUseColumnLabel(useColumnLabel); } @Override public void setUserProvidedTransaction(SessionScope sessionScope, Connection userConnection) { this.delegate.setUserProvidedTransaction(sessionScope, userConnection); } @Override public void startBatch(SessionScope sessionScope) { this.delegate.startBatch(sessionScope); } @Override public void startTransaction(SessionScope sessionScope, int transactionIsolation) throws SQLException { this.delegate.startTransaction(sessionScope, transactionIsolation); } @Override public void startTransaction(SessionScope sessionScope) throws SQLException { this.delegate.startTransaction(sessionScope); } @Override public int update(SessionScope sessionScope, String id, Object param) throws SQLException { checkAndRefreshSqlMap(id); return this.delegate.update(sessionScope, id, param); } }
DySqlMapParser.java,重置处理sql节点的方法
package test.develop.ibatis; import java.lang.reflect.Field; import java.util.Properties; import org.w3c.dom.Node; import com.ibatis.common.xml.Nodelet; import com.ibatis.common.xml.NodeletParser; import com.ibatis.common.xml.NodeletUtils; import com.ibatis.sqlmap.client.SqlMapException; import com.ibatis.sqlmap.engine.builder.xml.SqlMapParser; import com.ibatis.sqlmap.engine.builder.xml.XmlParserState; public class DySqlMapParser extends SqlMapParser { private XmlParserState myState = null; public DySqlMapParser(XmlParserState state) { super(state); this.myState = state; resetSqlNodelets(); } private void resetSqlNodelets() { try { Field f = SqlMapParser.class.getDeclaredField("parser"); f.setAccessible(true); NodeletParser p = (NodeletParser) f.get(this); p.addNodelet("/sqlMap/sql", new Nodelet() { public void process(Node node) throws Exception { Properties attributes = NodeletUtils.parseAttributes(node, myState.getGlobalProps()); String id = attributes.getProperty("id"); if (myState.isUseStatementNamespaces()) { id = myState.applyNamespace(id); } myState.getSqlIncludes().put(id, node); } }); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
补充一个漏掉的类
package test.develop; public class FileDesc { private String path = null; private long tm; public FileDesc(String path, long tm) { super(); this.path = path; this.tm = tm; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public long getTm() { return tm; } public void setTm(long tm) { this.tm = tm; } @Override public boolean equals(Object o) { return o instanceof FileDesc && this.path.equals(((FileDesc)o).path) && this.tm == ((FileDesc)o).tm; } @Override public int hashCode() { int result = 17; result = result * 37 + (int)(tm ^ (tm >>> 32)); result = result * 37 + this.path.hashCode(); return result; } }
package test.develop; import java.io.IOException; import java.io.StringBufferInputStream; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class NoOpEntityResolver implements EntityResolver { @Override public InputSource resolveEntity(String arg0, String arg1) throws SAXException, IOException { return new InputSource(new StringBufferInputStream("")); } }
读取sqlmap文件的类
package test.develop.ibatis; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import test.develop.FileDesc; import test.develop.NoOpEntityResolver; public final class SqlMapConfigUtils { @SuppressWarnings("unchecked") public static List <FileDesc> readSqlMapFileMapping(String sqlMapConfig) { try { File f = new File(sqlMapConfig); InputStream is = new FileInputStream(f); InputStreamReader isr = new InputStreamReader(is, "utf-8"); SAXBuilder builder = new SAXBuilder(); builder.setEntityResolver(new NoOpEntityResolver()); Document doc = builder.build(isr); Element root = doc.getRootElement(); List list = root.getChildren("sqlMap"); List <FileDesc> retList = new ArrayList<FileDesc>(); for(Iterator it = list.listIterator(); it.hasNext(); ) { Element e = (Element) it.next(); String loc = e.getAttribute("resource").getValue(); URL url = SqlMapConfigUtils.class.getResource(loc); File file= new File(url.getFile()); long lastTm = file.lastModified(); FileDesc fd = new FileDesc(file.getAbsolutePath(), lastTm); retList.add(fd); } return retList; } catch (Exception e) { e.printStackTrace(); } return new ArrayList<FileDesc>(); } public static List <String> readSqlMap(FileDesc fd) { try { String path = fd.getPath(); InputStream is = new FileInputStream(path); InputStreamReader isr = new InputStreamReader(is, "utf-8"); SAXBuilder builder = new SAXBuilder(); builder.setEntityResolver(new NoOpEntityResolver()); Document doc = builder.build(isr); Element root = doc.getRootElement(); String namespace = null; if ( root.getAttribute("namespace") != null) { namespace = root.getAttribute("namespace").getValue(); } List list = root.getChildren(); List <String> retList = new ArrayList<String>(); for(Iterator it = list.listIterator(); it.hasNext(); ) { Element e = (Element) it.next(); String tagName = e.getName(); if ("statement".equals(tagName) || "insert".equals(tagName) || "update".equals(tagName) || "delete".equals(tagName) || "select".equals(tagName) || "procedure".equals(tagName)) { String id = e.getAttribute("id").getValue(); if ( namespace != null ) { id = namespace + "." + id; } retList.add(id); } } return retList; } catch (UnsupportedEncodingException e) { } catch (JDOMException e) { } catch (IOException e) {e.printStackTrace(); } return new ArrayList<String>(); } }
相关文章推荐
- 实现ibatis的动态加载sqlmap配置文件 .
- 利用java反射机制 读取配置文件 实现动态类加载以及动态类型转换
- C#动态加载DLL,通过配置文件实现对程序集的即插即用
- 利用java反射机制 读取配置文件 实现动态类加载以及动态类型转换
- JFig读取配置文件,实现动态加载
- C#读取配置文件详解 完全自定义实现动态加载dll
- 继承PropertyPlaceholderConfigurer 实现动态加载配置文件
- 实现ibatis手动控制加载sqlmap文件,终于不用重启应用了
- 动态【配置文件】之实现 (二)
- ibatis - sqlMapConfig.xml配置文件详解
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- spring动态加载(刷新)配置文件 [复制链接]
- 如何使用jquery动态加载js,css文件实现代码
- Consul+Registrator+Consul-template实现动态修改nginx配置文件
- JavaScript实现动态加载其他的js文件-(咋个办呢 zgbn)
- ibatis配置文件解析过程中对DTD的加载处理
- IBatis简单实现(附主键自动生成)其SqlMap XML文件配置
- Ibatis—sqlMapConfig.xml配置文件详解
- C#实现反射调用动态加载的DLL文件中的方法
- AutowireCapableBeanFactory,实现不必配置xml文件,动态加载bean