转载于 0309yt做一个优秀的程序员
为什么启用namespace?
namespace的优点
1.sqlmap看起来更加优雅。
比如hivestore-sqlmap.xml中原本的
<select id = "hivestore.insert">
而使用namespace后,就可以写成
<select id = "insert">
这样就更加清晰、简洁。因为你当前所在的模块即为hivestore,而insert非常清楚的标识就是一个插入操作。
2.因为ibatis的sqlmap中id与sql是全局保存的键值对。
很显然我们无发保证一个团队开发的项目,多个人在不同的sqlmap中使用xxx.yyy,排查过程中你需要深入到dao文件中去检查。而使用namespace后,可以防止此类事件的发生,紧紧需要在sqlmap.xml文件中检查第一行namespce是否不同即可。
1.如何启用namespace?
配置方式:
在sqlmap-config.xml文件中增加如下配置项
<setting useStatementNamespaces="true"/>
在xxxxx-sqlmap.xml文件中增加如下配置即可
<sqlMap namespace="xxxxxx">
namespce的缺点
遇到的问题?
使用namespace后:
<sqlMap namespace="hivestore">
<select id="insert" ........
<select id="column.insert".
方法一:.getSqlMapClientTemplate().insert(“hivestore.insert”, hivestore); 运行成功
方法二:this.getSqlMapClientTemplate().insert(“hivestore.column.insert”, hivestoreColumn); 运行出错
为什么我启用了namespce后,第二个方法却报名了名为hivestore.column.insert的sqlstatement找不到?
细节点:关于方法二为什么报错的原因
首先ibatis启动加载配置文件:与报错相关部分代码如下
1.SqlMapParse.java
parser.addNodelet("/sqlMap/select", new Nodelet() {
public void process(Node node) throws Exception {
statementParser.parseGeneralStatement(node, new SelectStatement());
}
});
2.SqlMapStatementParser.java
相关方法:
public void parseGeneralStatement(Node node, MappedStatement statement){}
关键行:
if (state.isUseStatementNamespaces()) {
id = state.applyNamespace(id);
}
默认值:
private boolean useStatementNamespaces = false;
3.细节点:
public String applyNamespace(String id) {
String newId = id;
if (namespace != null && namespace.length() > 0 && id != null && id.indexOf('.') < 0) {
newId = namespace + "." + id;
}
return newId;
}
id.indexOf(‘.’) < 0导致了方法二出错,这里不允许出现”.”