- 浏览: 73261 次
- 性别:
- 来自: 深圳
文章分类
最新评论
ibatis文件的文件的解析从主文件sql-map-config.xml开始。见类:com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser
public SqlMapConfigParser() { parser.setValidation(true); parser.setEntityResolver(new SqlMapClasspathEntityResolver()); addSqlMapConfigNodelets(); //"/sqlMapConfig/end()" addGlobalPropNodelets(); //"/sqlMapConfig/properties" addSettingsNodelets(); //"/sqlMapConfig/settings" addTypeAliasNodelets(); //"/sqlMapConfig/typeAlias" addTypeHandlerNodelets(); //"/sqlMapConfig/typeHandler" addTransactionManagerNodelets(); //"/sqlMapConfig/transactionManager/property" ... addSqlMapNodelets(); //"/sqlMapConfig/sqlMap" addResultObjectFactoryNodelets(); //"/sqlMapConfig/resultObjectFactory" ... }
先将上诉的节点默认添加进来,然后根据具体的设置在利用回调来初始化各个节点的具体属性值,以addSettingsNodelets()为例:
private void addSettingsNodelets() { parser.addNodelet("/sqlMapConfig/settings", new Nodelet() { public void process(Node node) throws Exception { //该方法做会调用 Properties attributes = NodeletUtils.parseAttributes(node, state.getGlobalProps()); SqlMapConfiguration config = state.getConfig(); String classInfoCacheEnabledAttr = attributes.getProperty("classInfoCacheEnabled"); boolean classInfoCacheEnabled = (classInfoCacheEnabledAttr == null || "true".equals(classInfoCacheEnabledAttr)); config.setClassInfoCacheEnabled(classInfoCacheEnabled); String lazyLoadingEnabledAttr = attributes.getProperty("lazyLoadingEnabled"); boolean lazyLoadingEnabled = (lazyLoadingEnabledAttr == null || "true".equals(lazyLoadingEnabledAttr)); config.setLazyLoadingEnabled(lazyLoadingEnabled); String statementCachingEnabledAttr = attributes.getProperty("statementCachingEnabled"); boolean statementCachingEnabled = (statementCachingEnabledAttr == null || "true".equals(statementCachingEnabledAttr)); config.setStatementCachingEnabled(statementCachingEnabled); String cacheModelsEnabledAttr = attributes.getProperty("cacheModelsEnabled"); boolean cacheModelsEnabled = (cacheModelsEnabledAttr == null || "true".equals(cacheModelsEnabledAttr)); config.setCacheModelsEnabled(cacheModelsEnabled); String enhancementEnabledAttr = attributes.getProperty("enhancementEnabled"); boolean enhancementEnabled = (enhancementEnabledAttr == null || "true".equals(enhancementEnabledAttr)); config.setEnhancementEnabled(enhancementEnabled); String useColumnLabelAttr = attributes.getProperty("useColumnLabel"); boolean useColumnLabel = (useColumnLabelAttr == null || "true".equals(useColumnLabelAttr)); config.setUseColumnLabel(useColumnLabel); String forceMultipleResultSetSupportAttr = attributes.getProperty("forceMultipleResultSetSupport"); boolean forceMultipleResultSetSupport = "true".equals(forceMultipleResultSetSupportAttr); config.setForceMultipleResultSetSupport(forceMultipleResultSetSupport); String defaultTimeoutAttr = attributes.getProperty("defaultStatementTimeout"); Integer defaultTimeout = defaultTimeoutAttr == null ? null : Integer.valueOf(defaultTimeoutAttr); config.setDefaultStatementTimeout(defaultTimeout); String useStatementNamespacesAttr = attributes.getProperty("useStatementNamespaces"); boolean useStatementNamespaces = "true".equals(useStatementNamespacesAttr); state.setUseStatementNamespaces(useStatementNamespaces); } }); }
parser.addNodelet(xpath,nodelet)添加一个节点,见类:com.ibatis.common.xml.NodeletParser
public void addNodelet(String xpath, Nodelet nodelet) { letMap.put(xpath, nodelet); }
在这个类中,解析节点的时候,
public void parse(Reader reader) throws NodeletException { try { Document doc = createDocument(reader); parse(doc.getLastChild()); } catch (Exception e) { throw new NodeletException("Error parsing XML. Cause: " + e, e); } } public void parse(InputStream inputStream) throws NodeletException { try { Document doc = createDocument(inputStream); parse(doc.getLastChild()); } catch (Exception e) { throw new NodeletException("Error parsing XML. Cause: " + e, e); } } /** * Begins parsing from the provided Node. */ public void parse(Node node) { Path path = new Path(); processNodelet(node, "/"); process(node, path); } /** * A recursive method that walkes the DOM tree, registers XPaths and * calls Nodelets registered under those XPaths. */ private void process(Node node, Path path) { if (node instanceof Element) { // Element String elementName = node.getNodeName(); path.add(elementName); processNodelet(node, path.toString()); processNodelet(node, new StringBuffer("//").append(elementName).toString()); // Attribute NamedNodeMap attributes = node.getAttributes(); int n = attributes.getLength(); for (int i = 0; i < n; i++) { Node att = attributes.item(i); String attrName = att.getNodeName(); path.add("@" + attrName); processNodelet(att, path.toString()); processNodelet(node, new StringBuffer("//@").append(attrName).toString()); path.remove(); } // Children NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { process(children.item(i), path); } path.add("end()"); processNodelet(node, path.toString()); path.remove(); path.remove(); } else if (node instanceof Text) { // Text path.add("text()"); processNodelet(node, path.toString()); processNodelet(node, "//text()"); path.remove(); } } private void processNodelet(Node node, String pathString) { Nodelet nodelet = (Nodelet) letMap.get(pathString); if (nodelet != null) { try { nodelet.process(node); //这个方法进行回调,设置初始值 } catch (Exception e) { throw new RuntimeException("Error parsing XPath '" + pathString + "'. Cause: " + e, e); } } }
在com.ibatis.sqlmap.engine.builder.xml.SqlMapParser里面解析到statement时:
protected void addStatementNodelets() { parser.addNodelet("/sqlMap/statement", new Nodelet() { public void process(Node node) throws Exception { statementParser.parseGeneralStatement(node, new MappedStatement()); } }); parser.addNodelet("/sqlMap/insert", new Nodelet() { public void process(Node node) throws Exception { statementParser.parseGeneralStatement(node, new InsertStatement()); } }); parser.addNodelet("/sqlMap/update", new Nodelet() { public void process(Node node) throws Exception { statementParser.parseGeneralStatement(node, new UpdateStatement()); } }); parser.addNodelet("/sqlMap/delete", new Nodelet() { public void process(Node node) throws Exception { statementParser.parseGeneralStatement(node, new DeleteStatement()); } }); parser.addNodelet("/sqlMap/select", new Nodelet() { public void process(Node node) throws Exception { statementParser.parseGeneralStatement(node, new SelectStatement()); } }); parser.addNodelet("/sqlMap/procedure", new Nodelet() { public void process(Node node) throws Exception { statementParser.parseGeneralStatement(node, new ProcedureStatement()); } }); }实际上调用了com.ibatis.sqlmap.engine.builder.xml.SqlStatementParser的parseGeneralStatement方法:
public void parseGeneralStatement(Node node, MappedStatement statement) { // ... MappedStatementConfig statementConf = state.getConfig().newMappedStatementConfig(id, statement, new XMLSqlSource(state, node), parameterMapName, parameterClass, resultMapName, additionalResultMapNames, resultClass, additionalResultClasses, resultSetType, fetchSizeInt, allowRemappingBool, timeoutInt, cacheModelName, xmlResultName); findAndParseSelectKey(node, statementConf); }此时又是调用了com.ibatis.sqlmap.engine.config.SqlMapConfiguration的newMappedStatementConfig方法:
public MappedStatementConfig newMappedStatementConfig(String id, MappedStatement statement, SqlSource processor, String parameterMapName, Class parameterClass, String resultMapName, String[] additionalResultMapNames, Class resultClass, Class[] additionalResultClasses, String resultSetType, Integer fetchSize, boolean allowRemapping, Integer timeout, String cacheModelName, String xmlResultName) { return new MappedStatementConfig(this, id, statement, processor, parameterMapName, parameterClass, resultMapName, additionalResultMapNames, resultClass, additionalResultClasses, cacheModelName, resultSetType, fetchSize, allowRemapping, timeout, defaultStatementTimeout, xmlResultName); }返回一个com.ibatis.sqlmap.engine.config.MappedStatementConfig的实例
MappedStatementConfig(SqlMapConfiguration config, String id, MappedStatement statement, SqlSource processor, String parameterMapName, Class parameterClass, String resultMapName, String[] additionalResultMapNames, Class resultClass, Class[] additionalResultClasses, String cacheModelName, String resultSetType, Integer fetchSize, boolean allowRemapping, Integer timeout, Integer defaultStatementTimeout, String xmlResultName) { this.errorContext = config.getErrorContext(); this.client = config.getClient(); SqlMapExecutorDelegate delegate = client.getDelegate(); this.typeHandlerFactory = config.getTypeHandlerFactory(); errorContext.setActivity("parsing a mapped statement"); errorContext.setObjectId(id + " statement"); errorContext.setMoreInfo("Check the result map name."); if (resultMapName != null) { statement.setResultMap(client.getDelegate().getResultMap(resultMapName)); if (additionalResultMapNames != null) { for (int i = 0; i < additionalResultMapNames.length; i++) { statement.addResultMap(client.getDelegate().getResultMap(additionalResultMapNames[i])); } } } errorContext.setMoreInfo("Check the parameter map name."); if (parameterMapName != null) { statement.setParameterMap(client.getDelegate().getParameterMap(parameterMapName)); } statement.setId(id); statement.setResource(errorContext.getResource()); if (resultSetType != null) { if ("FORWARD_ONLY".equals(resultSetType)) { statement.setResultSetType(new Integer(ResultSet.TYPE_FORWARD_ONLY)); } else if ("SCROLL_INSENSITIVE".equals(resultSetType)) { statement.setResultSetType(new Integer(ResultSet.TYPE_SCROLL_INSENSITIVE)); } else if ("SCROLL_SENSITIVE".equals(resultSetType)) { statement.setResultSetType(new Integer(ResultSet.TYPE_SCROLL_SENSITIVE)); } } if (fetchSize != null) { statement.setFetchSize(fetchSize); } // set parameter class either from attribute or from map (make sure to match) ParameterMap parameterMap = statement.getParameterMap(); if (parameterMap == null) { statement.setParameterClass(parameterClass); } else { statement.setParameterClass(parameterMap.getParameterClass()); } // process SQL statement, including inline parameter maps errorContext.setMoreInfo("Check the SQL statement."); Sql sql = processor.getSql(); setSqlForStatement(statement, sql); // set up either null result map or automatic result mapping ResultMap resultMap = (ResultMap) statement.getResultMap(); if (resultMap == null && resultClass == null) { statement.setResultMap(null); } else if (resultMap == null) { resultMap = buildAutoResultMap(allowRemapping, statement, resultClass, xmlResultName); statement.setResultMap(resultMap); if (additionalResultClasses != null) { for (int i = 0; i < additionalResultClasses.length; i++) { statement.addResultMap(buildAutoResultMap(allowRemapping, statement, additionalResultClasses[i], xmlResultName)); } } } statement.setTimeout(defaultStatementTimeout); if (timeout != null) { try { statement.setTimeout(timeout); } catch (NumberFormatException e) { throw new SqlMapException("Specified timeout value for statement " + statement.getId() + " is not a valid integer"); } } errorContext.setMoreInfo(null); errorContext.setObjectId(null); statement.setSqlMapClient(client); if (cacheModelName != null && cacheModelName.length() > 0 && client.getDelegate().isCacheModelsEnabled()) {//这个判断很关键 CacheModel cacheModel = client.getDelegate().getCacheModel(cacheModelName); mappedStatement = new CachingStatement(statement, cacheModel); } else { mappedStatement = statement; } rootStatement = statement; delegate.addMappedStatement(mappedStatement); }
上诉的if (cacheModelName != null && cacheModelName.length() > 0 && client.getDelegate().isCacheModelsEnabled())判断,直接决定了是否启用缓存,假设前面没有设置setting这个属性,该值是为空的,不存在默认值,故此时是不会启用缓存的。
总结:
当解析实际的配置文件sql-map-config.xml时,
如果设置了<setting>这个属性,则回调addSettingsNodelets里面的addNodelet里面的Nodelet的process方法。
设置里面的属性值,假如此时没有设置<setting>属性(注意,是没有设置,不是设置为空,因为设置为空,同样的调用回调,设置了默认值),则不再调用此回调函数,则此时将没有默认值,如果此时想启动缓存等,都是无效的。
故,此时应注意,如果想利用默认值,setting是必须设置的,哪怕设置为空。但,如果设置了setting后,文件的先后顺序是有要求的,如果A文件利用到b文件的命名空间的某个引用id,则此时必须使得B文件在A文件之前装载,否则将出现文件A引用文件B中的id时出现不存在的异常。
相关推荐
- **iBATIS SQLMap-2.3.4.726**:这是iBATIS的主程序包,包含了框架的主要类和接口,以及相关的配置文件。 - **iBATIS Extended**:可能是iBATIS的扩展组件或者第三方对iBATIS的增强版,增加了额外的功能或优化。 - ...
《深入解析iBatis源码》 iBatis,一个优秀的Java持久层框架,以其轻量级、灵活的特性在众多ORM(Object-Relational Mapping)框架中独树一帜。iBatis的核心在于它的SQL映射机制,它将数据库操作与业务逻辑解耦,...
1. **SqlMapConfig.xml**:这是iBATIS的核心配置文件,包含了数据源、事务管理器、SqlMapClient以及全局设置等信息。 2. **MappedStatement**:每个SQL语句在iBATIS中都对应一个MappedStatement对象,包含了SQL语句...
Ibatis,一个优秀的持久层框架,它允许开发者将SQL语句直接写在配置文件中,避免了JDBC的繁琐代码,提升了开发效率。接下来,我们将深入探讨IbatisDemo中的关键知识点。 一、Ibatis框架简介 Ibatis是由MyBatis团队...
深入研究iBatis源码有助于理解其内部工作原理,包括如何解析XML配置文件,如何执行SQL语句,以及如何进行结果映射。源码分析可以帮助开发者更好地定制和优化自己的应用。 六、iBatis实践项目 通过实践项目,可以...
《ibatis框架源码剖析》是一本深入探讨mybatis前身——ibatis的源码解析书籍。通过对源码的深入分析,我们可以理解ibatis的核心机制,掌握数据库操作的底层原理,从而更好地利用和优化这个强大的持久层框架。在这个...
标题 "ibatis学习" 暗示我们即将探讨的是关于Ibatis,一个著名的Java持久层框架,它允许开发者将SQL语句直接写在配置文件中,以实现灵活的数据访问。Ibatis提供了简单易用的API,使得数据库操作与业务逻辑解耦,提高...
iBatis的亮点在于它的XML配置文件,开发者可以在其中编写SQL语句,并通过动态参数绑定,实现灵活的数据查询。此外,iBatis支持ResultMap,可以方便地映射查询结果到Java对象,避免了过多的手动类型转换。通过...
在源码分析部分,你会看到iBATIS如何加载和解析XML配置文件,如何执行SQL语句,以及如何处理异常。这部分内容对于理解iBATIS的工作流程至关重要,它将帮助你更好地调试和优化基于iBATIS的应用。 最后,你会了解到...
Ibatis2.x是一款轻量级的ORM框架,它允许开发者通过SQL Map配置文件来编写SQL语句,提供了灵活的SQL控制。然而,随着技术的发展,Mybatis3.x应运而生,它在Ibatis的基础上进行了诸多改进和优化。 首先,从版本号的...
1. **SQL映射文件**:iBatis的核心在于XML配置文件,其中包含了SQL语句和参数映射。这使得开发者能够自由地编写复杂的SQL,而不需要在Java代码中嵌入大量的字符串拼接。 2. **动态SQL**:iBatis支持动态SQL,可以在...
9. **源码解析**:对于对底层原理感兴趣的开发者,可能包含iBatis源码的解读,帮助理解其工作原理。 10. **进阶内容**:可能涵盖MyBatis(iBatis的升级版)的特性,以及如何使用插件扩展iBatis功能。 通过深入学习...
- 如何解析SqlMapConfig.xml配置文件,创建SqlSessionFactory? - SqlSession是如何管理数据库会话的? - Executor接口及其实现如何处理SQL执行? - 参数和结果是如何通过ParameterHandler和ResultHandler进行映射的...
三、XML映射文件解析 iBatis通过解析XML映射文件来获取SQL语句和参数映射信息。映射文件包含以下关键元素: - `<mapper>`:定义一个Mapper接口,映射到特定的XML文件。 - `<select>`、`<insert>`、`<update>`、`...
标题 "根据mybatis/ibatis sqlmapper文件解析生成数据库表" 暗示了我们将会探讨一个关于MyBatis或iBatis框架的工具,它能够解析SQL映射文件并根据这些文件自动生成数据库表。这个过程对于快速构建数据库模型,尤其是...
《深入解析iBatis3:源码与驱动详解》 iBatis3作为一个轻量级的持久层框架,因其灵活性和高效性,在Java开发中备受青睐。本文将围绕标题"ibatis3源码+驱动",对iBatis3的核心功能、设计理念、源码结构以及驱动机制...
映射文件允许灵活地配置参数,支持动态SQL,比如根据条件选择性地执行某个部分。 3. SQL Session:SQL Session是iBATIS与数据库进行交互的接口,负责执行SQL语句并管理事务。一个Session对应一次数据库连接,用于...
Ibatis,全称为MyBatis,是一个优秀的Java持久层框架,它主要负责SQL映射,将Java对象与数据库之间的交互转换为易于管理的XML或注解配置文件,从而减轻了开发者编写繁琐的手动SQL和结果集映射的工作。在本实例中,...
Ibatis的核心概念是SqlMapConfig.xml配置文件,它包含了数据源、事务管理器等关键设置。在源码中,可以看到Ibatis如何通过SqlSessionFactory构建会话工厂,以及SqlSession接口如何处理数据库交互。SqlMapper接口提供...