From 26e6638657b6765a861a860038076fd8fcf12edd Mon Sep 17 00:00:00 2001 From: e Date: Thu, 25 Feb 2016 14:41:54 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0=20spring=204.2.?= =?UTF-8?q?4=E3=80=81hibernate=20validator=205.2.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 13 +- .../resources/spring-context-activiti.xml | 104 ++++---- src/main/resources/spring-context-jedis.xml | 48 ++-- src/main/resources/spring-context-shiro.xml | 218 ++++++++-------- src/main/resources/spring-context.xml | 224 ++++++++-------- src/main/resources/spring-mvc.xml | 242 +++++++++--------- 6 files changed, 425 insertions(+), 424 deletions(-) diff --git a/pom.xml b/pom.xml index a9a49e7a5c..6d4309f391 100644 --- a/pom.xml +++ b/pom.xml @@ -16,12 +16,13 @@ - 4.0.8.RELEASE - 5.1.1.Final + 4.2.4.RELEASE + 5.2.4.Final + 3.2.8 - 1.2.2 - 1.0.11 - 2.6.9 + 1.2.4 + 1.0.17 + 2.6.11 2.0.4 1.2.3 2.4.2 @@ -39,7 +40,7 @@ 1.4.7 17.0 5.5.1 - 3.9 + 3.13 2.3.20 diff --git a/src/main/resources/spring-context-activiti.xml b/src/main/resources/spring-context-activiti.xml index 3435d06be4..4355af1543 100644 --- a/src/main/resources/spring-context-activiti.xml +++ b/src/main/resources/spring-context-activiti.xml @@ -1,53 +1,53 @@ - - - - Activiti Configuration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Activiti Configuration + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring-context-jedis.xml b/src/main/resources/spring-context-jedis.xml index e5e2167a89..bd2a581e75 100644 --- a/src/main/resources/spring-context-jedis.xml +++ b/src/main/resources/spring-context-jedis.xml @@ -1,25 +1,25 @@ - - - - Jedis Configuration - - - - - - - - - - - - - - - - + + + + Jedis Configuration + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring-context-shiro.xml b/src/main/resources/spring-context-shiro.xml index c5a00ed047..d8cc58f55c 100644 --- a/src/main/resources/spring-context-shiro.xml +++ b/src/main/resources/spring-context-shiro.xml @@ -1,110 +1,110 @@ - - - - Shiro Configuration - - - - - - - - - /static/** = anon - /userfiles/** = anon - ${adminPath}/cas = cas - ${adminPath}/login = authc - ${adminPath}/logout = logout - ${adminPath}/** = user - /act/rest/service/editor/** = perms[act:model:edit] - /act/rest/service/model/** = perms[act:model:edit] - /act/rest/service/** = user - /ReportServer/** = user - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Shiro Configuration + + + + + + + + + /static/** = anon + /userfiles/** = anon + ${adminPath}/cas = cas + ${adminPath}/login = authc + ${adminPath}/logout = logout + ${adminPath}/** = user + /act/rest/service/editor/** = perms[act:model:edit] + /act/rest/service/model/** = perms[act:model:edit] + /act/rest/service/** = user + /ReportServer/** = user + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring-context.xml b/src/main/resources/spring-context.xml index 35c84f254a..078cc38b12 100644 --- a/src/main/resources/spring-context.xml +++ b/src/main/resources/spring-context.xml @@ -1,113 +1,113 @@ - - - - Spring Configuration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Spring Configuration + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring-mvc.xml b/src/main/resources/spring-mvc.xml index 07d61d55b1..eeb14b4624 100644 --- a/src/main/resources/spring-mvc.xml +++ b/src/main/resources/spring-mvc.xml @@ -1,122 +1,122 @@ - - - - Spring MVC Configuration - - - - - - - - - - - - - - - - - - - - application/json;charset=UTF-8 - - - - - - - - - - - - - - - - com.thinkgem.jeesite.common.persistence.BaseEntity - com.thinkgem.jeesite.common.supcan.treelist.TreeList - com.thinkgem.jeesite.common.supcan.treelist.cols.Col - com.thinkgem.jeesite.common.supcan.treelist.cols.Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - error/403 - error/500 - - - - - - - - - - + + + + Spring MVC Configuration + + + + + + + + + + + + + + + + + + + + application/json;charset=UTF-8 + + + + + + + + + + + + + + + + com.thinkgem.jeesite.common.persistence.BaseEntity + com.thinkgem.jeesite.common.supcan.treelist.TreeList + com.thinkgem.jeesite.common.supcan.treelist.cols.Col + com.thinkgem.jeesite.common.supcan.treelist.cols.Group + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + error/403 + error/500 + + + + + + + + + + \ No newline at end of file From 9940acdbd9959161351b62b3b35db3f677ec88a9 Mon Sep 17 00:00:00 2001 From: e Date: Thu, 25 Feb 2016 17:01:28 +0800 Subject: [PATCH 2/5] update mybatis 3.2 to 3.3.1 --- pom.xml | 4 +- .../ibatis/builder/xml/XMLMapperBuilder.java | 975 ++++----- .../apache/ibatis/session/Configuration.java | 1782 +++++++++-------- src/main/resources/mybatis-config.xml | 9 +- 4 files changed, 1399 insertions(+), 1371 deletions(-) diff --git a/pom.xml b/pom.xml index 6d4309f391..c76b306778 100644 --- a/pom.xml +++ b/pom.xml @@ -18,8 +18,8 @@ 4.2.4.RELEASE 5.2.4.Final - - 3.2.8 + 3.3.1 + 1.2.4 1.0.17 2.6.11 diff --git a/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java b/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java index df0403c2c7..f107fb2dd1 100644 --- a/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java +++ b/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java @@ -1,487 +1,488 @@ -/* - * Copyright 2009-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ibatis.builder.xml; - -import java.io.InputStream; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.apache.ibatis.builder.BaseBuilder; -import org.apache.ibatis.builder.BuilderException; -import org.apache.ibatis.builder.CacheRefResolver; -import org.apache.ibatis.builder.IncompleteElementException; -import org.apache.ibatis.builder.MapperBuilderAssistant; -import org.apache.ibatis.builder.ResultMapResolver; -import org.apache.ibatis.cache.Cache; -import org.apache.ibatis.executor.ErrorContext; -import org.apache.ibatis.io.Resources; -import org.apache.ibatis.mapping.Discriminator; -import org.apache.ibatis.mapping.ParameterMapping; -import org.apache.ibatis.mapping.ParameterMode; -import org.apache.ibatis.mapping.ResultFlag; -import org.apache.ibatis.mapping.ResultMap; -import org.apache.ibatis.mapping.ResultMapping; -import org.apache.ibatis.parsing.XNode; -import org.apache.ibatis.parsing.XPathParser; -import org.apache.ibatis.session.Configuration; -import org.apache.ibatis.type.JdbcType; -import org.apache.ibatis.type.TypeHandler; - -/** - * @author Clinton Begin - * @description 增加解析方法,原方法不解析相同的resource - */ -public class XMLMapperBuilder extends BaseBuilder { - - private XPathParser parser; - private MapperBuilderAssistant builderAssistant; - private Map sqlFragments; - private String resource; - - @Deprecated - public XMLMapperBuilder(Reader reader, Configuration configuration, - String resource, Map sqlFragments, String namespace) { - this(reader, configuration, resource, sqlFragments); - this.builderAssistant.setCurrentNamespace(namespace); - } - - @Deprecated - public XMLMapperBuilder(Reader reader, Configuration configuration, - String resource, Map sqlFragments) { - this(new XPathParser(reader, true, configuration.getVariables(), - new XMLMapperEntityResolver()), configuration, resource, - sqlFragments); - } - - public XMLMapperBuilder(InputStream inputStream, - Configuration configuration, String resource, - Map sqlFragments, String namespace) { - this(inputStream, configuration, resource, sqlFragments); - this.builderAssistant.setCurrentNamespace(namespace); - } - - public XMLMapperBuilder(InputStream inputStream, - Configuration configuration, String resource, - Map sqlFragments) { - this(new XPathParser(inputStream, true, configuration.getVariables(), - new XMLMapperEntityResolver()), configuration, resource, - sqlFragments); - } - - private XMLMapperBuilder(XPathParser parser, Configuration configuration, - String resource, Map sqlFragments) { - super(configuration); - this.builderAssistant = new MapperBuilderAssistant(configuration, - resource); - this.parser = parser; - this.sqlFragments = sqlFragments; - this.resource = resource; - } - - public void parse() { - if (!configuration.isResourceLoaded(resource)) { - configurationElement(parser.evalNode("/mapper")); - configuration.addLoadedResource(resource); - bindMapperForNamespace(); - } - - parsePendingResultMaps(); - parsePendingChacheRefs(); - parsePendingStatements(); - } - - // TODO 增加解析方法,原方法不解析相同的resource - public void parse1() { - // if (!configuration.isResourceLoaded(resource)) { - configurationElement(parser.evalNode("/mapper")); - configuration.addLoadedResource(resource); - bindMapperForNamespace(); - // } - - parsePendingResultMaps(); - parsePendingChacheRefs(); - parsePendingStatements(); - } - - public XNode getSqlFragment(String refid) { - return sqlFragments.get(refid); - } - - private void configurationElement(XNode context) { - try { - String namespace = context.getStringAttribute("namespace"); - if (namespace.equals("")) { - throw new BuilderException("Mapper's namespace cannot be empty"); - } - builderAssistant.setCurrentNamespace(namespace); - cacheRefElement(context.evalNode("cache-ref")); - cacheElement(context.evalNode("cache")); - parameterMapElement(context.evalNodes("/mapper/parameterMap")); - resultMapElements(context.evalNodes("/mapper/resultMap")); - sqlElement(context.evalNodes("/mapper/sql")); - buildStatementFromContext(context - .evalNodes("select|insert|update|delete")); - } catch (Exception e) { - throw new BuilderException("Error parsing Mapper XML. Cause: " + e, - e); - } - } - - private void buildStatementFromContext(List list) { - if (configuration.getDatabaseId() != null) { - buildStatementFromContext(list, configuration.getDatabaseId()); - } - buildStatementFromContext(list, null); - } - - private void buildStatementFromContext(List list, - String requiredDatabaseId) { - for (XNode context : list) { - final XMLStatementBuilder statementParser = new XMLStatementBuilder( - configuration, builderAssistant, context, - requiredDatabaseId); - try { - statementParser.parseStatementNode(); - } catch (IncompleteElementException e) { - configuration.addIncompleteStatement(statementParser); - } - } - } - - private void parsePendingResultMaps() { - Collection incompleteResultMaps = configuration - .getIncompleteResultMaps(); - synchronized (incompleteResultMaps) { - Iterator iter = incompleteResultMaps.iterator(); - while (iter.hasNext()) { - try { - iter.next().resolve(); - iter.remove(); - } catch (IncompleteElementException e) { - // ResultMap is still missing a resource... - } - } - } - } - - private void parsePendingChacheRefs() { - Collection incompleteCacheRefs = configuration - .getIncompleteCacheRefs(); - synchronized (incompleteCacheRefs) { - Iterator iter = incompleteCacheRefs.iterator(); - while (iter.hasNext()) { - try { - iter.next().resolveCacheRef(); - iter.remove(); - } catch (IncompleteElementException e) { - // Cache ref is still missing a resource... - } - } - } - } - - private void parsePendingStatements() { - Collection incompleteStatements = configuration - .getIncompleteStatements(); - synchronized (incompleteStatements) { - Iterator iter = incompleteStatements - .iterator(); - while (iter.hasNext()) { - try { - iter.next().parseStatementNode(); - iter.remove(); - } catch (IncompleteElementException e) { - // Statement is still missing a resource... - } - } - } - } - - private void cacheRefElement(XNode context) { - if (context != null) { - configuration.addCacheRef(builderAssistant.getCurrentNamespace(), - context.getStringAttribute("namespace")); - CacheRefResolver cacheRefResolver = new CacheRefResolver( - builderAssistant, context.getStringAttribute("namespace")); - try { - cacheRefResolver.resolveCacheRef(); - } catch (IncompleteElementException e) { - configuration.addIncompleteCacheRef(cacheRefResolver); - } - } - } - - private void cacheElement(XNode context) throws Exception { - if (context != null) { - String type = context.getStringAttribute("type", "PERPETUAL"); - Class typeClass = typeAliasRegistry - .resolveAlias(type); - String eviction = context.getStringAttribute("eviction", "LRU"); - Class evictionClass = typeAliasRegistry - .resolveAlias(eviction); - Long flushInterval = context.getLongAttribute("flushInterval"); - Integer size = context.getIntAttribute("size"); - boolean readWrite = !context.getBooleanAttribute("readOnly", false); - Properties props = context.getChildrenAsProperties(); - builderAssistant.useNewCache(typeClass, evictionClass, - flushInterval, size, readWrite, props); - } - } - - private void parameterMapElement(List list) throws Exception { - for (XNode parameterMapNode : list) { - String id = parameterMapNode.getStringAttribute("id"); - String type = parameterMapNode.getStringAttribute("type"); - Class parameterClass = resolveClass(type); - List parameterNodes = parameterMapNode - .evalNodes("parameter"); - List parameterMappings = new ArrayList(); - for (XNode parameterNode : parameterNodes) { - String property = parameterNode.getStringAttribute("property"); - String javaType = parameterNode.getStringAttribute("javaType"); - String jdbcType = parameterNode.getStringAttribute("jdbcType"); - String resultMap = parameterNode - .getStringAttribute("resultMap"); - String mode = parameterNode.getStringAttribute("mode"); - String typeHandler = parameterNode - .getStringAttribute("typeHandler"); - Integer numericScale = parameterNode - .getIntAttribute("numericScale"); - ParameterMode modeEnum = resolveParameterMode(mode); - Class javaTypeClass = resolveClass(javaType); - JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType); - @SuppressWarnings("unchecked") - Class> typeHandlerClass = (Class>) resolveClass(typeHandler); - ParameterMapping parameterMapping = builderAssistant - .buildParameterMapping(parameterClass, property, - javaTypeClass, jdbcTypeEnum, resultMap, - modeEnum, typeHandlerClass, numericScale); - parameterMappings.add(parameterMapping); - } - builderAssistant.addParameterMap(id, parameterClass, - parameterMappings); - } - } - - private void resultMapElements(List list) throws Exception { - for (XNode resultMapNode : list) { - try { - resultMapElement(resultMapNode); - } catch (IncompleteElementException e) { - // ignore, it will be retried - } - } - } - - private ResultMap resultMapElement(XNode resultMapNode) throws Exception { - return resultMapElement(resultMapNode, - Collections. emptyList()); - } - - private ResultMap resultMapElement(XNode resultMapNode, - List additionalResultMappings) throws Exception { - ErrorContext.instance().activity( - "processing " + resultMapNode.getValueBasedIdentifier()); - String id = resultMapNode.getStringAttribute("id", - resultMapNode.getValueBasedIdentifier()); - String type = resultMapNode.getStringAttribute("type", resultMapNode - .getStringAttribute("ofType", resultMapNode.getStringAttribute( - "resultType", - resultMapNode.getStringAttribute("javaType")))); - String extend = resultMapNode.getStringAttribute("extends"); - Boolean autoMapping = resultMapNode.getBooleanAttribute("autoMapping"); - Class typeClass = resolveClass(type); - Discriminator discriminator = null; - List resultMappings = new ArrayList(); - resultMappings.addAll(additionalResultMappings); - List resultChildren = resultMapNode.getChildren(); - for (XNode resultChild : resultChildren) { - if ("constructor".equals(resultChild.getName())) { - processConstructorElement(resultChild, typeClass, - resultMappings); - } else if ("discriminator".equals(resultChild.getName())) { - discriminator = processDiscriminatorElement(resultChild, - typeClass, resultMappings); - } else { - ArrayList flags = new ArrayList(); - if ("id".equals(resultChild.getName())) { - flags.add(ResultFlag.ID); - } - resultMappings.add(buildResultMappingFromContext(resultChild, - typeClass, flags)); - } - } - ResultMapResolver resultMapResolver = new ResultMapResolver( - builderAssistant, id, typeClass, extend, discriminator, - resultMappings, autoMapping); - try { - return resultMapResolver.resolve(); - } catch (IncompleteElementException e) { - configuration.addIncompleteResultMap(resultMapResolver); - throw e; - } - } - - private void processConstructorElement(XNode resultChild, - Class resultType, List resultMappings) - throws Exception { - List argChildren = resultChild.getChildren(); - for (XNode argChild : argChildren) { - ArrayList flags = new ArrayList(); - flags.add(ResultFlag.CONSTRUCTOR); - if ("idArg".equals(argChild.getName())) { - flags.add(ResultFlag.ID); - } - resultMappings.add(buildResultMappingFromContext(argChild, - resultType, flags)); - } - } - - private Discriminator processDiscriminatorElement(XNode context, - Class resultType, List resultMappings) - throws Exception { - String column = context.getStringAttribute("column"); - String javaType = context.getStringAttribute("javaType"); - String jdbcType = context.getStringAttribute("jdbcType"); - String typeHandler = context.getStringAttribute("typeHandler"); - Class javaTypeClass = resolveClass(javaType); - @SuppressWarnings("unchecked") - Class> typeHandlerClass = (Class>) resolveClass(typeHandler); - JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType); - Map discriminatorMap = new HashMap(); - for (XNode caseChild : context.getChildren()) { - String value = caseChild.getStringAttribute("value"); - String resultMap = caseChild.getStringAttribute("resultMap", - processNestedResultMappings(caseChild, resultMappings)); - discriminatorMap.put(value, resultMap); - } - return builderAssistant - .buildDiscriminator(resultType, column, javaTypeClass, - jdbcTypeEnum, typeHandlerClass, discriminatorMap); - } - - private void sqlElement(List list) throws Exception { - if (configuration.getDatabaseId() != null) { - sqlElement(list, configuration.getDatabaseId()); - } - sqlElement(list, null); - } - - private void sqlElement(List list, String requiredDatabaseId) - throws Exception { - for (XNode context : list) { - String databaseId = context.getStringAttribute("databaseId"); - String id = context.getStringAttribute("id"); - id = builderAssistant.applyCurrentNamespace(id, false); - if (databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId)) - sqlFragments.put(id, context); - } - } - - private boolean databaseIdMatchesCurrent(String id, String databaseId, - String requiredDatabaseId) { - if (requiredDatabaseId != null) { - if (!requiredDatabaseId.equals(databaseId)) { - return false; - } - } else { - if (databaseId != null) { - return false; - } - // skip this fragment if there is a previous one with a not null - // databaseId - if (this.sqlFragments.containsKey(id)) { - XNode context = this.sqlFragments.get(id); - if (context.getStringAttribute("databaseId") != null) { - return false; - } - } - } - return true; - } - - private ResultMapping buildResultMappingFromContext(XNode context, - Class resultType, ArrayList flags) throws Exception { - String property = context.getStringAttribute("property"); - String column = context.getStringAttribute("column"); - String javaType = context.getStringAttribute("javaType"); - String jdbcType = context.getStringAttribute("jdbcType"); - String nestedSelect = context.getStringAttribute("select"); - String nestedResultMap = context.getStringAttribute( - "resultMap", - processNestedResultMappings(context, - Collections. emptyList())); - String notNullColumn = context.getStringAttribute("notNullColumn"); - String columnPrefix = context.getStringAttribute("columnPrefix"); - String typeHandler = context.getStringAttribute("typeHandler"); - String resulSet = context.getStringAttribute("resultSet"); - String foreignColumn = context.getStringAttribute("foreignColumn"); - boolean lazy = "lazy".equals(context.getStringAttribute("fetchType", - configuration.isLazyLoadingEnabled() ? "lazy" : "eager")); - Class javaTypeClass = resolveClass(javaType); - @SuppressWarnings("unchecked") - Class> typeHandlerClass = (Class>) resolveClass(typeHandler); - JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType); - return builderAssistant.buildResultMapping(resultType, property, - column, javaTypeClass, jdbcTypeEnum, nestedSelect, - nestedResultMap, notNullColumn, columnPrefix, typeHandlerClass, - flags, resulSet, foreignColumn, lazy); - } - - private String processNestedResultMappings(XNode context, - List resultMappings) throws Exception { - if ("association".equals(context.getName()) - || "collection".equals(context.getName()) - || "case".equals(context.getName())) { - if (context.getStringAttribute("select") == null) { - ResultMap resultMap = resultMapElement(context, resultMappings); - return resultMap.getId(); - } - } - return null; - } - - private void bindMapperForNamespace() { - String namespace = builderAssistant.getCurrentNamespace(); - if (namespace != null) { - Class boundType = null; - try { - boundType = Resources.classForName(namespace); - } catch (ClassNotFoundException e) { - // ignore, bound type is not required - } - if (boundType != null) { - if (!configuration.hasMapper(boundType)) { - // Spring may not know the real resource name so we set a - // flag - // to prevent loading again this resource from the mapper - // interface - // look at MapperAnnotationBuilder#loadXmlResource - configuration.addLoadedResource("namespace:" + namespace); - configuration.addMapper(boundType); - } - } - } - } - -} +/* + * Copyright 2009-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ibatis.builder.xml; + +import java.io.InputStream; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.ibatis.builder.BaseBuilder; +import org.apache.ibatis.builder.BuilderException; +import org.apache.ibatis.builder.CacheRefResolver; +import org.apache.ibatis.builder.IncompleteElementException; +import org.apache.ibatis.builder.MapperBuilderAssistant; +import org.apache.ibatis.builder.ResultMapResolver; +import org.apache.ibatis.cache.Cache; +import org.apache.ibatis.executor.ErrorContext; +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.mapping.Discriminator; +import org.apache.ibatis.mapping.ParameterMapping; +import org.apache.ibatis.mapping.ParameterMode; +import org.apache.ibatis.mapping.ResultFlag; +import org.apache.ibatis.mapping.ResultMap; +import org.apache.ibatis.mapping.ResultMapping; +import org.apache.ibatis.parsing.XNode; +import org.apache.ibatis.parsing.XPathParser; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.TypeHandler; + +/** + * @author Clinton Begin + * @description 增加解析方法,原方法不解析相同的resource + */ +public class XMLMapperBuilder extends BaseBuilder { + + private XPathParser parser; + private MapperBuilderAssistant builderAssistant; + private Map sqlFragments; + private String resource; + + @Deprecated + public XMLMapperBuilder(Reader reader, Configuration configuration, + String resource, Map sqlFragments, String namespace) { + this(reader, configuration, resource, sqlFragments); + this.builderAssistant.setCurrentNamespace(namespace); + } + + @Deprecated + public XMLMapperBuilder(Reader reader, Configuration configuration, + String resource, Map sqlFragments) { + this(new XPathParser(reader, true, configuration.getVariables(), + new XMLMapperEntityResolver()), configuration, resource, + sqlFragments); + } + + public XMLMapperBuilder(InputStream inputStream, + Configuration configuration, String resource, + Map sqlFragments, String namespace) { + this(inputStream, configuration, resource, sqlFragments); + this.builderAssistant.setCurrentNamespace(namespace); + } + + public XMLMapperBuilder(InputStream inputStream, + Configuration configuration, String resource, + Map sqlFragments) { + this(new XPathParser(inputStream, true, configuration.getVariables(), + new XMLMapperEntityResolver()), configuration, resource, + sqlFragments); + } + + private XMLMapperBuilder(XPathParser parser, Configuration configuration, + String resource, Map sqlFragments) { + super(configuration); + this.builderAssistant = new MapperBuilderAssistant(configuration, + resource); + this.parser = parser; + this.sqlFragments = sqlFragments; + this.resource = resource; + } + + public void parse() { + if (!configuration.isResourceLoaded(resource)) { + configurationElement(parser.evalNode("/mapper")); + configuration.addLoadedResource(resource); + bindMapperForNamespace(); + } + + parsePendingResultMaps(); + parsePendingChacheRefs(); + parsePendingStatements(); + } + + // TODO 增加解析方法,原方法不解析相同的resource + public void parse1() { + // if (!configuration.isResourceLoaded(resource)) { + configurationElement(parser.evalNode("/mapper")); + configuration.addLoadedResource(resource); + bindMapperForNamespace(); + // } + + parsePendingResultMaps(); + parsePendingChacheRefs(); + parsePendingStatements(); + } + + public XNode getSqlFragment(String refid) { + return sqlFragments.get(refid); + } + + private void configurationElement(XNode context) { + try { + String namespace = context.getStringAttribute("namespace"); + if (namespace.equals("")) { + throw new BuilderException("Mapper's namespace cannot be empty"); + } + builderAssistant.setCurrentNamespace(namespace); + cacheRefElement(context.evalNode("cache-ref")); + cacheElement(context.evalNode("cache")); + parameterMapElement(context.evalNodes("/mapper/parameterMap")); + resultMapElements(context.evalNodes("/mapper/resultMap")); + sqlElement(context.evalNodes("/mapper/sql")); + buildStatementFromContext(context + .evalNodes("select|insert|update|delete")); + } catch (Exception e) { + throw new BuilderException("Error parsing Mapper XML. Cause: " + e, + e); + } + } + + private void buildStatementFromContext(List list) { + if (configuration.getDatabaseId() != null) { + buildStatementFromContext(list, configuration.getDatabaseId()); + } + buildStatementFromContext(list, null); + } + + private void buildStatementFromContext(List list, + String requiredDatabaseId) { + for (XNode context : list) { + final XMLStatementBuilder statementParser = new XMLStatementBuilder( + configuration, builderAssistant, context, + requiredDatabaseId); + try { + statementParser.parseStatementNode(); + } catch (IncompleteElementException e) { + configuration.addIncompleteStatement(statementParser); + } + } + } + + private void parsePendingResultMaps() { + Collection incompleteResultMaps = configuration + .getIncompleteResultMaps(); + synchronized (incompleteResultMaps) { + Iterator iter = incompleteResultMaps.iterator(); + while (iter.hasNext()) { + try { + iter.next().resolve(); + iter.remove(); + } catch (IncompleteElementException e) { + // ResultMap is still missing a resource... + } + } + } + } + + private void parsePendingChacheRefs() { + Collection incompleteCacheRefs = configuration + .getIncompleteCacheRefs(); + synchronized (incompleteCacheRefs) { + Iterator iter = incompleteCacheRefs.iterator(); + while (iter.hasNext()) { + try { + iter.next().resolveCacheRef(); + iter.remove(); + } catch (IncompleteElementException e) { + // Cache ref is still missing a resource... + } + } + } + } + + private void parsePendingStatements() { + Collection incompleteStatements = configuration + .getIncompleteStatements(); + synchronized (incompleteStatements) { + Iterator iter = incompleteStatements + .iterator(); + while (iter.hasNext()) { + try { + iter.next().parseStatementNode(); + iter.remove(); + } catch (IncompleteElementException e) { + // Statement is still missing a resource... + } + } + } + } + + private void cacheRefElement(XNode context) { + if (context != null) { + configuration.addCacheRef(builderAssistant.getCurrentNamespace(), + context.getStringAttribute("namespace")); + CacheRefResolver cacheRefResolver = new CacheRefResolver( + builderAssistant, context.getStringAttribute("namespace")); + try { + cacheRefResolver.resolveCacheRef(); + } catch (IncompleteElementException e) { + configuration.addIncompleteCacheRef(cacheRefResolver); + } + } + } + + private void cacheElement(XNode context) throws Exception { + if (context != null) { + String type = context.getStringAttribute("type", "PERPETUAL"); + Class typeClass = typeAliasRegistry + .resolveAlias(type); + String eviction = context.getStringAttribute("eviction", "LRU"); + Class evictionClass = typeAliasRegistry + .resolveAlias(eviction); + Long flushInterval = context.getLongAttribute("flushInterval"); + Integer size = context.getIntAttribute("size"); + boolean readWrite = !context.getBooleanAttribute("readOnly", false); + boolean blocking = context.getBooleanAttribute("blocking", false); + Properties props = context.getChildrenAsProperties(); + builderAssistant.useNewCache(typeClass, evictionClass, + flushInterval, size, readWrite, blocking, props); + } + } + + private void parameterMapElement(List list) throws Exception { + for (XNode parameterMapNode : list) { + String id = parameterMapNode.getStringAttribute("id"); + String type = parameterMapNode.getStringAttribute("type"); + Class parameterClass = resolveClass(type); + List parameterNodes = parameterMapNode + .evalNodes("parameter"); + List parameterMappings = new ArrayList(); + for (XNode parameterNode : parameterNodes) { + String property = parameterNode.getStringAttribute("property"); + String javaType = parameterNode.getStringAttribute("javaType"); + String jdbcType = parameterNode.getStringAttribute("jdbcType"); + String resultMap = parameterNode + .getStringAttribute("resultMap"); + String mode = parameterNode.getStringAttribute("mode"); + String typeHandler = parameterNode + .getStringAttribute("typeHandler"); + Integer numericScale = parameterNode + .getIntAttribute("numericScale"); + ParameterMode modeEnum = resolveParameterMode(mode); + Class javaTypeClass = resolveClass(javaType); + JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType); + @SuppressWarnings("unchecked") + Class> typeHandlerClass = (Class>) resolveClass(typeHandler); + ParameterMapping parameterMapping = builderAssistant + .buildParameterMapping(parameterClass, property, + javaTypeClass, jdbcTypeEnum, resultMap, + modeEnum, typeHandlerClass, numericScale); + parameterMappings.add(parameterMapping); + } + builderAssistant.addParameterMap(id, parameterClass, + parameterMappings); + } + } + + private void resultMapElements(List list) throws Exception { + for (XNode resultMapNode : list) { + try { + resultMapElement(resultMapNode); + } catch (IncompleteElementException e) { + // ignore, it will be retried + } + } + } + + private ResultMap resultMapElement(XNode resultMapNode) throws Exception { + return resultMapElement(resultMapNode, + Collections. emptyList()); + } + + private ResultMap resultMapElement(XNode resultMapNode, + List additionalResultMappings) throws Exception { + ErrorContext.instance().activity( + "processing " + resultMapNode.getValueBasedIdentifier()); + String id = resultMapNode.getStringAttribute("id", + resultMapNode.getValueBasedIdentifier()); + String type = resultMapNode.getStringAttribute("type", resultMapNode + .getStringAttribute("ofType", resultMapNode.getStringAttribute( + "resultType", + resultMapNode.getStringAttribute("javaType")))); + String extend = resultMapNode.getStringAttribute("extends"); + Boolean autoMapping = resultMapNode.getBooleanAttribute("autoMapping"); + Class typeClass = resolveClass(type); + Discriminator discriminator = null; + List resultMappings = new ArrayList(); + resultMappings.addAll(additionalResultMappings); + List resultChildren = resultMapNode.getChildren(); + for (XNode resultChild : resultChildren) { + if ("constructor".equals(resultChild.getName())) { + processConstructorElement(resultChild, typeClass, + resultMappings); + } else if ("discriminator".equals(resultChild.getName())) { + discriminator = processDiscriminatorElement(resultChild, + typeClass, resultMappings); + } else { + ArrayList flags = new ArrayList(); + if ("id".equals(resultChild.getName())) { + flags.add(ResultFlag.ID); + } + resultMappings.add(buildResultMappingFromContext(resultChild, + typeClass, flags)); + } + } + ResultMapResolver resultMapResolver = new ResultMapResolver( + builderAssistant, id, typeClass, extend, discriminator, + resultMappings, autoMapping); + try { + return resultMapResolver.resolve(); + } catch (IncompleteElementException e) { + configuration.addIncompleteResultMap(resultMapResolver); + throw e; + } + } + + private void processConstructorElement(XNode resultChild, + Class resultType, List resultMappings) + throws Exception { + List argChildren = resultChild.getChildren(); + for (XNode argChild : argChildren) { + ArrayList flags = new ArrayList(); + flags.add(ResultFlag.CONSTRUCTOR); + if ("idArg".equals(argChild.getName())) { + flags.add(ResultFlag.ID); + } + resultMappings.add(buildResultMappingFromContext(argChild, + resultType, flags)); + } + } + + private Discriminator processDiscriminatorElement(XNode context, + Class resultType, List resultMappings) + throws Exception { + String column = context.getStringAttribute("column"); + String javaType = context.getStringAttribute("javaType"); + String jdbcType = context.getStringAttribute("jdbcType"); + String typeHandler = context.getStringAttribute("typeHandler"); + Class javaTypeClass = resolveClass(javaType); + @SuppressWarnings("unchecked") + Class> typeHandlerClass = (Class>) resolveClass(typeHandler); + JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType); + Map discriminatorMap = new HashMap(); + for (XNode caseChild : context.getChildren()) { + String value = caseChild.getStringAttribute("value"); + String resultMap = caseChild.getStringAttribute("resultMap", + processNestedResultMappings(caseChild, resultMappings)); + discriminatorMap.put(value, resultMap); + } + return builderAssistant + .buildDiscriminator(resultType, column, javaTypeClass, + jdbcTypeEnum, typeHandlerClass, discriminatorMap); + } + + private void sqlElement(List list) throws Exception { + if (configuration.getDatabaseId() != null) { + sqlElement(list, configuration.getDatabaseId()); + } + sqlElement(list, null); + } + + private void sqlElement(List list, String requiredDatabaseId) + throws Exception { + for (XNode context : list) { + String databaseId = context.getStringAttribute("databaseId"); + String id = context.getStringAttribute("id"); + id = builderAssistant.applyCurrentNamespace(id, false); + if (databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId)) + sqlFragments.put(id, context); + } + } + + private boolean databaseIdMatchesCurrent(String id, String databaseId, + String requiredDatabaseId) { + if (requiredDatabaseId != null) { + if (!requiredDatabaseId.equals(databaseId)) { + return false; + } + } else { + if (databaseId != null) { + return false; + } + // skip this fragment if there is a previous one with a not null + // databaseId + if (this.sqlFragments.containsKey(id)) { + XNode context = this.sqlFragments.get(id); + if (context.getStringAttribute("databaseId") != null) { + return false; + } + } + } + return true; + } + + private ResultMapping buildResultMappingFromContext(XNode context, + Class resultType, ArrayList flags) throws Exception { + String property = context.getStringAttribute("property"); + String column = context.getStringAttribute("column"); + String javaType = context.getStringAttribute("javaType"); + String jdbcType = context.getStringAttribute("jdbcType"); + String nestedSelect = context.getStringAttribute("select"); + String nestedResultMap = context.getStringAttribute( + "resultMap", + processNestedResultMappings(context, + Collections. emptyList())); + String notNullColumn = context.getStringAttribute("notNullColumn"); + String columnPrefix = context.getStringAttribute("columnPrefix"); + String typeHandler = context.getStringAttribute("typeHandler"); + String resulSet = context.getStringAttribute("resultSet"); + String foreignColumn = context.getStringAttribute("foreignColumn"); + boolean lazy = "lazy".equals(context.getStringAttribute("fetchType", + configuration.isLazyLoadingEnabled() ? "lazy" : "eager")); + Class javaTypeClass = resolveClass(javaType); + @SuppressWarnings("unchecked") + Class> typeHandlerClass = (Class>) resolveClass(typeHandler); + JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType); + return builderAssistant.buildResultMapping(resultType, property, + column, javaTypeClass, jdbcTypeEnum, nestedSelect, + nestedResultMap, notNullColumn, columnPrefix, typeHandlerClass, + flags, resulSet, foreignColumn, lazy); + } + + private String processNestedResultMappings(XNode context, + List resultMappings) throws Exception { + if ("association".equals(context.getName()) + || "collection".equals(context.getName()) + || "case".equals(context.getName())) { + if (context.getStringAttribute("select") == null) { + ResultMap resultMap = resultMapElement(context, resultMappings); + return resultMap.getId(); + } + } + return null; + } + + private void bindMapperForNamespace() { + String namespace = builderAssistant.getCurrentNamespace(); + if (namespace != null) { + Class boundType = null; + try { + boundType = Resources.classForName(namespace); + } catch (ClassNotFoundException e) { + // ignore, bound type is not required + } + if (boundType != null) { + if (!configuration.hasMapper(boundType)) { + // Spring may not know the real resource name so we set a + // flag + // to prevent loading again this resource from the mapper + // interface + // look at MapperAnnotationBuilder#loadXmlResource + configuration.addLoadedResource("namespace:" + namespace); + configuration.addMapper(boundType); + } + } + } + } + +} diff --git a/src/main/java/org/apache/ibatis/session/Configuration.java b/src/main/java/org/apache/ibatis/session/Configuration.java index ffcef8318e..bd93930a72 100644 --- a/src/main/java/org/apache/ibatis/session/Configuration.java +++ b/src/main/java/org/apache/ibatis/session/Configuration.java @@ -1,881 +1,901 @@ -/* - * Copyright 2009-2014 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ibatis.session; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import org.apache.ibatis.binding.MapperRegistry; -import org.apache.ibatis.builder.CacheRefResolver; -import org.apache.ibatis.builder.ResultMapResolver; -import org.apache.ibatis.builder.annotation.MethodResolver; -import org.apache.ibatis.builder.xml.XMLStatementBuilder; -import org.apache.ibatis.cache.Cache; -import org.apache.ibatis.cache.decorators.FifoCache; -import org.apache.ibatis.cache.decorators.LruCache; -import org.apache.ibatis.cache.decorators.SoftCache; -import org.apache.ibatis.cache.decorators.WeakCache; -import org.apache.ibatis.cache.impl.PerpetualCache; -import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory; -import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory; -import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory; -import org.apache.ibatis.executor.BatchExecutor; -import org.apache.ibatis.executor.CachingExecutor; -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.executor.ReuseExecutor; -import org.apache.ibatis.executor.SimpleExecutor; -import org.apache.ibatis.executor.keygen.KeyGenerator; -import org.apache.ibatis.executor.loader.ProxyFactory; -import org.apache.ibatis.executor.loader.cglib.CglibProxyFactory; -import org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory; -import org.apache.ibatis.executor.parameter.ParameterHandler; -import org.apache.ibatis.executor.resultset.DefaultResultSetHandler; -import org.apache.ibatis.executor.resultset.ResultSetHandler; -import org.apache.ibatis.executor.statement.RoutingStatementHandler; -import org.apache.ibatis.executor.statement.StatementHandler; -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.logging.LogFactory; -import org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl; -import org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl; -import org.apache.ibatis.logging.log4j.Log4jImpl; -import org.apache.ibatis.logging.log4j2.Log4j2Impl; -import org.apache.ibatis.logging.nologging.NoLoggingImpl; -import org.apache.ibatis.logging.slf4j.Slf4jImpl; -import org.apache.ibatis.logging.stdout.StdOutImpl; -import org.apache.ibatis.mapping.BoundSql; -import org.apache.ibatis.mapping.Environment; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.mapping.ParameterMap; -import org.apache.ibatis.mapping.ResultMap; -import org.apache.ibatis.mapping.VendorDatabaseIdProvider; -import org.apache.ibatis.parsing.XNode; -import org.apache.ibatis.plugin.Interceptor; -import org.apache.ibatis.plugin.InterceptorChain; -import org.apache.ibatis.reflection.MetaObject; -import org.apache.ibatis.reflection.factory.DefaultObjectFactory; -import org.apache.ibatis.reflection.factory.ObjectFactory; -import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory; -import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; -import org.apache.ibatis.scripting.LanguageDriver; -import org.apache.ibatis.scripting.LanguageDriverRegistry; -import org.apache.ibatis.scripting.defaults.RawLanguageDriver; -import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver; -import org.apache.ibatis.transaction.Transaction; -import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; -import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; -import org.apache.ibatis.type.JdbcType; -import org.apache.ibatis.type.TypeAliasRegistry; -import org.apache.ibatis.type.TypeHandlerRegistry; - -/** - * @author Clinton Begin - * @description 重写put,实现刷新的功能 - */ -public class Configuration { - - protected Environment environment; - - protected boolean safeRowBoundsEnabled = false; - protected boolean safeResultHandlerEnabled = true; - protected boolean mapUnderscoreToCamelCase = false; - protected boolean aggressiveLazyLoading = true; - protected boolean multipleResultSetsEnabled = true; - protected boolean useGeneratedKeys = false; - protected boolean useColumnLabel = true; - protected boolean cacheEnabled = true; - protected boolean callSettersOnNulls = false; - protected String logPrefix; - protected Class logImpl; - protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION; - protected JdbcType jdbcTypeForNull = JdbcType.OTHER; - protected Set lazyLoadTriggerMethods = new HashSet( - Arrays.asList(new String[] { "equals", "clone", "hashCode", - "toString" })); - protected Integer defaultStatementTimeout; - protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE; - protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL; - - protected Properties variables = new Properties(); - protected ObjectFactory objectFactory = new DefaultObjectFactory(); - protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory(); - protected MapperRegistry mapperRegistry = new MapperRegistry(this); - - protected boolean lazyLoadingEnabled = false; - protected ProxyFactory proxyFactory; - - protected String databaseId; - /** - * Configuration factory class. Used to create Configuration for loading - * deserialized unread properties. - * - * @see Issue - * 300 (google code) - */ - protected Class configurationFactory; - - protected final InterceptorChain interceptorChain = new InterceptorChain(); - protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry(); - protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry(); - protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry(); - - protected final Map mappedStatements = new StrictMap( - "Mapped Statements collection"); - protected final Map caches = new StrictMap( - "Caches collection"); - protected final Map resultMaps = new StrictMap( - "Result Maps collection"); - protected final Map parameterMaps = new StrictMap( - "Parameter Maps collection"); - protected final Map keyGenerators = new StrictMap( - "Key Generators collection"); - - protected final Set loadedResources = new HashSet(); - protected final Map sqlFragments = new StrictMap( - "XML fragments parsed from previous mappers"); - - protected final Collection incompleteStatements = new LinkedList(); - protected final Collection incompleteCacheRefs = new LinkedList(); - protected final Collection incompleteResultMaps = new LinkedList(); - protected final Collection incompleteMethods = new LinkedList(); - - /* - * A map holds cache-ref relationship. The key is the namespace that - * references a cache bound to another namespace and the value is the - * namespace which the actual cache is bound to. - */ - protected final Map cacheRefMap = new HashMap(); - - public Configuration(Environment environment) { - this(); - this.environment = environment; - } - - public Configuration() { - typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class); - typeAliasRegistry.registerAlias("MANAGED", - ManagedTransactionFactory.class); - - typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class); - typeAliasRegistry - .registerAlias("POOLED", PooledDataSourceFactory.class); - typeAliasRegistry.registerAlias("UNPOOLED", - UnpooledDataSourceFactory.class); - - typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class); - typeAliasRegistry.registerAlias("FIFO", FifoCache.class); - typeAliasRegistry.registerAlias("LRU", LruCache.class); - typeAliasRegistry.registerAlias("SOFT", SoftCache.class); - typeAliasRegistry.registerAlias("WEAK", WeakCache.class); - - typeAliasRegistry.registerAlias("DB_VENDOR", - VendorDatabaseIdProvider.class); - - typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class); - typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class); - - typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class); - typeAliasRegistry.registerAlias("COMMONS_LOGGING", - JakartaCommonsLoggingImpl.class); - typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class); - typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class); - typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class); - typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class); - typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class); - - typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class); - typeAliasRegistry.registerAlias("JAVASSIST", - JavassistProxyFactory.class); - - languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class); - languageRegistry.register(RawLanguageDriver.class); - } - - public String getLogPrefix() { - return logPrefix; - } - - public void setLogPrefix(String logPrefix) { - this.logPrefix = logPrefix; - } - - public Class getLogImpl() { - return logImpl; - } - - @SuppressWarnings("unchecked") - public void setLogImpl(Class logImpl) { - if (logImpl != null) { - this.logImpl = (Class) logImpl; - LogFactory.useCustomLogging(this.logImpl); - } - } - - public boolean isCallSettersOnNulls() { - return callSettersOnNulls; - } - - public void setCallSettersOnNulls(boolean callSettersOnNulls) { - this.callSettersOnNulls = callSettersOnNulls; - } - - public String getDatabaseId() { - return databaseId; - } - - public void setDatabaseId(String databaseId) { - this.databaseId = databaseId; - } - - public Class getConfigurationFactory() { - return configurationFactory; - } - - public void setConfigurationFactory(Class configurationFactory) { - this.configurationFactory = configurationFactory; - } - - public boolean isSafeResultHandlerEnabled() { - return safeResultHandlerEnabled; - } - - public void setSafeResultHandlerEnabled(boolean safeResultHandlerEnabled) { - this.safeResultHandlerEnabled = safeResultHandlerEnabled; - } - - public boolean isSafeRowBoundsEnabled() { - return safeRowBoundsEnabled; - } - - public void setSafeRowBoundsEnabled(boolean safeRowBoundsEnabled) { - this.safeRowBoundsEnabled = safeRowBoundsEnabled; - } - - public boolean isMapUnderscoreToCamelCase() { - return mapUnderscoreToCamelCase; - } - - public void setMapUnderscoreToCamelCase(boolean mapUnderscoreToCamelCase) { - this.mapUnderscoreToCamelCase = mapUnderscoreToCamelCase; - } - - public void addLoadedResource(String resource) { - loadedResources.add(resource); - } - - public boolean isResourceLoaded(String resource) { - return loadedResources.contains(resource); - } - - public Environment getEnvironment() { - return environment; - } - - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - public AutoMappingBehavior getAutoMappingBehavior() { - return autoMappingBehavior; - } - - public void setAutoMappingBehavior(AutoMappingBehavior autoMappingBehavior) { - this.autoMappingBehavior = autoMappingBehavior; - } - - public boolean isLazyLoadingEnabled() { - return lazyLoadingEnabled; - } - - public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) { - this.lazyLoadingEnabled = lazyLoadingEnabled; - } - - public ProxyFactory getProxyFactory() { - if (proxyFactory == null) { - // makes sure CGLIB is not needed unless explicitly requested - proxyFactory = new CglibProxyFactory(); - } - return proxyFactory; - } - - public void setProxyFactory(ProxyFactory proxyFactory) { - this.proxyFactory = proxyFactory; - } - - public boolean isAggressiveLazyLoading() { - return aggressiveLazyLoading; - } - - public void setAggressiveLazyLoading(boolean aggressiveLazyLoading) { - this.aggressiveLazyLoading = aggressiveLazyLoading; - } - - public boolean isMultipleResultSetsEnabled() { - return multipleResultSetsEnabled; - } - - public void setMultipleResultSetsEnabled(boolean multipleResultSetsEnabled) { - this.multipleResultSetsEnabled = multipleResultSetsEnabled; - } - - public Set getLazyLoadTriggerMethods() { - return lazyLoadTriggerMethods; - } - - public void setLazyLoadTriggerMethods(Set lazyLoadTriggerMethods) { - this.lazyLoadTriggerMethods = lazyLoadTriggerMethods; - } - - public boolean isUseGeneratedKeys() { - return useGeneratedKeys; - } - - public void setUseGeneratedKeys(boolean useGeneratedKeys) { - this.useGeneratedKeys = useGeneratedKeys; - } - - public ExecutorType getDefaultExecutorType() { - return defaultExecutorType; - } - - public void setDefaultExecutorType(ExecutorType defaultExecutorType) { - this.defaultExecutorType = defaultExecutorType; - } - - public boolean isCacheEnabled() { - return cacheEnabled; - } - - public void setCacheEnabled(boolean cacheEnabled) { - this.cacheEnabled = cacheEnabled; - } - - public Integer getDefaultStatementTimeout() { - return defaultStatementTimeout; - } - - public void setDefaultStatementTimeout(Integer defaultStatementTimeout) { - this.defaultStatementTimeout = defaultStatementTimeout; - } - - public boolean isUseColumnLabel() { - return useColumnLabel; - } - - public void setUseColumnLabel(boolean useColumnLabel) { - this.useColumnLabel = useColumnLabel; - } - - public LocalCacheScope getLocalCacheScope() { - return localCacheScope; - } - - public void setLocalCacheScope(LocalCacheScope localCacheScope) { - this.localCacheScope = localCacheScope; - } - - public JdbcType getJdbcTypeForNull() { - return jdbcTypeForNull; - } - - public void setJdbcTypeForNull(JdbcType jdbcTypeForNull) { - this.jdbcTypeForNull = jdbcTypeForNull; - } - - public Properties getVariables() { - return variables; - } - - public void setVariables(Properties variables) { - this.variables = variables; - } - - public TypeHandlerRegistry getTypeHandlerRegistry() { - return typeHandlerRegistry; - } - - public TypeAliasRegistry getTypeAliasRegistry() { - return typeAliasRegistry; - } - - /** - * @since 3.2.2 - */ - public MapperRegistry getMapperRegistry() { - return mapperRegistry; - } - - public ObjectFactory getObjectFactory() { - return objectFactory; - } - - public void setObjectFactory(ObjectFactory objectFactory) { - this.objectFactory = objectFactory; - } - - public ObjectWrapperFactory getObjectWrapperFactory() { - return objectWrapperFactory; - } - - public void setObjectWrapperFactory( - ObjectWrapperFactory objectWrapperFactory) { - this.objectWrapperFactory = objectWrapperFactory; - } - - /** - * @since 3.2.2 - */ - public List getInterceptors() { - return interceptorChain.getInterceptors(); - } - - public LanguageDriverRegistry getLanguageRegistry() { - return languageRegistry; - } - - public void setDefaultScriptingLanguage(Class driver) { - if (driver == null) { - driver = XMLLanguageDriver.class; - } - getLanguageRegistry().setDefaultDriverClass(driver); - } - - public LanguageDriver getDefaultScriptingLanuageInstance() { - return languageRegistry.getDefaultDriver(); - } - - public MetaObject newMetaObject(Object object) { - return MetaObject - .forObject(object, objectFactory, objectWrapperFactory); - } - - public ParameterHandler newParameterHandler( - MappedStatement mappedStatement, Object parameterObject, - BoundSql boundSql) { - ParameterHandler parameterHandler = mappedStatement.getLang() - .createParameterHandler(mappedStatement, parameterObject, - boundSql); - parameterHandler = (ParameterHandler) interceptorChain - .pluginAll(parameterHandler); - return parameterHandler; - } - - public ResultSetHandler newResultSetHandler(Executor executor, - MappedStatement mappedStatement, RowBounds rowBounds, - ParameterHandler parameterHandler, ResultHandler resultHandler, - BoundSql boundSql) { - ResultSetHandler resultSetHandler = new DefaultResultSetHandler( - executor, mappedStatement, parameterHandler, resultHandler, - boundSql, rowBounds); - resultSetHandler = (ResultSetHandler) interceptorChain - .pluginAll(resultSetHandler); - return resultSetHandler; - } - - public StatementHandler newStatementHandler(Executor executor, - MappedStatement mappedStatement, Object parameterObject, - RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { - StatementHandler statementHandler = new RoutingStatementHandler( - executor, mappedStatement, parameterObject, rowBounds, - resultHandler, boundSql); - statementHandler = (StatementHandler) interceptorChain - .pluginAll(statementHandler); - return statementHandler; - } - - public Executor newExecutor(Transaction transaction) { - return newExecutor(transaction, defaultExecutorType); - } - - public Executor newExecutor(Transaction transaction, - ExecutorType executorType) { - executorType = executorType == null ? defaultExecutorType - : executorType; - executorType = executorType == null ? ExecutorType.SIMPLE - : executorType; - Executor executor; - if (ExecutorType.BATCH == executorType) { - executor = new BatchExecutor(this, transaction); - } else if (ExecutorType.REUSE == executorType) { - executor = new ReuseExecutor(this, transaction); - } else { - executor = new SimpleExecutor(this, transaction); - } - if (cacheEnabled) { - executor = new CachingExecutor(executor); - } - executor = (Executor) interceptorChain.pluginAll(executor); - return executor; - } - - public void addKeyGenerator(String id, KeyGenerator keyGenerator) { - keyGenerators.put(id, keyGenerator); - } - - public Collection getKeyGeneratorNames() { - return keyGenerators.keySet(); - } - - public Collection getKeyGenerators() { - return keyGenerators.values(); - } - - public KeyGenerator getKeyGenerator(String id) { - return keyGenerators.get(id); - } - - public boolean hasKeyGenerator(String id) { - return keyGenerators.containsKey(id); - } - - public void addCache(Cache cache) { - caches.put(cache.getId(), cache); - } - - public Collection getCacheNames() { - return caches.keySet(); - } - - public Collection getCaches() { - return caches.values(); - } - - public Cache getCache(String id) { - return caches.get(id); - } - - public boolean hasCache(String id) { - return caches.containsKey(id); - } - - public void addResultMap(ResultMap rm) { - resultMaps.put(rm.getId(), rm); - checkLocallyForDiscriminatedNestedResultMaps(rm); - checkGloballyForDiscriminatedNestedResultMaps(rm); - } - - public Collection getResultMapNames() { - return resultMaps.keySet(); - } - - public Collection getResultMaps() { - return resultMaps.values(); - } - - public ResultMap getResultMap(String id) { - return resultMaps.get(id); - } - - public boolean hasResultMap(String id) { - return resultMaps.containsKey(id); - } - - public void addParameterMap(ParameterMap pm) { - parameterMaps.put(pm.getId(), pm); - } - - public Collection getParameterMapNames() { - return parameterMaps.keySet(); - } - - public Collection getParameterMaps() { - return parameterMaps.values(); - } - - public ParameterMap getParameterMap(String id) { - return parameterMaps.get(id); - } - - public boolean hasParameterMap(String id) { - return parameterMaps.containsKey(id); - } - - public void addMappedStatement(MappedStatement ms) { - mappedStatements.put(ms.getId(), ms); - } - - public Collection getMappedStatementNames() { - buildAllStatements(); - return mappedStatements.keySet(); - } - - public Collection getMappedStatements() { - buildAllStatements(); - return mappedStatements.values(); - } - - public Collection getIncompleteStatements() { - return incompleteStatements; - } - - public void addIncompleteStatement(XMLStatementBuilder incompleteStatement) { - incompleteStatements.add(incompleteStatement); - } - - public Collection getIncompleteCacheRefs() { - return incompleteCacheRefs; - } - - public void addIncompleteCacheRef(CacheRefResolver incompleteCacheRef) { - incompleteCacheRefs.add(incompleteCacheRef); - } - - public Collection getIncompleteResultMaps() { - return incompleteResultMaps; - } - - public void addIncompleteResultMap(ResultMapResolver resultMapResolver) { - incompleteResultMaps.add(resultMapResolver); - } - - public void addIncompleteMethod(MethodResolver builder) { - incompleteMethods.add(builder); - } - - public Collection getIncompleteMethods() { - return incompleteMethods; - } - - public MappedStatement getMappedStatement(String id) { - return this.getMappedStatement(id, true); - } - - public MappedStatement getMappedStatement(String id, - boolean validateIncompleteStatements) { - if (validateIncompleteStatements) { - buildAllStatements(); - } - return mappedStatements.get(id); - } - - public Map getSqlFragments() { - return sqlFragments; - } - - public void addInterceptor(Interceptor interceptor) { - interceptorChain.addInterceptor(interceptor); - } - - public void addMappers(String packageName, Class superType) { - mapperRegistry.addMappers(packageName, superType); - } - - public void addMappers(String packageName) { - mapperRegistry.addMappers(packageName); - } - - public void addMapper(Class type) { - mapperRegistry.addMapper(type); - } - - public T getMapper(Class type, SqlSession sqlSession) { - return mapperRegistry.getMapper(type, sqlSession); - } - - public boolean hasMapper(Class type) { - return mapperRegistry.hasMapper(type); - } - - public boolean hasStatement(String statementName) { - return hasStatement(statementName, true); - } - - public boolean hasStatement(String statementName, - boolean validateIncompleteStatements) { - if (validateIncompleteStatements) { - buildAllStatements(); - } - return mappedStatements.containsKey(statementName); - } - - public void addCacheRef(String namespace, String referencedNamespace) { - cacheRefMap.put(namespace, referencedNamespace); - } - - /* - * Parses all the unprocessed statement nodes in the cache. It is - * recommended to call this method once all the mappers are added as it - * provides fail-fast statement validation. - */ - protected void buildAllStatements() { - if (!incompleteResultMaps.isEmpty()) { - synchronized (incompleteResultMaps) { - // This always throws a BuilderException. - incompleteResultMaps.iterator().next().resolve(); - } - } - if (!incompleteCacheRefs.isEmpty()) { - synchronized (incompleteCacheRefs) { - // This always throws a BuilderException. - incompleteCacheRefs.iterator().next().resolveCacheRef(); - } - } - if (!incompleteStatements.isEmpty()) { - synchronized (incompleteStatements) { - // This always throws a BuilderException. - incompleteStatements.iterator().next().parseStatementNode(); - } - } - if (!incompleteMethods.isEmpty()) { - synchronized (incompleteMethods) { - // This always throws a BuilderException. - incompleteMethods.iterator().next().resolve(); - } - } - } - - /* - * Extracts namespace from fully qualified statement id. - * - * @param statementId - * - * @return namespace or null when id does not contain period. - */ - protected String extractNamespace(String statementId) { - int lastPeriod = statementId.lastIndexOf('.'); - return lastPeriod > 0 ? statementId.substring(0, lastPeriod) : null; - } - - // Slow but a one time cost. A better solution is welcome. - protected void checkGloballyForDiscriminatedNestedResultMaps(ResultMap rm) { - if (rm.hasNestedResultMaps()) { - for (Map.Entry entry : resultMaps.entrySet()) { - Object value = entry.getValue(); - if (value instanceof ResultMap) { - ResultMap entryResultMap = (ResultMap) value; - if (!entryResultMap.hasNestedResultMaps() - && entryResultMap.getDiscriminator() != null) { - Collection discriminatedResultMapNames = entryResultMap - .getDiscriminator().getDiscriminatorMap() - .values(); - if (discriminatedResultMapNames.contains(rm.getId())) { - entryResultMap.forceNestedResultMaps(); - } - } - } - } - } - } - - // Slow but a one time cost. A better solution is welcome. - protected void checkLocallyForDiscriminatedNestedResultMaps(ResultMap rm) { - if (!rm.hasNestedResultMaps() && rm.getDiscriminator() != null) { - for (Map.Entry entry : rm.getDiscriminator() - .getDiscriminatorMap().entrySet()) { - String discriminatedResultMapName = entry.getValue(); - if (hasResultMap(discriminatedResultMapName)) { - ResultMap discriminatedResultMap = resultMaps - .get(discriminatedResultMapName); - if (discriminatedResultMap.hasNestedResultMaps()) { - rm.forceNestedResultMaps(); - break; - } - } - } - } - } - - protected static class StrictMap extends HashMap { - - private static final long serialVersionUID = -4950446264854982944L; - private String name; - - public StrictMap(String name, int initialCapacity, float loadFactor) { - super(initialCapacity, loadFactor); - this.name = name; - } - - public StrictMap(String name, int initialCapacity) { - super(initialCapacity); - this.name = name; - } - - public StrictMap(String name) { - super(); - this.name = name; - } - - public StrictMap(String name, Map m) { - super(m); - this.name = name; - } - - // TODO 如果现在状态为刷新,则刷新(先删除后添加) - @SuppressWarnings("unchecked") - public V put(String key, V value) { - if (org.apache.ibatis.thread.Runnable.isRefresh()) { - remove(key); - org.apache.ibatis.thread.Runnable.log.debug("refresh key:" - + key.substring(key.lastIndexOf(".") + 1)); - } - if (containsKey(key)) - throw new IllegalArgumentException(name - + " already contains value for " + key); - if (key.contains(".")) { - final String shortKey = getShortName(key); - if (super.get(shortKey) == null) { - super.put(shortKey, value); - } else { - super.put(shortKey, (V) new Ambiguity(shortKey)); - } - } - return super.put(key, value); - } - - public V get(Object key) { - V value = super.get(key); - if (value == null) { - throw new IllegalArgumentException(name - + " does not contain value for " + key); - } - if (value instanceof Ambiguity) { - throw new IllegalArgumentException( - ((Ambiguity) value).getSubject() - + " is ambiguous in " - + name - + " (try using the full name including the namespace, or rename one of the entries)"); - } - return value; - } - - private String getShortName(String key) { - final String[] keyparts = key.split("\\."); - final String shortKey = keyparts[keyparts.length - 1]; - return shortKey; - } - - protected static class Ambiguity { - private String subject; - - public Ambiguity(String subject) { - this.subject = subject; - } - - public String getSubject() { - return subject; - } - } - } - -} +/* + * Copyright 2009-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ibatis.session; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.apache.ibatis.binding.MapperRegistry; +import org.apache.ibatis.builder.CacheRefResolver; +import org.apache.ibatis.builder.ResultMapResolver; +import org.apache.ibatis.builder.annotation.MethodResolver; +import org.apache.ibatis.builder.xml.XMLStatementBuilder; +import org.apache.ibatis.cache.Cache; +import org.apache.ibatis.cache.decorators.FifoCache; +import org.apache.ibatis.cache.decorators.LruCache; +import org.apache.ibatis.cache.decorators.SoftCache; +import org.apache.ibatis.cache.decorators.WeakCache; +import org.apache.ibatis.cache.impl.PerpetualCache; +import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory; +import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory; +import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory; +import org.apache.ibatis.executor.BatchExecutor; +import org.apache.ibatis.executor.CachingExecutor; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.executor.ReuseExecutor; +import org.apache.ibatis.executor.SimpleExecutor; +import org.apache.ibatis.executor.keygen.KeyGenerator; +import org.apache.ibatis.executor.loader.ProxyFactory; +import org.apache.ibatis.executor.loader.cglib.CglibProxyFactory; +import org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory; +import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.executor.resultset.DefaultResultSetHandler; +import org.apache.ibatis.executor.resultset.ResultSetHandler; +import org.apache.ibatis.executor.statement.RoutingStatementHandler; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; +import org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl; +import org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl; +import org.apache.ibatis.logging.log4j.Log4jImpl; +import org.apache.ibatis.logging.log4j2.Log4j2Impl; +import org.apache.ibatis.logging.nologging.NoLoggingImpl; +import org.apache.ibatis.logging.slf4j.Slf4jImpl; +import org.apache.ibatis.logging.stdout.StdOutImpl; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.ParameterMap; +import org.apache.ibatis.mapping.ResultMap; +import org.apache.ibatis.mapping.VendorDatabaseIdProvider; +import org.apache.ibatis.parsing.XNode; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.InterceptorChain; +import org.apache.ibatis.reflection.DefaultReflectorFactory; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.ReflectorFactory; +import org.apache.ibatis.reflection.factory.DefaultObjectFactory; +import org.apache.ibatis.reflection.factory.ObjectFactory; +import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory; +import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; +import org.apache.ibatis.scripting.LanguageDriver; +import org.apache.ibatis.scripting.LanguageDriverRegistry; +import org.apache.ibatis.scripting.defaults.RawLanguageDriver; +import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver; +import org.apache.ibatis.transaction.Transaction; +import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.apache.ibatis.transaction.managed.ManagedTransactionFactory; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.TypeAliasRegistry; +import org.apache.ibatis.type.TypeHandlerRegistry; + +/** + * @author Clinton Begin + * @description 重写put,实现刷新的功能 + */ +public class Configuration { + + protected Environment environment; + + protected boolean safeRowBoundsEnabled = false; + protected boolean safeResultHandlerEnabled = true; + protected boolean mapUnderscoreToCamelCase = false; + protected boolean aggressiveLazyLoading = true; + protected boolean multipleResultSetsEnabled = true; + protected boolean useGeneratedKeys = false; + protected boolean useColumnLabel = true; + protected boolean cacheEnabled = true; + protected boolean callSettersOnNulls = false; + protected String logPrefix; + protected Class logImpl; + protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION; + protected JdbcType jdbcTypeForNull = JdbcType.OTHER; + protected Set lazyLoadTriggerMethods = new HashSet( + Arrays.asList(new String[] { "equals", "clone", "hashCode", + "toString" })); + protected Integer defaultStatementTimeout=25; + protected Integer defaultFetchSize=100; + protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE; + protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL; + + protected Properties variables = new Properties(); + protected ObjectFactory objectFactory = new DefaultObjectFactory(); + protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory(); + protected ReflectorFactory reflectorFactory=new DefaultReflectorFactory(); + protected MapperRegistry mapperRegistry = new MapperRegistry(this); + + protected boolean lazyLoadingEnabled = false; + protected ProxyFactory proxyFactory; + + protected String databaseId; + /** + * Configuration factory class. Used to create Configuration for loading + * deserialized unread properties. + * + * @see Issue + * 300 (google code) + */ + protected Class configurationFactory; + + protected final InterceptorChain interceptorChain = new InterceptorChain(); + protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry(); + protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry(); + protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry(); + + protected final Map mappedStatements = new StrictMap( + "Mapped Statements collection"); + protected final Map caches = new StrictMap( + "Caches collection"); + protected final Map resultMaps = new StrictMap( + "Result Maps collection"); + protected final Map parameterMaps = new StrictMap( + "Parameter Maps collection"); + protected final Map keyGenerators = new StrictMap( + "Key Generators collection"); + + protected final Set loadedResources = new HashSet(); + protected final Map sqlFragments = new StrictMap( + "XML fragments parsed from previous mappers"); + + protected final Collection incompleteStatements = new LinkedList(); + protected final Collection incompleteCacheRefs = new LinkedList(); + protected final Collection incompleteResultMaps = new LinkedList(); + protected final Collection incompleteMethods = new LinkedList(); + + /* + * A map holds cache-ref relationship. The key is the namespace that + * references a cache bound to another namespace and the value is the + * namespace which the actual cache is bound to. + */ + protected final Map cacheRefMap = new HashMap(); + + public Configuration(Environment environment) { + this(); + this.environment = environment; + } + + public Configuration() { + typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class); + typeAliasRegistry.registerAlias("MANAGED", + ManagedTransactionFactory.class); + + typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class); + typeAliasRegistry + .registerAlias("POOLED", PooledDataSourceFactory.class); + typeAliasRegistry.registerAlias("UNPOOLED", + UnpooledDataSourceFactory.class); + + typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class); + typeAliasRegistry.registerAlias("FIFO", FifoCache.class); + typeAliasRegistry.registerAlias("LRU", LruCache.class); + typeAliasRegistry.registerAlias("SOFT", SoftCache.class); + typeAliasRegistry.registerAlias("WEAK", WeakCache.class); + + typeAliasRegistry.registerAlias("DB_VENDOR", + VendorDatabaseIdProvider.class); + + typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class); + typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class); + + typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class); + typeAliasRegistry.registerAlias("COMMONS_LOGGING", + JakartaCommonsLoggingImpl.class); + typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class); + typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class); + typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class); + typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class); + typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class); + + typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class); + typeAliasRegistry.registerAlias("JAVASSIST", + JavassistProxyFactory.class); + + languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class); + languageRegistry.register(RawLanguageDriver.class); + } + + public String getLogPrefix() { + return logPrefix; + } + + public void setLogPrefix(String logPrefix) { + this.logPrefix = logPrefix; + } + + public Class getLogImpl() { + return logImpl; + } + + @SuppressWarnings("unchecked") + public void setLogImpl(Class logImpl) { + if (logImpl != null) { + this.logImpl = (Class) logImpl; + LogFactory.useCustomLogging(this.logImpl); + } + } + + public boolean isCallSettersOnNulls() { + return callSettersOnNulls; + } + + public void setCallSettersOnNulls(boolean callSettersOnNulls) { + this.callSettersOnNulls = callSettersOnNulls; + } + + public String getDatabaseId() { + return databaseId; + } + + public void setDatabaseId(String databaseId) { + this.databaseId = databaseId; + } + + public Class getConfigurationFactory() { + return configurationFactory; + } + + public void setConfigurationFactory(Class configurationFactory) { + this.configurationFactory = configurationFactory; + } + + public boolean isSafeResultHandlerEnabled() { + return safeResultHandlerEnabled; + } + + public void setSafeResultHandlerEnabled(boolean safeResultHandlerEnabled) { + this.safeResultHandlerEnabled = safeResultHandlerEnabled; + } + + public boolean isSafeRowBoundsEnabled() { + return safeRowBoundsEnabled; + } + + public void setSafeRowBoundsEnabled(boolean safeRowBoundsEnabled) { + this.safeRowBoundsEnabled = safeRowBoundsEnabled; + } + + public boolean isMapUnderscoreToCamelCase() { + return mapUnderscoreToCamelCase; + } + + public void setMapUnderscoreToCamelCase(boolean mapUnderscoreToCamelCase) { + this.mapUnderscoreToCamelCase = mapUnderscoreToCamelCase; + } + + public void addLoadedResource(String resource) { + loadedResources.add(resource); + } + + public boolean isResourceLoaded(String resource) { + return loadedResources.contains(resource); + } + + public Environment getEnvironment() { + return environment; + } + + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + public AutoMappingBehavior getAutoMappingBehavior() { + return autoMappingBehavior; + } + + public void setAutoMappingBehavior(AutoMappingBehavior autoMappingBehavior) { + this.autoMappingBehavior = autoMappingBehavior; + } + + public boolean isLazyLoadingEnabled() { + return lazyLoadingEnabled; + } + + public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) { + this.lazyLoadingEnabled = lazyLoadingEnabled; + } + + public ProxyFactory getProxyFactory() { + if (proxyFactory == null) { + // makes sure CGLIB is not needed unless explicitly requested + proxyFactory = new CglibProxyFactory(); + } + return proxyFactory; + } + + public void setProxyFactory(ProxyFactory proxyFactory) { + this.proxyFactory = proxyFactory; + } + + public boolean isAggressiveLazyLoading() { + return aggressiveLazyLoading; + } + + public void setAggressiveLazyLoading(boolean aggressiveLazyLoading) { + this.aggressiveLazyLoading = aggressiveLazyLoading; + } + + public boolean isMultipleResultSetsEnabled() { + return multipleResultSetsEnabled; + } + + public void setMultipleResultSetsEnabled(boolean multipleResultSetsEnabled) { + this.multipleResultSetsEnabled = multipleResultSetsEnabled; + } + + public Set getLazyLoadTriggerMethods() { + return lazyLoadTriggerMethods; + } + + public void setLazyLoadTriggerMethods(Set lazyLoadTriggerMethods) { + this.lazyLoadTriggerMethods = lazyLoadTriggerMethods; + } + + public boolean isUseGeneratedKeys() { + return useGeneratedKeys; + } + + public void setUseGeneratedKeys(boolean useGeneratedKeys) { + this.useGeneratedKeys = useGeneratedKeys; + } + + public ExecutorType getDefaultExecutorType() { + return defaultExecutorType; + } + + public void setDefaultExecutorType(ExecutorType defaultExecutorType) { + this.defaultExecutorType = defaultExecutorType; + } + + public boolean isCacheEnabled() { + return cacheEnabled; + } + + public void setCacheEnabled(boolean cacheEnabled) { + this.cacheEnabled = cacheEnabled; + } + + public Integer getDefaultStatementTimeout() { + return defaultStatementTimeout; + } + + public void setDefaultStatementTimeout(Integer defaultStatementTimeout) { + this.defaultStatementTimeout = defaultStatementTimeout; + } + + public boolean isUseColumnLabel() { + return useColumnLabel; + } + + public void setUseColumnLabel(boolean useColumnLabel) { + this.useColumnLabel = useColumnLabel; + } + + public LocalCacheScope getLocalCacheScope() { + return localCacheScope; + } + + public void setLocalCacheScope(LocalCacheScope localCacheScope) { + this.localCacheScope = localCacheScope; + } + + public JdbcType getJdbcTypeForNull() { + return jdbcTypeForNull; + } + + public void setJdbcTypeForNull(JdbcType jdbcTypeForNull) { + this.jdbcTypeForNull = jdbcTypeForNull; + } + + public Properties getVariables() { + return variables; + } + + public void setVariables(Properties variables) { + this.variables = variables; + } + + public TypeHandlerRegistry getTypeHandlerRegistry() { + return typeHandlerRegistry; + } + + public TypeAliasRegistry getTypeAliasRegistry() { + return typeAliasRegistry; + } + + /** + * @since 3.2.2 + */ + public MapperRegistry getMapperRegistry() { + return mapperRegistry; + } + + public ObjectFactory getObjectFactory() { + return objectFactory; + } + + public void setObjectFactory(ObjectFactory objectFactory) { + this.objectFactory = objectFactory; + } + + public ObjectWrapperFactory getObjectWrapperFactory() { + return objectWrapperFactory; + } + + public void setObjectWrapperFactory( + ObjectWrapperFactory objectWrapperFactory) { + this.objectWrapperFactory = objectWrapperFactory; + } + + /** + * @since 3.2.2 + */ + public List getInterceptors() { + return interceptorChain.getInterceptors(); + } + + public LanguageDriverRegistry getLanguageRegistry() { + return languageRegistry; + } + + public void setDefaultScriptingLanguage(Class driver) { + if (driver == null) { + driver = XMLLanguageDriver.class; + } + getLanguageRegistry().setDefaultDriverClass(driver); + } + + public LanguageDriver getDefaultScriptingLanuageInstance() { + return languageRegistry.getDefaultDriver(); + } + + public MetaObject newMetaObject(Object object) { + return MetaObject + .forObject(object, objectFactory, objectWrapperFactory,reflectorFactory); + } + + public ParameterHandler newParameterHandler( + MappedStatement mappedStatement, Object parameterObject, + BoundSql boundSql) { + ParameterHandler parameterHandler = mappedStatement.getLang() + .createParameterHandler(mappedStatement, parameterObject, + boundSql); + parameterHandler = (ParameterHandler) interceptorChain + .pluginAll(parameterHandler); + return parameterHandler; + } + + public ResultSetHandler newResultSetHandler(Executor executor, + MappedStatement mappedStatement, RowBounds rowBounds, + ParameterHandler parameterHandler, ResultHandler resultHandler, + BoundSql boundSql) { + ResultSetHandler resultSetHandler = new DefaultResultSetHandler( + executor, mappedStatement, parameterHandler, resultHandler, + boundSql, rowBounds); + resultSetHandler = (ResultSetHandler) interceptorChain + .pluginAll(resultSetHandler); + return resultSetHandler; + } + + public StatementHandler newStatementHandler(Executor executor, + MappedStatement mappedStatement, Object parameterObject, + RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { + StatementHandler statementHandler = new RoutingStatementHandler( + executor, mappedStatement, parameterObject, rowBounds, + resultHandler, boundSql); + statementHandler = (StatementHandler) interceptorChain + .pluginAll(statementHandler); + return statementHandler; + } + + public Executor newExecutor(Transaction transaction) { + return newExecutor(transaction, defaultExecutorType); + } + + public Executor newExecutor(Transaction transaction, + ExecutorType executorType) { + executorType = executorType == null ? defaultExecutorType + : executorType; + executorType = executorType == null ? ExecutorType.SIMPLE + : executorType; + Executor executor; + if (ExecutorType.BATCH == executorType) { + executor = new BatchExecutor(this, transaction); + } else if (ExecutorType.REUSE == executorType) { + executor = new ReuseExecutor(this, transaction); + } else { + executor = new SimpleExecutor(this, transaction); + } + if (cacheEnabled) { + executor = new CachingExecutor(executor); + } + executor = (Executor) interceptorChain.pluginAll(executor); + return executor; + } + + public void addKeyGenerator(String id, KeyGenerator keyGenerator) { + keyGenerators.put(id, keyGenerator); + } + + public Collection getKeyGeneratorNames() { + return keyGenerators.keySet(); + } + + public Collection getKeyGenerators() { + return keyGenerators.values(); + } + + public KeyGenerator getKeyGenerator(String id) { + return keyGenerators.get(id); + } + + public boolean hasKeyGenerator(String id) { + return keyGenerators.containsKey(id); + } + + public void addCache(Cache cache) { + caches.put(cache.getId(), cache); + } + + public Collection getCacheNames() { + return caches.keySet(); + } + + public Collection getCaches() { + return caches.values(); + } + + public Cache getCache(String id) { + return caches.get(id); + } + + public ReflectorFactory getReflectorFactory() { + return reflectorFactory; + } + + public void setReflectorFactory(ReflectorFactory reflectorFactory) { + this.reflectorFactory = reflectorFactory; + } + + public boolean hasCache(String id) { + return caches.containsKey(id); + } + + public void addResultMap(ResultMap rm) { + resultMaps.put(rm.getId(), rm); + checkLocallyForDiscriminatedNestedResultMaps(rm); + checkGloballyForDiscriminatedNestedResultMaps(rm); + } + + public Collection getResultMapNames() { + return resultMaps.keySet(); + } + + public Collection getResultMaps() { + return resultMaps.values(); + } + + public ResultMap getResultMap(String id) { + return resultMaps.get(id); + } + + public boolean hasResultMap(String id) { + return resultMaps.containsKey(id); + } + + public void addParameterMap(ParameterMap pm) { + parameterMaps.put(pm.getId(), pm); + } + + public Collection getParameterMapNames() { + return parameterMaps.keySet(); + } + + public Collection getParameterMaps() { + return parameterMaps.values(); + } + + public ParameterMap getParameterMap(String id) { + return parameterMaps.get(id); + } + + public boolean hasParameterMap(String id) { + return parameterMaps.containsKey(id); + } + + public void addMappedStatement(MappedStatement ms) { + mappedStatements.put(ms.getId(), ms); + } + + public Collection getMappedStatementNames() { + buildAllStatements(); + return mappedStatements.keySet(); + } + + public Collection getMappedStatements() { + buildAllStatements(); + return mappedStatements.values(); + } + + public Collection getIncompleteStatements() { + return incompleteStatements; + } + + public void addIncompleteStatement(XMLStatementBuilder incompleteStatement) { + incompleteStatements.add(incompleteStatement); + } + + public Collection getIncompleteCacheRefs() { + return incompleteCacheRefs; + } + + public void addIncompleteCacheRef(CacheRefResolver incompleteCacheRef) { + incompleteCacheRefs.add(incompleteCacheRef); + } + + public Collection getIncompleteResultMaps() { + return incompleteResultMaps; + } + + public void addIncompleteResultMap(ResultMapResolver resultMapResolver) { + incompleteResultMaps.add(resultMapResolver); + } + + public void addIncompleteMethod(MethodResolver builder) { + incompleteMethods.add(builder); + } + + public Collection getIncompleteMethods() { + return incompleteMethods; + } + + public MappedStatement getMappedStatement(String id) { + return this.getMappedStatement(id, true); + } + + public Integer getDefaultFetchSize() { + return defaultFetchSize; + } + + public void setDefaultFetchSize(Integer defaultFetchSize) { + this.defaultFetchSize = defaultFetchSize; + } + + public MappedStatement getMappedStatement(String id, + boolean validateIncompleteStatements) { + if (validateIncompleteStatements) { + buildAllStatements(); + } + return mappedStatements.get(id); + } + + public Map getSqlFragments() { + return sqlFragments; + } + + public void addInterceptor(Interceptor interceptor) { + interceptorChain.addInterceptor(interceptor); + } + + public void addMappers(String packageName, Class superType) { + mapperRegistry.addMappers(packageName, superType); + } + + public void addMappers(String packageName) { + mapperRegistry.addMappers(packageName); + } + + public void addMapper(Class type) { + mapperRegistry.addMapper(type); + } + + public T getMapper(Class type, SqlSession sqlSession) { + return mapperRegistry.getMapper(type, sqlSession); + } + + public boolean hasMapper(Class type) { + return mapperRegistry.hasMapper(type); + } + + public boolean hasStatement(String statementName) { + return hasStatement(statementName, true); + } + + public boolean hasStatement(String statementName, + boolean validateIncompleteStatements) { + if (validateIncompleteStatements) { + buildAllStatements(); + } + return mappedStatements.containsKey(statementName); + } + + public void addCacheRef(String namespace, String referencedNamespace) { + cacheRefMap.put(namespace, referencedNamespace); + } + + /* + * Parses all the unprocessed statement nodes in the cache. It is + * recommended to call this method once all the mappers are added as it + * provides fail-fast statement validation. + */ + protected void buildAllStatements() { + if (!incompleteResultMaps.isEmpty()) { + synchronized (incompleteResultMaps) { + // This always throws a BuilderException. + incompleteResultMaps.iterator().next().resolve(); + } + } + if (!incompleteCacheRefs.isEmpty()) { + synchronized (incompleteCacheRefs) { + // This always throws a BuilderException. + incompleteCacheRefs.iterator().next().resolveCacheRef(); + } + } + if (!incompleteStatements.isEmpty()) { + synchronized (incompleteStatements) { + // This always throws a BuilderException. + incompleteStatements.iterator().next().parseStatementNode(); + } + } + if (!incompleteMethods.isEmpty()) { + synchronized (incompleteMethods) { + // This always throws a BuilderException. + incompleteMethods.iterator().next().resolve(); + } + } + } + + /* + * Extracts namespace from fully qualified statement id. + * + * @param statementId + * + * @return namespace or null when id does not contain period. + */ + protected String extractNamespace(String statementId) { + int lastPeriod = statementId.lastIndexOf('.'); + return lastPeriod > 0 ? statementId.substring(0, lastPeriod) : null; + } + + // Slow but a one time cost. A better solution is welcome. + protected void checkGloballyForDiscriminatedNestedResultMaps(ResultMap rm) { + if (rm.hasNestedResultMaps()) { + for (Map.Entry entry : resultMaps.entrySet()) { + Object value = entry.getValue(); + if (value instanceof ResultMap) { + ResultMap entryResultMap = (ResultMap) value; + if (!entryResultMap.hasNestedResultMaps() + && entryResultMap.getDiscriminator() != null) { + Collection discriminatedResultMapNames = entryResultMap + .getDiscriminator().getDiscriminatorMap() + .values(); + if (discriminatedResultMapNames.contains(rm.getId())) { + entryResultMap.forceNestedResultMaps(); + } + } + } + } + } + } + + // Slow but a one time cost. A better solution is welcome. + protected void checkLocallyForDiscriminatedNestedResultMaps(ResultMap rm) { + if (!rm.hasNestedResultMaps() && rm.getDiscriminator() != null) { + for (Map.Entry entry : rm.getDiscriminator() + .getDiscriminatorMap().entrySet()) { + String discriminatedResultMapName = entry.getValue(); + if (hasResultMap(discriminatedResultMapName)) { + ResultMap discriminatedResultMap = resultMaps + .get(discriminatedResultMapName); + if (discriminatedResultMap.hasNestedResultMaps()) { + rm.forceNestedResultMaps(); + break; + } + } + } + } + } + + protected static class StrictMap extends HashMap { + + private static final long serialVersionUID = -4950446264854982944L; + private String name; + + public StrictMap(String name, int initialCapacity, float loadFactor) { + super(initialCapacity, loadFactor); + this.name = name; + } + + public StrictMap(String name, int initialCapacity) { + super(initialCapacity); + this.name = name; + } + + public StrictMap(String name) { + super(); + this.name = name; + } + + public StrictMap(String name, Map m) { + super(m); + this.name = name; + } + + // TODO 如果现在状态为刷新,则刷新(先删除后添加) + @SuppressWarnings("unchecked") + public V put(String key, V value) { + if (org.apache.ibatis.thread.Runnable.isRefresh()) { + remove(key); + org.apache.ibatis.thread.Runnable.log.debug("refresh key:" + + key.substring(key.lastIndexOf(".") + 1)); + } + if (containsKey(key)) + throw new IllegalArgumentException(name + + " already contains value for " + key); + if (key.contains(".")) { + final String shortKey = getShortName(key); + if (super.get(shortKey) == null) { + super.put(shortKey, value); + } else { + super.put(shortKey, (V) new Ambiguity(shortKey)); + } + } + return super.put(key, value); + } + + public V get(Object key) { + V value = super.get(key); + if (value == null) { + throw new IllegalArgumentException(name + + " does not contain value for " + key); + } + if (value instanceof Ambiguity) { + throw new IllegalArgumentException( + ((Ambiguity) value).getSubject() + + " is ambiguous in " + + name + + " (try using the full name including the namespace, or rename one of the entries)"); + } + return value; + } + + private String getShortName(String key) { + final String[] keyparts = key.split("\\."); + final String shortKey = keyparts[keyparts.length - 1]; + return shortKey; + } + + protected static class Ambiguity { + private String subject; + + public Ambiguity(String subject) { + this.subject = subject; + } + + public String getSubject() { + return subject; + } + } + } + +} diff --git a/src/main/resources/mybatis-config.xml b/src/main/resources/mybatis-config.xml index 845a9a8759..d70060c883 100644 --- a/src/main/resources/mybatis-config.xml +++ b/src/main/resources/mybatis-config.xml @@ -36,7 +36,14 @@ - + + + + + + + + From a94d2a0bdbe7210f40447ed2f442d88088d7f177 Mon Sep 17 00:00:00 2001 From: kookse Date: Thu, 25 Feb 2016 17:06:31 +0800 Subject: [PATCH 3/5] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f4b6f7ff67..b6dfdfd6e3 100644 --- a/README.md +++ b/README.md @@ -51,14 +51,14 @@ JeeSite 提供了常用工具进行封装,包括日志工具、缓存工具、 1、后端 -* 核心框架:Spring Framework 4.0 +* 核心框架:Spring Framework 4.2.4 * 安全框架:Apache Shiro 1.2 -* 视图框架:Spring MVC 4.0 -* 服务端验证:Hibernate Validator 5.1 +* 视图框架:Spring MVC 4.2.4 +* 服务端验证:Hibernate Validator 5.2.4 * 布局框架:SiteMesh 2.4 * 工作流引擎:Activiti 5.15、FoxBPM 6 * 任务调度:Spring Task 4.0 -* 持久层框架:MyBatis 3.2 +* 持久层框架:MyBatis 3.3.1 * 数据库连接池:Alibaba Druid 1.0 * 缓存框架:Ehcache 2.6、Redis * 日志管理:SLF4J 1.7、Log4j From c95ea56b770b2fce7730224bb97c83de7b4d0fee Mon Sep 17 00:00:00 2001 From: kookse Date: Thu, 25 Feb 2016 17:49:27 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E5=8A=9E=E5=85=AC-=E9=80=9A=E5=91=8A=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E2=80=9D=E7=9A=84=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=87=BA=E7=8E=B0=E7=9A=84=E6=B7=BB=E5=8A=A0=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98=20'dbName'=20not=20found.?= =?UTF-8?q?=20Available=20arameters=20are=20[list]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mappings/modules/oa/OaNotifyRecordDao.xml | 208 +++++++++--------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/src/main/resources/mappings/modules/oa/OaNotifyRecordDao.xml b/src/main/resources/mappings/modules/oa/OaNotifyRecordDao.xml index 0f3a96a463..e5cc1304ee 100644 --- a/src/main/resources/mappings/modules/oa/OaNotifyRecordDao.xml +++ b/src/main/resources/mappings/modules/oa/OaNotifyRecordDao.xml @@ -1,105 +1,105 @@ - - - - - - a.ID AS "id", - a.OA_NOTIFY_ID AS "oaNotify.id", - a.USER_ID AS "user.id", - a.READ_FLAG AS "readFlag", - a.READ_DATE AS "readDate", - u.name AS "user.name", - o.name AS "user.office.name" - - - - JOIN sys_user u ON u.id = a.user_id - JOIN sys_office o ON o.id = u.office_id - - - - - - - - - - INSERT INTO OA_NOTIFY_RECORD( - ID, - OA_NOTIFY_ID, - USER_ID, - READ_FLAG, - READ_DATE - ) VALUES ( - #{id}, - #{oaNotify.id}, - #{user.id}, - #{readFlag}, - #{readDate} - ) - - - - INSERT INTO OA_NOTIFY_RECORD( - ID, - OA_NOTIFY_ID, - USER_ID, - READ_FLAG, - READ_DATE - ) - - SELECT - #{e.id}, - #{e.oaNotify.id}, - #{e.user.id}, - #{e.readFlag}, - #{e.readDate} - - FROM dual - - - - - - UPDATE OA_NOTIFY_RECORD SET - READ_FLAG = #{readFlag}, - READ_DATE = #{readDate} - WHERE OA_NOTIFY_ID = #{oaNotify.id} - AND USER_ID = #{user.id} - AND READ_FLAG != '1' - - - - UPDATE FROM OA_NOTIFY_RECORD - WHERE id = #{id} - - - - DELETE FROM OA_NOTIFY_RECORD - WHERE oa_notify_id = #{oaNotifyId} - - + + + + + + a.ID AS "id", + a.OA_NOTIFY_ID AS "oaNotify.id", + a.USER_ID AS "user.id", + a.READ_FLAG AS "readFlag", + a.READ_DATE AS "readDate", + u.name AS "user.name", + o.name AS "user.office.name" + + + + JOIN sys_user u ON u.id = a.user_id + JOIN sys_office o ON o.id = u.office_id + + + + + + + + + + INSERT INTO OA_NOTIFY_RECORD( + ID, + OA_NOTIFY_ID, + USER_ID, + READ_FLAG, + READ_DATE + ) VALUES ( + #{id}, + #{oaNotify.id}, + #{user.id}, + #{readFlag}, + #{readDate} + ) + + + + INSERT INTO OA_NOTIFY_RECORD( + ID, + OA_NOTIFY_ID, + USER_ID, + READ_FLAG, + READ_DATE + ) + + SELECT + #{e.id}, + #{e.oaNotify.id}, + #{e.user.id}, + #{e.readFlag}, + #{e.readDate} + + FROM dual + + + + + + UPDATE OA_NOTIFY_RECORD SET + READ_FLAG = #{readFlag}, + READ_DATE = #{readDate} + WHERE OA_NOTIFY_ID = #{oaNotify.id} + AND USER_ID = #{user.id} + AND READ_FLAG != '1' + + + + UPDATE FROM OA_NOTIFY_RECORD + WHERE id = #{id} + + + + DELETE FROM OA_NOTIFY_RECORD + WHERE oa_notify_id = #{oaNotifyId} + + \ No newline at end of file From 069a10e41d0461bf315da4d442275d3914b05709 Mon Sep 17 00:00:00 2001 From: kookse Date: Tue, 1 Mar 2016 12:00:25 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=81=9C=E7=94=A8=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=B8=AD=E5=AF=B9mybatis=E5=81=9A=E4=BF=AE=E6=94=B9=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=EF=BC=8Corg->org=5Fback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ibatis/builder/xml/XMLMapperBuilder.java | 2 +- .../apache/ibatis/session/Configuration.java | 2 +- .../apache/ibatis/thread/PropertiesUtil.java | 62 +- .../apache/ibatis/thread/Runnable.java | 388 +++--- .../mybatis/spring/SqlSessionFactoryBean.java | 1214 ++++++++--------- 5 files changed, 834 insertions(+), 834 deletions(-) rename src/main/java/{org => org_back}/apache/ibatis/builder/xml/XMLMapperBuilder.java (97%) rename src/main/java/{org => org_back}/apache/ibatis/session/Configuration.java (96%) rename src/main/java/{org => org_back}/apache/ibatis/thread/PropertiesUtil.java (90%) rename src/main/java/{org => org_back}/apache/ibatis/thread/Runnable.java (95%) rename src/main/java/{org => org_back}/mybatis/spring/SqlSessionFactoryBean.java (96%) diff --git a/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java b/src/main/java/org_back/apache/ibatis/builder/xml/XMLMapperBuilder.java similarity index 97% rename from src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java rename to src/main/java/org_back/apache/ibatis/builder/xml/XMLMapperBuilder.java index f107fb2dd1..fc4e5c5364 100644 --- a/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java +++ b/src/main/java/org_back/apache/ibatis/builder/xml/XMLMapperBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.ibatis.builder.xml; +package org_back.apache.ibatis.builder.xml; import java.io.InputStream; import java.io.Reader; diff --git a/src/main/java/org/apache/ibatis/session/Configuration.java b/src/main/java/org_back/apache/ibatis/session/Configuration.java similarity index 96% rename from src/main/java/org/apache/ibatis/session/Configuration.java rename to src/main/java/org_back/apache/ibatis/session/Configuration.java index bd93930a72..02974d947c 100644 --- a/src/main/java/org/apache/ibatis/session/Configuration.java +++ b/src/main/java/org_back/apache/ibatis/session/Configuration.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.ibatis.session; +package org_back.apache.ibatis.session; import java.util.Arrays; import java.util.Collection; diff --git a/src/main/java/org/apache/ibatis/thread/PropertiesUtil.java b/src/main/java/org_back/apache/ibatis/thread/PropertiesUtil.java similarity index 90% rename from src/main/java/org/apache/ibatis/thread/PropertiesUtil.java rename to src/main/java/org_back/apache/ibatis/thread/PropertiesUtil.java index 6211468b09..187a772026 100644 --- a/src/main/java/org/apache/ibatis/thread/PropertiesUtil.java +++ b/src/main/java/org_back/apache/ibatis/thread/PropertiesUtil.java @@ -1,31 +1,31 @@ -package org.apache.ibatis.thread; - -import java.util.Properties; - -public class PropertiesUtil { - - private static String filename = "/mybatis-refresh.properties"; - private static Properties pro = new Properties(); - static { - try { - pro.load(PropertiesUtil.class.getResourceAsStream(filename)); - } catch (Exception e) { - e.printStackTrace(); - System.out.println("Load mybatis-refresh “"+filename+"” file error."); - } - } - - public static int getInt(String key) { - int i = 0; - try { - i = Integer.parseInt(getString(key)); - } catch (Exception e) { - } - return i; - } - - public static String getString(String key) { - return pro == null ? null : pro.getProperty(key); - } - -} +package org_back.apache.ibatis.thread; + +import java.util.Properties; + +public class PropertiesUtil { + + private static String filename = "/mybatis-refresh.properties"; + private static Properties pro = new Properties(); + static { + try { + pro.load(PropertiesUtil.class.getResourceAsStream(filename)); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Load mybatis-refresh “"+filename+"” file error."); + } + } + + public static int getInt(String key) { + int i = 0; + try { + i = Integer.parseInt(getString(key)); + } catch (Exception e) { + } + return i; + } + + public static String getString(String key) { + return pro == null ? null : pro.getProperty(key); + } + +} diff --git a/src/main/java/org/apache/ibatis/thread/Runnable.java b/src/main/java/org_back/apache/ibatis/thread/Runnable.java similarity index 95% rename from src/main/java/org/apache/ibatis/thread/Runnable.java rename to src/main/java/org_back/apache/ibatis/thread/Runnable.java index 06548d4104..bb16935ca8 100644 --- a/src/main/java/org/apache/ibatis/thread/Runnable.java +++ b/src/main/java/org_back/apache/ibatis/thread/Runnable.java @@ -1,194 +1,194 @@ -package org.apache.ibatis.thread; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.apache.ibatis.session.Configuration; -import org.apache.log4j.Logger; -import org.mybatis.spring.SqlSessionFactoryBean; -import org.springframework.core.NestedIOException; - -/** - * 刷新使用进程 - * - * @author liubaoquan - * - */ -public class Runnable implements java.lang.Runnable { - - public static Logger log = Logger.getLogger(Runnable.class); - - private String location; - private Configuration configuration; - - private Long beforeTime = 0L; // 上一次刷新时间 - private static boolean refresh = false; // 是否执行刷新 - - private static String mappingPath = "mappings"; // xml文件夹匹配字符串,需要根据需要修改 - private static int delaySeconds = 10;// 延迟刷新秒数 - private static int sleepSeconds = 1;// 休眠时间 - - private static boolean enabled = false; - - static { - delaySeconds = PropertiesUtil.getInt("delaySeconds"); - sleepSeconds = PropertiesUtil.getInt("sleepSeconds"); - mappingPath = PropertiesUtil.getString("mappingPath"); - enabled = "true".equals(PropertiesUtil.getString("enabled")); - - delaySeconds = delaySeconds == 0 ? 50 : delaySeconds; - sleepSeconds = sleepSeconds == 0 ? 1 : sleepSeconds; - mappingPath = StringUtils.isBlank(mappingPath) ? "mappings" - : mappingPath; - - log.debug("[delaySeconds] " + delaySeconds); - log.debug("[sleepSeconds] " + sleepSeconds); - log.debug("[mappingPath] " + mappingPath); - - } - - public static boolean isRefresh() { - return refresh; - } - - public Runnable(String location, Configuration configuration) { - this.location = location.replaceAll("\\\\", "/"); - this.configuration = configuration; - } - - @Override - public void run() { - location = location.substring("file [".length(), - location.lastIndexOf(mappingPath) + mappingPath.length()); - beforeTime = System.currentTimeMillis(); - - log.debug("[location] " + location); - log.debug("[configuration] " + configuration); - - if (enabled){ - start(this); - } - } - - public void start(final Runnable runnable) { - - new Thread(new java.lang.Runnable() { - - @Override - public void run() { - - try { - Thread.sleep(delaySeconds * 1000); - } catch (InterruptedException e2) { - e2.printStackTrace(); - } - refresh = true; - - System.out.println("========= Enabled refresh mybatis mapper ========="); - - while (true) { - try { - runnable.refresh(location, beforeTime); - } catch (Exception e1) { - e1.printStackTrace(); - } - - try { - Thread.sleep(sleepSeconds * 1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - } - } - }).start(); - } - - /** - * 执行刷新 - * - * @param filePath - * 刷新目录 - * @param beforeTime - * 上次刷新时间 - * @throws NestedIOException - * 解析异常 - * @throws FileNotFoundException - * 文件未找到 - */ - public void refresh(String filePath, Long beforeTime) throws Exception { - - // 本次刷新时间 - Long refrehTime = System.currentTimeMillis(); - - List refreshs = this.getRefreshFile(new File(filePath), - beforeTime); - if (refreshs.size() > 0) { - log.debug("refresh files:" + refreshs.size()); - } - for (int i = 0; i < refreshs.size(); i++) { - System.out.println("Refresh file: " - + mappingPath - + StringUtils.substringAfterLast(refreshs.get(i) - .getAbsolutePath(), mappingPath)); - log.debug("refresh file:" + refreshs.get(i).getAbsolutePath()); - log.debug("refresh filename:" + refreshs.get(i).getName()); - SqlSessionFactoryBean.refresh(new FileInputStream(refreshs.get(i)), - refreshs.get(i).getAbsolutePath(), configuration); - } - // 如果刷新了文件,则修改刷新时间,否则不修改 - if (refreshs.size() > 0) { - this.beforeTime = refrehTime; - } - } - - /** - * 获取需要刷新的文件列表 - * - * @param dir - * 目录 - * @param beforeTime - * 上次刷新时间 - * @return 刷新文件列表 - */ - public List getRefreshFile(File dir, Long beforeTime) { - List refreshs = new ArrayList(); - - File[] files = dir.listFiles(); - for (int i = 0; i < files.length; i++) { - File file = files[i]; - if (file.isDirectory()) { - refreshs.addAll(this.getRefreshFile(file, beforeTime)); - } else if (file.isFile()) { - if (this.check(file, beforeTime)) { - refreshs.add(file); - } - } else { - System.out.println("error file." + file.getName()); - } - } - - return refreshs; - } - - /** - * 判断文件是否需要刷新 - * - * @param file - * 文件 - * @param beforeTime - * 上次刷新时间 - * @return 需要刷新返回true,否则返回false - */ - public boolean check(File file, Long beforeTime) { - if (file.lastModified() > beforeTime) { - return true; - } - return false; - } - -} +package org_back.apache.ibatis.thread; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.session.Configuration; +import org.apache.log4j.Logger; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.springframework.core.NestedIOException; + +/** + * 刷新使用进程 + * + * @author liubaoquan + * + */ +public class Runnable implements java.lang.Runnable { + + public static Logger log = Logger.getLogger(Runnable.class); + + private String location; + private Configuration configuration; + + private Long beforeTime = 0L; // 上一次刷新时间 + private static boolean refresh = false; // 是否执行刷新 + + private static String mappingPath = "mappings"; // xml文件夹匹配字符串,需要根据需要修改 + private static int delaySeconds = 10;// 延迟刷新秒数 + private static int sleepSeconds = 1;// 休眠时间 + + private static boolean enabled = false; + + static { + delaySeconds = PropertiesUtil.getInt("delaySeconds"); + sleepSeconds = PropertiesUtil.getInt("sleepSeconds"); + mappingPath = PropertiesUtil.getString("mappingPath"); + enabled = "true".equals(PropertiesUtil.getString("enabled")); + + delaySeconds = delaySeconds == 0 ? 50 : delaySeconds; + sleepSeconds = sleepSeconds == 0 ? 1 : sleepSeconds; + mappingPath = StringUtils.isBlank(mappingPath) ? "mappings" + : mappingPath; + + log.debug("[delaySeconds] " + delaySeconds); + log.debug("[sleepSeconds] " + sleepSeconds); + log.debug("[mappingPath] " + mappingPath); + + } + + public static boolean isRefresh() { + return refresh; + } + + public Runnable(String location, Configuration configuration) { + this.location = location.replaceAll("\\\\", "/"); + this.configuration = configuration; + } + + @Override + public void run() { + location = location.substring("file [".length(), + location.lastIndexOf(mappingPath) + mappingPath.length()); + beforeTime = System.currentTimeMillis(); + + log.debug("[location] " + location); + log.debug("[configuration] " + configuration); + + if (enabled){ + start(this); + } + } + + public void start(final Runnable runnable) { + + new Thread(new java.lang.Runnable() { + + @Override + public void run() { + + try { + Thread.sleep(delaySeconds * 1000); + } catch (InterruptedException e2) { + e2.printStackTrace(); + } + refresh = true; + + System.out.println("========= Enabled refresh mybatis mapper ========="); + + while (true) { + try { + runnable.refresh(location, beforeTime); + } catch (Exception e1) { + e1.printStackTrace(); + } + + try { + Thread.sleep(sleepSeconds * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + } + }).start(); + } + + /** + * 执行刷新 + * + * @param filePath + * 刷新目录 + * @param beforeTime + * 上次刷新时间 + * @throws NestedIOException + * 解析异常 + * @throws FileNotFoundException + * 文件未找到 + */ + public void refresh(String filePath, Long beforeTime) throws Exception { + + // 本次刷新时间 + Long refrehTime = System.currentTimeMillis(); + + List refreshs = this.getRefreshFile(new File(filePath), + beforeTime); + if (refreshs.size() > 0) { + log.debug("refresh files:" + refreshs.size()); + } + for (int i = 0; i < refreshs.size(); i++) { + System.out.println("Refresh file: " + + mappingPath + + StringUtils.substringAfterLast(refreshs.get(i) + .getAbsolutePath(), mappingPath)); + log.debug("refresh file:" + refreshs.get(i).getAbsolutePath()); + log.debug("refresh filename:" + refreshs.get(i).getName()); + SqlSessionFactoryBean.refresh(new FileInputStream(refreshs.get(i)), + refreshs.get(i).getAbsolutePath(), configuration); + } + // 如果刷新了文件,则修改刷新时间,否则不修改 + if (refreshs.size() > 0) { + this.beforeTime = refrehTime; + } + } + + /** + * 获取需要刷新的文件列表 + * + * @param dir + * 目录 + * @param beforeTime + * 上次刷新时间 + * @return 刷新文件列表 + */ + public List getRefreshFile(File dir, Long beforeTime) { + List refreshs = new ArrayList(); + + File[] files = dir.listFiles(); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.isDirectory()) { + refreshs.addAll(this.getRefreshFile(file, beforeTime)); + } else if (file.isFile()) { + if (this.check(file, beforeTime)) { + refreshs.add(file); + } + } else { + System.out.println("error file." + file.getName()); + } + } + + return refreshs; + } + + /** + * 判断文件是否需要刷新 + * + * @param file + * 文件 + * @param beforeTime + * 上次刷新时间 + * @return 需要刷新返回true,否则返回false + */ + public boolean check(File file, Long beforeTime) { + if (file.lastModified() > beforeTime) { + return true; + } + return false; + } + +} diff --git a/src/main/java/org/mybatis/spring/SqlSessionFactoryBean.java b/src/main/java/org_back/mybatis/spring/SqlSessionFactoryBean.java similarity index 96% rename from src/main/java/org/mybatis/spring/SqlSessionFactoryBean.java rename to src/main/java/org_back/mybatis/spring/SqlSessionFactoryBean.java index 221fb2cfea..5db7c5e758 100644 --- a/src/main/java/org/mybatis/spring/SqlSessionFactoryBean.java +++ b/src/main/java/org_back/mybatis/spring/SqlSessionFactoryBean.java @@ -1,607 +1,607 @@ -/* - * Copyright 2010-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mybatis.spring; - -import static org.springframework.util.Assert.notNull; -import static org.springframework.util.ObjectUtils.isEmpty; -import static org.springframework.util.StringUtils.hasLength; -import static org.springframework.util.StringUtils.tokenizeToStringArray; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.Properties; - -import javax.sql.DataSource; - -import org.apache.ibatis.builder.xml.XMLConfigBuilder; -import org.apache.ibatis.builder.xml.XMLMapperBuilder; -import org.apache.ibatis.executor.ErrorContext; -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.logging.LogFactory; -import org.apache.ibatis.mapping.DatabaseIdProvider; -import org.apache.ibatis.mapping.Environment; -import org.apache.ibatis.plugin.Interceptor; -import org.apache.ibatis.reflection.factory.ObjectFactory; -import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; -import org.apache.ibatis.session.Configuration; -import org.apache.ibatis.session.SqlSessionFactory; -import org.apache.ibatis.session.SqlSessionFactoryBuilder; -import org.apache.ibatis.transaction.TransactionFactory; -import org.apache.ibatis.type.TypeHandler; -import org.mybatis.spring.transaction.SpringManagedTransactionFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.core.NestedIOException; -import org.springframework.core.io.Resource; -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; - -/** - * {@code FactoryBean} that creates an MyBatis {@code SqlSessionFactory}. This - * is the usual way to set up a shared MyBatis {@code SqlSessionFactory} in a - * Spring application context; the SqlSessionFactory can then be passed to - * MyBatis-based DAOs via dependency injection. - * - * Either {@code DataSourceTransactionManager} or {@code JtaTransactionManager} - * can be used for transaction demarcation in combination with a - * {@code SqlSessionFactory}. JTA should be used for transactions which span - * multiple databases or when container managed transactions (CMT) are being - * used. - * - * @author Putthibong Boonbong - * @author Hunter Presnall - * @author Eduardo Macarron - * - * @see #setConfigLocation - * @see #setDataSource - * @version $Id$ - * @desctiption 刷新xml文件 - */ -public class SqlSessionFactoryBean implements FactoryBean, - InitializingBean, ApplicationListener { - - private static final Log logger = LogFactory - .getLog(SqlSessionFactoryBean.class); - - private Resource configLocation; - - private Resource[] mapperLocations; - - private DataSource dataSource; - - private TransactionFactory transactionFactory; - - private Properties configurationProperties; - - private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); - - private SqlSessionFactory sqlSessionFactory; - - private String environment = SqlSessionFactoryBean.class.getSimpleName(); // EnvironmentAware requires spring 3.1 - - private boolean failFast; - - private Interceptor[] plugins; - - private TypeHandler[] typeHandlers; - - private String typeHandlersPackage; - - private Class[] typeAliases; - - private String typeAliasesPackage; - - private Class typeAliasesSuperType; - - private DatabaseIdProvider databaseIdProvider; // issue #19. No default provider. - - private ObjectFactory objectFactory; - - private ObjectWrapperFactory objectWrapperFactory; - - /** - * Sets the ObjectFactory. - * - * @since 1.1.2 - * @param objectFactory - */ - public void setObjectFactory(ObjectFactory objectFactory) { - this.objectFactory = objectFactory; - } - - /** - * Sets the ObjectWrapperFactory. - * - * @since 1.1.2 - * @param objectWrapperFactory - */ - public void setObjectWrapperFactory( - ObjectWrapperFactory objectWrapperFactory) { - this.objectWrapperFactory = objectWrapperFactory; - } - - /** - * Gets the DatabaseIdProvider - * - * @since 1.1.0 - * @return - */ - public DatabaseIdProvider getDatabaseIdProvider() { - return databaseIdProvider; - } - - /** - * Sets the DatabaseIdProvider. As of version 1.2.2 this variable is not - * initialized by default. - * - * @since 1.1.0 - * @param databaseIdProvider - */ - public void setDatabaseIdProvider(DatabaseIdProvider databaseIdProvider) { - this.databaseIdProvider = databaseIdProvider; - } - - /** - * Mybatis plugin list. - * - * @since 1.0.1 - * - * @param plugins - * list of plugins - * - */ - public void setPlugins(Interceptor[] plugins) { - this.plugins = plugins; - } - - /** - * Packages to search for type aliases. - * - * @since 1.0.1 - * - * @param typeAliasesPackage - * package to scan for domain objects - * - */ - public void setTypeAliasesPackage(String typeAliasesPackage) { - this.typeAliasesPackage = typeAliasesPackage; - } - - /** - * Super class which domain objects have to extend to have a type alias - * created. No effect if there is no package to scan configured. - * - * @since 1.1.2 - * - * @param typeAliasesSuperType - * super class for domain objects - * - */ - public void setTypeAliasesSuperType(Class typeAliasesSuperType) { - this.typeAliasesSuperType = typeAliasesSuperType; - } - - /** - * Packages to search for type handlers. - * - * @since 1.0.1 - * - * @param typeHandlersPackage - * package to scan for type handlers - * - */ - public void setTypeHandlersPackage(String typeHandlersPackage) { - this.typeHandlersPackage = typeHandlersPackage; - } - - /** - * Set type handlers. They must be annotated with {@code MappedTypes} and - * optionally with {@code MappedJdbcTypes} - * - * @since 1.0.1 - * - * @param typeHandlers - * Type handler list - */ - public void setTypeHandlers(TypeHandler[] typeHandlers) { - this.typeHandlers = typeHandlers; - } - - /** - * List of type aliases to register. They can be annotated with - * {@code Alias} - * - * @since 1.0.1 - * - * @param typeAliases - * Type aliases list - */ - public void setTypeAliases(Class[] typeAliases) { - this.typeAliases = typeAliases; - } - - /** - * If true, a final check is done on Configuration to assure that all mapped - * statements are fully loaded and there is no one still pending to resolve - * includes. Defaults to false. - * - * @since 1.0.1 - * - * @param failFast - * enable failFast - */ - public void setFailFast(boolean failFast) { - this.failFast = failFast; - } - - /** - * Set the location of the MyBatis {@code SqlSessionFactory} config file. A - * typical value is "WEB-INF/mybatis-configuration.xml". - */ - public void setConfigLocation(Resource configLocation) { - this.configLocation = configLocation; - } - - /** - * Set locations of MyBatis mapper files that are going to be merged into - * the {@code SqlSessionFactory} configuration at runtime. - * - * This is an alternative to specifying "<sqlmapper>" entries in an - * MyBatis config file. This property being based on Spring's resource - * abstraction also allows for specifying resource patterns here: e.g. - * "classpath*:sqlmap/*-mapper.xml". - */ - public void setMapperLocations(Resource[] mapperLocations) { - this.mapperLocations = mapperLocations; - } - - /** - * Set optional properties to be passed into the SqlSession configuration, - * as alternative to a {@code <properties>} tag in the configuration - * xml file. This will be used to resolve placeholders in the config file. - */ - public void setConfigurationProperties( - Properties sqlSessionFactoryProperties) { - this.configurationProperties = sqlSessionFactoryProperties; - } - - /** - * Set the JDBC {@code DataSource} that this instance should manage - * transactions for. The {@code DataSource} should match the one used by the - * {@code SqlSessionFactory}: for example, you could specify the same JNDI - * DataSource for both. - * - * A transactional JDBC {@code Connection} for this {@code DataSource} will - * be provided to application code accessing this {@code DataSource} - * directly via {@code DataSourceUtils} or - * {@code DataSourceTransactionManager}. - * - * The {@code DataSource} specified here should be the target - * {@code DataSource} to manage transactions for, not a - * {@code TransactionAwareDataSourceProxy}. Only data access code may work - * with {@code TransactionAwareDataSourceProxy}, while the transaction - * manager needs to work on the underlying target {@code DataSource}. If - * there's nevertheless a {@code TransactionAwareDataSourceProxy} passed in, - * it will be unwrapped to extract its target {@code DataSource}. - * - */ - public void setDataSource(DataSource dataSource) { - if (dataSource instanceof TransactionAwareDataSourceProxy) { - // If we got a TransactionAwareDataSourceProxy, we need to perform - // transactions for its underlying target DataSource, else data - // access code won't see properly exposed transactions (i.e. - // transactions for the target DataSource). - this.dataSource = ((TransactionAwareDataSourceProxy) dataSource) - .getTargetDataSource(); - } else { - this.dataSource = dataSource; - } - } - - /** - * Sets the {@code SqlSessionFactoryBuilder} to use when creating the - * {@code SqlSessionFactory}. - * - * This is mainly meant for testing so that mock SqlSessionFactory classes - * can be injected. By default, {@code SqlSessionFactoryBuilder} creates - * {@code DefaultSqlSessionFactory} instances. - * - */ - public void setSqlSessionFactoryBuilder( - SqlSessionFactoryBuilder sqlSessionFactoryBuilder) { - this.sqlSessionFactoryBuilder = sqlSessionFactoryBuilder; - } - - /** - * Set the MyBatis TransactionFactory to use. Default is - * {@code SpringManagedTransactionFactory} - * - * The default {@code SpringManagedTransactionFactory} should be appropriate - * for all cases: be it Spring transaction management, EJB CMT or plain JTA. - * If there is no active transaction, SqlSession operations will execute SQL - * statements non-transactionally. - * - * It is strongly recommended to use the default - * {@code TransactionFactory}. If not used, any attempt at getting an - * SqlSession through Spring's MyBatis framework will throw an exception if - * a transaction is active. - * - * @see SpringManagedTransactionFactory - * @param transactionFactory - * the MyBatis TransactionFactory - */ - public void setTransactionFactory(TransactionFactory transactionFactory) { - this.transactionFactory = transactionFactory; - } - - /** - * NOTE: This class overrides any {@code Environment} you - * have set in the MyBatis config file. This is used only as a placeholder - * name. The default value is - * {@code SqlSessionFactoryBean.class.getSimpleName()}. - * - * @param environment - * the environment name - */ - public void setEnvironment(String environment) { - this.environment = environment; - } - - /** - * {@inheritDoc} - */ - public void afterPropertiesSet() throws Exception { - notNull(dataSource, "Property 'dataSource' is required"); - notNull(sqlSessionFactoryBuilder, - "Property 'sqlSessionFactoryBuilder' is required"); - - this.sqlSessionFactory = buildSqlSessionFactory(); - } - - /** - * Build a {@code SqlSessionFactory} instance. - * - * The default implementation uses the standard MyBatis - * {@code XMLConfigBuilder} API to build a {@code SqlSessionFactory} - * instance based on an Reader. - * - * @return SqlSessionFactory - * @throws IOException - * if loading the config file failed - */ - protected SqlSessionFactory buildSqlSessionFactory() throws IOException { - - Configuration configuration; - - XMLConfigBuilder xmlConfigBuilder = null; - if (this.configLocation != null) { - xmlConfigBuilder = new XMLConfigBuilder( - this.configLocation.getInputStream(), null, - this.configurationProperties); - configuration = xmlConfigBuilder.getConfiguration(); - } else { - if (logger.isDebugEnabled()) { - logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration"); - } - configuration = new Configuration(); - configuration.setVariables(this.configurationProperties); - } - - if (this.objectFactory != null) { - configuration.setObjectFactory(this.objectFactory); - } - - if (this.objectWrapperFactory != null) { - configuration.setObjectWrapperFactory(this.objectWrapperFactory); - } - - if (hasLength(this.typeAliasesPackage)) { - String[] typeAliasPackageArray = tokenizeToStringArray( - this.typeAliasesPackage, - ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); - for (String packageToScan : typeAliasPackageArray) { - configuration.getTypeAliasRegistry().registerAliases( - packageToScan, - typeAliasesSuperType == null ? Object.class - : typeAliasesSuperType); - if (logger.isDebugEnabled()) { - logger.debug("Scanned package: '" + packageToScan - + "' for aliases"); - } - } - } - - if (!isEmpty(this.typeAliases)) { - for (Class typeAlias : this.typeAliases) { - configuration.getTypeAliasRegistry().registerAlias(typeAlias); - if (logger.isDebugEnabled()) { - logger.debug("Registered type alias: '" + typeAlias + "'"); - } - } - } - - if (!isEmpty(this.plugins)) { - for (Interceptor plugin : this.plugins) { - configuration.addInterceptor(plugin); - if (logger.isDebugEnabled()) { - logger.debug("Registered plugin: '" + plugin + "'"); - } - } - } - - if (hasLength(this.typeHandlersPackage)) { - String[] typeHandlersPackageArray = tokenizeToStringArray( - this.typeHandlersPackage, - ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); - for (String packageToScan : typeHandlersPackageArray) { - configuration.getTypeHandlerRegistry().register(packageToScan); - if (logger.isDebugEnabled()) { - logger.debug("Scanned package: '" + packageToScan - + "' for type handlers"); - } - } - } - - if (!isEmpty(this.typeHandlers)) { - for (TypeHandler typeHandler : this.typeHandlers) { - configuration.getTypeHandlerRegistry().register(typeHandler); - if (logger.isDebugEnabled()) { - logger.debug("Registered type handler: '" + typeHandler - + "'"); - } - } - } - - if (xmlConfigBuilder != null) { - try { - xmlConfigBuilder.parse(); - - if (logger.isDebugEnabled()) { - logger.debug("Parsed configuration file: '" - + this.configLocation + "'"); - } - } catch (Exception ex) { - throw new NestedIOException("Failed to parse config resource: " - + this.configLocation, ex); - } finally { - ErrorContext.instance().reset(); - } - } - - if (this.transactionFactory == null) { - this.transactionFactory = new SpringManagedTransactionFactory(); - } - - Environment environment = new Environment(this.environment, - this.transactionFactory, this.dataSource); - configuration.setEnvironment(environment); - - if (this.databaseIdProvider != null) { - try { - configuration.setDatabaseId(this.databaseIdProvider - .getDatabaseId(this.dataSource)); - } catch (SQLException e) { - throw new NestedIOException("Failed getting a databaseId", e); - } - } - // TODO 增加location 获取加载xml的路径,也可配置 - String location = null; - if (!isEmpty(this.mapperLocations)) { - for (Resource mapperLocation : this.mapperLocations) { - if (location == null) { - location = mapperLocation.toString(); - } - if (mapperLocation == null) { - continue; - } - - try { - XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder( - mapperLocation.getInputStream(), configuration, - mapperLocation.toString(), - configuration.getSqlFragments()); - xmlMapperBuilder.parse(); - } catch (Exception e) { - e.printStackTrace(); // 出现错误抛出异常 - throw new NestedIOException( - "Failed to parse mapping resource: '" - + mapperLocation + "'", e); - } finally { - ErrorContext.instance().reset(); - } - - if (logger.isDebugEnabled()) { - logger.debug("Parsed mapper file: '" + mapperLocation + "'"); - } - } - } else { - if (logger.isDebugEnabled()) { - logger.debug("Property 'mapperLocations' was not specified or no matching resources found"); - } - } - - // TODO 编译sqlsession时,启动定时器 - new org.apache.ibatis.thread.Runnable(location, configuration).run(); - - return this.sqlSessionFactoryBuilder.build(configuration); - } - - /** - * {@inheritDoc} - */ - public SqlSessionFactory getObject() throws Exception { - if (this.sqlSessionFactory == null) { - afterPropertiesSet(); - } - - return this.sqlSessionFactory; - } - - /** - * {@inheritDoc} - */ - public Class getObjectType() { - return this.sqlSessionFactory == null ? SqlSessionFactory.class - : this.sqlSessionFactory.getClass(); - } - - /** - * {@inheritDoc} - */ - public boolean isSingleton() { - return true; - } - - /** - * {@inheritDoc} - */ - public void onApplicationEvent(ApplicationEvent event) { - if (failFast && event instanceof ContextRefreshedEvent) { - // fail-fast -> check all statements are completed - this.sqlSessionFactory.getConfiguration().getMappedStatementNames(); - } - } - - /** - * TODO 刷新 - * - * @param inputStream - * @param resource - * @param configuration - * @throws NestedIOException - */ - public static void refresh(java.io.InputStream inputStream, - String resource, Configuration configuration) - throws NestedIOException { - - try { - XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder( - inputStream, configuration, resource, - configuration.getSqlFragments()); - xmlMapperBuilder.parse1(); - } catch (Exception e) { - throw new NestedIOException("Failed to parse mapping resource: '" - + resource + "'", e); - } finally { - ErrorContext.instance().reset(); - } - - } - -} +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org_back.mybatis.spring; + +import static org.springframework.util.Assert.notNull; +import static org.springframework.util.ObjectUtils.isEmpty; +import static org.springframework.util.StringUtils.hasLength; +import static org.springframework.util.StringUtils.tokenizeToStringArray; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Properties; + +import javax.sql.DataSource; + +import org.apache.ibatis.builder.xml.XMLConfigBuilder; +import org.apache.ibatis.builder.xml.XMLMapperBuilder; +import org.apache.ibatis.executor.ErrorContext; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; +import org.apache.ibatis.mapping.DatabaseIdProvider; +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.reflection.factory.ObjectFactory; +import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.apache.ibatis.transaction.TransactionFactory; +import org.apache.ibatis.type.TypeHandler; +import org.mybatis.spring.transaction.SpringManagedTransactionFactory; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.NestedIOException; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; + +/** + * {@code FactoryBean} that creates an MyBatis {@code SqlSessionFactory}. This + * is the usual way to set up a shared MyBatis {@code SqlSessionFactory} in a + * Spring application context; the SqlSessionFactory can then be passed to + * MyBatis-based DAOs via dependency injection. + * + * Either {@code DataSourceTransactionManager} or {@code JtaTransactionManager} + * can be used for transaction demarcation in combination with a + * {@code SqlSessionFactory}. JTA should be used for transactions which span + * multiple databases or when container managed transactions (CMT) are being + * used. + * + * @author Putthibong Boonbong + * @author Hunter Presnall + * @author Eduardo Macarron + * + * @see #setConfigLocation + * @see #setDataSource + * @version $Id$ + * @desctiption 刷新xml文件 + */ +public class SqlSessionFactoryBean implements FactoryBean, + InitializingBean, ApplicationListener { + + private static final Log logger = LogFactory + .getLog(SqlSessionFactoryBean.class); + + private Resource configLocation; + + private Resource[] mapperLocations; + + private DataSource dataSource; + + private TransactionFactory transactionFactory; + + private Properties configurationProperties; + + private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); + + private SqlSessionFactory sqlSessionFactory; + + private String environment = SqlSessionFactoryBean.class.getSimpleName(); // EnvironmentAware requires spring 3.1 + + private boolean failFast; + + private Interceptor[] plugins; + + private TypeHandler[] typeHandlers; + + private String typeHandlersPackage; + + private Class[] typeAliases; + + private String typeAliasesPackage; + + private Class typeAliasesSuperType; + + private DatabaseIdProvider databaseIdProvider; // issue #19. No default provider. + + private ObjectFactory objectFactory; + + private ObjectWrapperFactory objectWrapperFactory; + + /** + * Sets the ObjectFactory. + * + * @since 1.1.2 + * @param objectFactory + */ + public void setObjectFactory(ObjectFactory objectFactory) { + this.objectFactory = objectFactory; + } + + /** + * Sets the ObjectWrapperFactory. + * + * @since 1.1.2 + * @param objectWrapperFactory + */ + public void setObjectWrapperFactory( + ObjectWrapperFactory objectWrapperFactory) { + this.objectWrapperFactory = objectWrapperFactory; + } + + /** + * Gets the DatabaseIdProvider + * + * @since 1.1.0 + * @return + */ + public DatabaseIdProvider getDatabaseIdProvider() { + return databaseIdProvider; + } + + /** + * Sets the DatabaseIdProvider. As of version 1.2.2 this variable is not + * initialized by default. + * + * @since 1.1.0 + * @param databaseIdProvider + */ + public void setDatabaseIdProvider(DatabaseIdProvider databaseIdProvider) { + this.databaseIdProvider = databaseIdProvider; + } + + /** + * Mybatis plugin list. + * + * @since 1.0.1 + * + * @param plugins + * list of plugins + * + */ + public void setPlugins(Interceptor[] plugins) { + this.plugins = plugins; + } + + /** + * Packages to search for type aliases. + * + * @since 1.0.1 + * + * @param typeAliasesPackage + * package to scan for domain objects + * + */ + public void setTypeAliasesPackage(String typeAliasesPackage) { + this.typeAliasesPackage = typeAliasesPackage; + } + + /** + * Super class which domain objects have to extend to have a type alias + * created. No effect if there is no package to scan configured. + * + * @since 1.1.2 + * + * @param typeAliasesSuperType + * super class for domain objects + * + */ + public void setTypeAliasesSuperType(Class typeAliasesSuperType) { + this.typeAliasesSuperType = typeAliasesSuperType; + } + + /** + * Packages to search for type handlers. + * + * @since 1.0.1 + * + * @param typeHandlersPackage + * package to scan for type handlers + * + */ + public void setTypeHandlersPackage(String typeHandlersPackage) { + this.typeHandlersPackage = typeHandlersPackage; + } + + /** + * Set type handlers. They must be annotated with {@code MappedTypes} and + * optionally with {@code MappedJdbcTypes} + * + * @since 1.0.1 + * + * @param typeHandlers + * Type handler list + */ + public void setTypeHandlers(TypeHandler[] typeHandlers) { + this.typeHandlers = typeHandlers; + } + + /** + * List of type aliases to register. They can be annotated with + * {@code Alias} + * + * @since 1.0.1 + * + * @param typeAliases + * Type aliases list + */ + public void setTypeAliases(Class[] typeAliases) { + this.typeAliases = typeAliases; + } + + /** + * If true, a final check is done on Configuration to assure that all mapped + * statements are fully loaded and there is no one still pending to resolve + * includes. Defaults to false. + * + * @since 1.0.1 + * + * @param failFast + * enable failFast + */ + public void setFailFast(boolean failFast) { + this.failFast = failFast; + } + + /** + * Set the location of the MyBatis {@code SqlSessionFactory} config file. A + * typical value is "WEB-INF/mybatis-configuration.xml". + */ + public void setConfigLocation(Resource configLocation) { + this.configLocation = configLocation; + } + + /** + * Set locations of MyBatis mapper files that are going to be merged into + * the {@code SqlSessionFactory} configuration at runtime. + * + * This is an alternative to specifying "<sqlmapper>" entries in an + * MyBatis config file. This property being based on Spring's resource + * abstraction also allows for specifying resource patterns here: e.g. + * "classpath*:sqlmap/*-mapper.xml". + */ + public void setMapperLocations(Resource[] mapperLocations) { + this.mapperLocations = mapperLocations; + } + + /** + * Set optional properties to be passed into the SqlSession configuration, + * as alternative to a {@code <properties>} tag in the configuration + * xml file. This will be used to resolve placeholders in the config file. + */ + public void setConfigurationProperties( + Properties sqlSessionFactoryProperties) { + this.configurationProperties = sqlSessionFactoryProperties; + } + + /** + * Set the JDBC {@code DataSource} that this instance should manage + * transactions for. The {@code DataSource} should match the one used by the + * {@code SqlSessionFactory}: for example, you could specify the same JNDI + * DataSource for both. + * + * A transactional JDBC {@code Connection} for this {@code DataSource} will + * be provided to application code accessing this {@code DataSource} + * directly via {@code DataSourceUtils} or + * {@code DataSourceTransactionManager}. + * + * The {@code DataSource} specified here should be the target + * {@code DataSource} to manage transactions for, not a + * {@code TransactionAwareDataSourceProxy}. Only data access code may work + * with {@code TransactionAwareDataSourceProxy}, while the transaction + * manager needs to work on the underlying target {@code DataSource}. If + * there's nevertheless a {@code TransactionAwareDataSourceProxy} passed in, + * it will be unwrapped to extract its target {@code DataSource}. + * + */ + public void setDataSource(DataSource dataSource) { + if (dataSource instanceof TransactionAwareDataSourceProxy) { + // If we got a TransactionAwareDataSourceProxy, we need to perform + // transactions for its underlying target DataSource, else data + // access code won't see properly exposed transactions (i.e. + // transactions for the target DataSource). + this.dataSource = ((TransactionAwareDataSourceProxy) dataSource) + .getTargetDataSource(); + } else { + this.dataSource = dataSource; + } + } + + /** + * Sets the {@code SqlSessionFactoryBuilder} to use when creating the + * {@code SqlSessionFactory}. + * + * This is mainly meant for testing so that mock SqlSessionFactory classes + * can be injected. By default, {@code SqlSessionFactoryBuilder} creates + * {@code DefaultSqlSessionFactory} instances. + * + */ + public void setSqlSessionFactoryBuilder( + SqlSessionFactoryBuilder sqlSessionFactoryBuilder) { + this.sqlSessionFactoryBuilder = sqlSessionFactoryBuilder; + } + + /** + * Set the MyBatis TransactionFactory to use. Default is + * {@code SpringManagedTransactionFactory} + * + * The default {@code SpringManagedTransactionFactory} should be appropriate + * for all cases: be it Spring transaction management, EJB CMT or plain JTA. + * If there is no active transaction, SqlSession operations will execute SQL + * statements non-transactionally. + * + * It is strongly recommended to use the default + * {@code TransactionFactory}. If not used, any attempt at getting an + * SqlSession through Spring's MyBatis framework will throw an exception if + * a transaction is active. + * + * @see SpringManagedTransactionFactory + * @param transactionFactory + * the MyBatis TransactionFactory + */ + public void setTransactionFactory(TransactionFactory transactionFactory) { + this.transactionFactory = transactionFactory; + } + + /** + * NOTE: This class overrides any {@code Environment} you + * have set in the MyBatis config file. This is used only as a placeholder + * name. The default value is + * {@code SqlSessionFactoryBean.class.getSimpleName()}. + * + * @param environment + * the environment name + */ + public void setEnvironment(String environment) { + this.environment = environment; + } + + /** + * {@inheritDoc} + */ + public void afterPropertiesSet() throws Exception { + notNull(dataSource, "Property 'dataSource' is required"); + notNull(sqlSessionFactoryBuilder, + "Property 'sqlSessionFactoryBuilder' is required"); + + this.sqlSessionFactory = buildSqlSessionFactory(); + } + + /** + * Build a {@code SqlSessionFactory} instance. + * + * The default implementation uses the standard MyBatis + * {@code XMLConfigBuilder} API to build a {@code SqlSessionFactory} + * instance based on an Reader. + * + * @return SqlSessionFactory + * @throws IOException + * if loading the config file failed + */ + protected SqlSessionFactory buildSqlSessionFactory() throws IOException { + + Configuration configuration; + + XMLConfigBuilder xmlConfigBuilder = null; + if (this.configLocation != null) { + xmlConfigBuilder = new XMLConfigBuilder( + this.configLocation.getInputStream(), null, + this.configurationProperties); + configuration = xmlConfigBuilder.getConfiguration(); + } else { + if (logger.isDebugEnabled()) { + logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration"); + } + configuration = new Configuration(); + configuration.setVariables(this.configurationProperties); + } + + if (this.objectFactory != null) { + configuration.setObjectFactory(this.objectFactory); + } + + if (this.objectWrapperFactory != null) { + configuration.setObjectWrapperFactory(this.objectWrapperFactory); + } + + if (hasLength(this.typeAliasesPackage)) { + String[] typeAliasPackageArray = tokenizeToStringArray( + this.typeAliasesPackage, + ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); + for (String packageToScan : typeAliasPackageArray) { + configuration.getTypeAliasRegistry().registerAliases( + packageToScan, + typeAliasesSuperType == null ? Object.class + : typeAliasesSuperType); + if (logger.isDebugEnabled()) { + logger.debug("Scanned package: '" + packageToScan + + "' for aliases"); + } + } + } + + if (!isEmpty(this.typeAliases)) { + for (Class typeAlias : this.typeAliases) { + configuration.getTypeAliasRegistry().registerAlias(typeAlias); + if (logger.isDebugEnabled()) { + logger.debug("Registered type alias: '" + typeAlias + "'"); + } + } + } + + if (!isEmpty(this.plugins)) { + for (Interceptor plugin : this.plugins) { + configuration.addInterceptor(plugin); + if (logger.isDebugEnabled()) { + logger.debug("Registered plugin: '" + plugin + "'"); + } + } + } + + if (hasLength(this.typeHandlersPackage)) { + String[] typeHandlersPackageArray = tokenizeToStringArray( + this.typeHandlersPackage, + ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); + for (String packageToScan : typeHandlersPackageArray) { + configuration.getTypeHandlerRegistry().register(packageToScan); + if (logger.isDebugEnabled()) { + logger.debug("Scanned package: '" + packageToScan + + "' for type handlers"); + } + } + } + + if (!isEmpty(this.typeHandlers)) { + for (TypeHandler typeHandler : this.typeHandlers) { + configuration.getTypeHandlerRegistry().register(typeHandler); + if (logger.isDebugEnabled()) { + logger.debug("Registered type handler: '" + typeHandler + + "'"); + } + } + } + + if (xmlConfigBuilder != null) { + try { + xmlConfigBuilder.parse(); + + if (logger.isDebugEnabled()) { + logger.debug("Parsed configuration file: '" + + this.configLocation + "'"); + } + } catch (Exception ex) { + throw new NestedIOException("Failed to parse config resource: " + + this.configLocation, ex); + } finally { + ErrorContext.instance().reset(); + } + } + + if (this.transactionFactory == null) { + this.transactionFactory = new SpringManagedTransactionFactory(); + } + + Environment environment = new Environment(this.environment, + this.transactionFactory, this.dataSource); + configuration.setEnvironment(environment); + + if (this.databaseIdProvider != null) { + try { + configuration.setDatabaseId(this.databaseIdProvider + .getDatabaseId(this.dataSource)); + } catch (SQLException e) { + throw new NestedIOException("Failed getting a databaseId", e); + } + } + // TODO 增加location 获取加载xml的路径,也可配置 + String location = null; + if (!isEmpty(this.mapperLocations)) { + for (Resource mapperLocation : this.mapperLocations) { + if (location == null) { + location = mapperLocation.toString(); + } + if (mapperLocation == null) { + continue; + } + + try { + XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder( + mapperLocation.getInputStream(), configuration, + mapperLocation.toString(), + configuration.getSqlFragments()); + xmlMapperBuilder.parse(); + } catch (Exception e) { + e.printStackTrace(); // 出现错误抛出异常 + throw new NestedIOException( + "Failed to parse mapping resource: '" + + mapperLocation + "'", e); + } finally { + ErrorContext.instance().reset(); + } + + if (logger.isDebugEnabled()) { + logger.debug("Parsed mapper file: '" + mapperLocation + "'"); + } + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("Property 'mapperLocations' was not specified or no matching resources found"); + } + } + + // TODO 编译sqlsession时,启动定时器 + new org.apache.ibatis.thread.Runnable(location, configuration).run(); + + return this.sqlSessionFactoryBuilder.build(configuration); + } + + /** + * {@inheritDoc} + */ + public SqlSessionFactory getObject() throws Exception { + if (this.sqlSessionFactory == null) { + afterPropertiesSet(); + } + + return this.sqlSessionFactory; + } + + /** + * {@inheritDoc} + */ + public Class getObjectType() { + return this.sqlSessionFactory == null ? SqlSessionFactory.class + : this.sqlSessionFactory.getClass(); + } + + /** + * {@inheritDoc} + */ + public boolean isSingleton() { + return true; + } + + /** + * {@inheritDoc} + */ + public void onApplicationEvent(ApplicationEvent event) { + if (failFast && event instanceof ContextRefreshedEvent) { + // fail-fast -> check all statements are completed + this.sqlSessionFactory.getConfiguration().getMappedStatementNames(); + } + } + + /** + * TODO 刷新 + * + * @param inputStream + * @param resource + * @param configuration + * @throws NestedIOException + */ + public static void refresh(java.io.InputStream inputStream, + String resource, Configuration configuration) + throws NestedIOException { + + try { + XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder( + inputStream, configuration, resource, + configuration.getSqlFragments()); + xmlMapperBuilder.parse1(); + } catch (Exception e) { + throw new NestedIOException("Failed to parse mapping resource: '" + + resource + "'", e); + } finally { + ErrorContext.instance().reset(); + } + + } + +}