您的位置:首页 > 数据库

实现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的

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>();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: