/// <summary>
        /// Builds the the iBATIS core model (statement, alias, resultMap, parameterMap, dataSource)
        /// from an <see cref="IConfigurationStore"/> and store all the refrences in an <see cref="IModelStore"/> .
        /// </summary>
        /// <param name="configurationSetting">The configuration setting.</param>
        /// <param name="store">The configuration store.</param>
        /// <returns>The model store</returns>
        public virtual void BuildModel(ConfigurationSetting configurationSetting, IConfigurationStore store)
        {
            IObjectFactory objectFactory = null;
            IGetAccessorFactory getAccessorFactory = null;
            ISetAccessorFactory setAccessorFactory = null;
            ISessionFactory sessionFactory = null;
            ISessionStore sessionStore = null;
            
            if (configurationSetting != null)
            {
                objectFactory = configurationSetting.ObjectFactory;
                setAccessorFactory = configurationSetting.SetAccessorFactory;
                getAccessorFactory = configurationSetting.GetAccessorFactory;
                dataSource = configurationSetting.DataSource;
                sessionFactory = configurationSetting.SessionFactory;
                sessionStore = configurationSetting.SessionStore;
                dynamicSqlEngine = configurationSetting.DynamicSqlEngine;
                isCacheModelsEnabled = configurationSetting.IsCacheModelsEnabled;
                useStatementNamespaces = configurationSetting.UseStatementNamespaces;
                useReflectionOptimizer = configurationSetting.UseReflectionOptimizer;
                preserveWhitespace = configurationSetting.PreserveWhitespace;
            }
            
            // Xml setting override code setting
            LoadSetting(store);

            if (objectFactory == null)
            {
                objectFactory = new ObjectFactory(useReflectionOptimizer);
            }
            if (setAccessorFactory == null)
            {
                setAccessorFactory = new SetAccessorFactory(useReflectionOptimizer);
            }
            if (getAccessorFactory == null)
            {
                getAccessorFactory = new GetAccessorFactory(useReflectionOptimizer);
            }
            AccessorFactory accessorFactory = new AccessorFactory(setAccessorFactory, getAccessorFactory);

            TypeHandlerFactory typeHandlerFactory = new TypeHandlerFactory();
            TypeAlias alias = new TypeAlias("MEMORY", typeof(PerpetualCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("Perpetual", typeof(PerpetualCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("LRU", typeof(LruCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("Lru", typeof(LruCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("FIFO", typeof(FifoCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("Fifo", typeof(FifoCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("Weak", typeof(WeakCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("WEAK", typeof(WeakCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("AnsiStringTypeHandler", typeof(AnsiStringTypeHandler));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            
            modelStore.DataExchangeFactory = new DataExchangeFactory(typeHandlerFactory, objectFactory, accessorFactory);

            if (sessionStore == null)
            {
                sessionStore = SessionStoreFactory.GetSessionStore(modelStore.Id);
            }
            modelStore.SessionStore = sessionStore;
            
            deSerializerFactory = new DeSerializerFactory(modelStore); 

            ParameterMap emptyParameterMap = new ParameterMap(
                ConfigConstants.EMPTY_PARAMETER_MAP,
                string.Empty,
                string.Empty,
                typeof(string),
                modelStore.DataExchangeFactory.GetDataExchangeForClass(null), 
                false);
            modelStore.AddParameterMap(emptyParameterMap);

            BuildProviders(store);
            BuildDataSource(store);

            if (sessionFactory == null)
            {
                sessionFactory = new DefaultSessionFactory(
                    dataSource, 
                    modelStore.SessionStore,
                    new DefaultTransactionManager(new AdoTransactionFactory()));
            }
            modelStore.SessionFactory = sessionFactory;

            BuildTypeAlias(store);
            BuildTypeHandlers(store);
            BuildCacheModels(store);
            BuildResultMaps(store);

            for (int i = 0; i < nestedProperties.Count; i++)
            {
                ResultProperty property = nestedProperties[i];
                property.NestedResultMap = modelStore.GetResultMap(property.NestedResultMapName);
            }

            for (int i = 0; i < discriminators.Count; i++)
            {
                discriminators[i].Initialize(modelStore);
            }
            BuildParameterMaps(store);
            BuildMappedStatements(store, configurationSetting);

            for (int i = 0; i < store.CacheModels.Length; i++)
            {
                CacheModel cacheModel = modelStore.GetCacheModel(store.CacheModels[i].Id);

                for (int j = 0; j < cacheModel.StatementFlushNames.Count; j++)
                {
                    string statement = cacheModel.StatementFlushNames[j];
                    IMappedStatement mappedStatement = modelStore.GetMappedStatement(statement);
                    if (mappedStatement != null)
                    {
                        cacheModel.RegisterTriggerStatement(mappedStatement);
                        if (logger.IsDebugEnabled)
                        {
                            logger.Debug("Registering trigger statement [" + statement + "] to cache model [" + cacheModel.Id + "]");
                        }
                    }
                    else
                    {
                        if (logger.IsWarnEnabled)
                        {
                            logger.Warn("Unable to register trigger statement [" + statement + "] to cache model [" + cacheModel.Id + "]. Statement does not exist.");
                        }
                    }

                }
            }

            if (logger.IsInfoEnabled)
            {
                logger.Info("Model Store");
                logger.Info(modelStore.ToString());
            }
        }
        public void TestSetIntegerPerformance()
        {
            const int TEST_ITERATIONS = 1000000;
            Property prop = new Property();
            int value = 123;
            Timer timer = new Timer();

            #region Direct access (fastest)
            GC.Collect();
            GC.WaitForPendingFinalizers();

            timer.Start();
            for (int i = 0; i < TEST_ITERATIONS; i++)
            {
                prop.Int = value;
            }
            timer.Stop();
            double directAccessDuration = 1000000 * (timer.Duration / (double)TEST_ITERATIONS);
            #endregion

            #region Property accessor
            GC.Collect();
            GC.WaitForPendingFinalizers();

            ISetAccessorFactory factory = new SetAccessorFactory(true);
            ISetAccessor propertyAccessor = factory.CreateSetAccessor(typeof(Property), "Int");
            timer.Start();
            for (int i = 0; i < TEST_ITERATIONS; i++)
            {
                propertyAccessor.Set(prop, value);
            }
            timer.Stop();
            double propertyAccessorDuration = 1000000 * (timer.Duration / (double)TEST_ITERATIONS);
            double propertyAccessorRatio = propertyAccessorDuration / directAccessDuration;
            #endregion

            #region IBatisNet.Common.Utilities.Object.ReflectionInfo
            GC.Collect();
            GC.WaitForPendingFinalizers();

            Type type = prop.GetType();
            ReflectionInfo reflectionInfo = ReflectionInfo.GetInstance(type);
            timer.Start();
            for (int i = 0; i < TEST_ITERATIONS; i++)
            {
                PropertyInfo propertyInfo = (PropertyInfo)reflectionInfo.GetSetter("Int");
                propertyInfo.SetValue(prop, value, null);
            }
            timer.Stop();
            double reflectionInfoDuration = 1000000 * (timer.Duration / (double)TEST_ITERATIONS);
            double reflectionInfoRatio = reflectionInfoDuration / directAccessDuration;
            #endregion

            #region Reflection
            GC.Collect();
            GC.WaitForPendingFinalizers();

            timer.Start();
            for (int i = 0; i < TEST_ITERATIONS; i++)
            {
                PropertyInfo propertyInfo = type.GetProperty("Int", BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance);
                propertyInfo.SetValue(prop, value, null);
            }
            timer.Stop();
            double reflectionDuration = 1000000 * (timer.Duration / (double)TEST_ITERATIONS);
            double reflectionRatio = reflectionDuration / directAccessDuration;
            #endregion

            #region ReflectionInvokeMember (slowest)
            GC.Collect();
            GC.WaitForPendingFinalizers();

            timer.Start();
            for (int i = 0; i < TEST_ITERATIONS; i++)
            {
                type.InvokeMember("Int",
                    BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance,
                    null, prop, new object[] { value });
            }
            timer.Stop();
            double reflectionInvokeMemberDuration = 1000000 * (timer.Duration / (double)TEST_ITERATIONS);
            double reflectionInvokeMemberRatio = reflectionInvokeMemberDuration / directAccessDuration;
            #endregion

            // Print results
            Console.WriteLine("{0} property sets on integer...", TEST_ITERATIONS);
            Console.WriteLine("Direct access: \t\t{0} ", directAccessDuration.ToString("F3"));
            Console.WriteLine("IMemberAccessor: \t\t{0} Ratio: {1}", propertyAccessorDuration.ToString("F3"), propertyAccessorRatio.ToString("F3"));
            Console.WriteLine("IBatisNet ReflectionInfo: \t{0} Ratio: {1}", reflectionInfoDuration.ToString("F3"), reflectionInfoRatio.ToString("F3"));
            Console.WriteLine("ReflectionInvokeMember: \t{0} Ratio: {1}", reflectionInvokeMemberDuration.ToString("F3"), reflectionInvokeMemberRatio.ToString("F3"));
            Console.WriteLine("Reflection: \t\t\t{0} Ratio: {1}", reflectionDuration.ToString("F3"), reflectionRatio.ToString("F3"));
        }
Beispiel #3
0
        /// <summary>
        /// Builds the the iBATIS core model (statement, alias, resultMap, parameterMap, dataSource)
        /// from an <see cref="IConfigurationStore"/> and store all the refrences in an <see cref="IModelStore"/> .
        /// </summary>
        /// <param name="configurationSetting">The configuration setting.</param>
        /// <param name="store">The configuration store.</param>
        /// <returns>The model store</returns>
        public virtual void BuildModel(ConfigurationSetting configurationSetting, IConfigurationStore store)
        {
            IObjectFactory objectFactory = null;
            IGetAccessorFactory getAccessorFactory = null;
            ISetAccessorFactory setAccessorFactory = null;
            ISessionFactory sessionFactory = null;
            ISessionStore sessionStore = null;
            
            if (configurationSetting != null)
            {
                objectFactory = configurationSetting.ObjectFactory;
                setAccessorFactory = configurationSetting.SetAccessorFactory;
                getAccessorFactory = configurationSetting.GetAccessorFactory;
                dataSource = configurationSetting.DataSource;
                sessionFactory = configurationSetting.SessionFactory;
                sessionStore = configurationSetting.SessionStore;
                dynamicSqlEngine = configurationSetting.DynamicSqlEngine;
                isCacheModelsEnabled = configurationSetting.IsCacheModelsEnabled;
                useStatementNamespaces = configurationSetting.UseStatementNamespaces;
                useReflectionOptimizer = configurationSetting.UseReflectionOptimizer;
                preserveWhitespace = configurationSetting.PreserveWhitespace;
            }
            
            // Xml setting override code setting 
            //取store中的数据初始化类成员 为下面做准备
            LoadSetting(store);

            if (objectFactory == null)
            {
                objectFactory = new ObjectFactory(useReflectionOptimizer);
            }
            if (setAccessorFactory == null)
            {
                setAccessorFactory = new SetAccessorFactory(useReflectionOptimizer);
            }
            if (getAccessorFactory == null)
            {
                getAccessorFactory = new GetAccessorFactory(useReflectionOptimizer);
            }
            AccessorFactory accessorFactory = new AccessorFactory(setAccessorFactory, getAccessorFactory);

            TypeHandlerFactory typeHandlerFactory = new TypeHandlerFactory();
            TypeAlias alias = new TypeAlias("MEMORY", typeof(PerpetualCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("Perpetual", typeof(PerpetualCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("LRU", typeof(LruCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("Lru", typeof(LruCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("FIFO", typeof(FifoCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("Fifo", typeof(FifoCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("Weak", typeof(WeakCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("WEAK", typeof(WeakCache));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("MemCached", typeof(MemCached));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);
            alias = new TypeAlias("MEMCACHED", typeof(MemCached));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            alias = new TypeAlias("AnsiStringTypeHandler", typeof(AnsiStringTypeHandler));
            typeHandlerFactory.AddTypeAlias(alias.Id, alias);

            //将以上类信息存入到modelStore中 实质性工作
            modelStore.DataExchangeFactory = new DataExchangeFactory(typeHandlerFactory, objectFactory, accessorFactory);

            if (sessionStore == null)
            {
                sessionStore = SessionStoreFactory.GetSessionStore(modelStore.Id);
            }
            //将ISessionStore类对象存入modelStore中 准备数据库的连接 与 事物操作功能  实质性工作
            modelStore.SessionStore = sessionStore;

            //初始化DefaultModelBuilder的成员变量 
            deSerializerFactory = new DeSerializerFactory(modelStore); 

            //设置一个空类型的参数映射类
            ParameterMap emptyParameterMap = new ParameterMap(
                ConfigConstants.EMPTY_PARAMETER_MAP,
                string.Empty,
                string.Empty,
                typeof(string),
                modelStore.DataExchangeFactory.GetDataExchangeForClass(null), //获得ComplexDataExchange对象
                false);

            //向参数字典中添加一个空参数类
            modelStore.AddParameterMap(emptyParameterMap);

            //完成了对DefaultModelBuilder成员变量dbProviderFactory的初始化,其中完成了对provider使用中节点的类初始化
            BuildProviders(store);

            //完成了对DefaultModelBuilder成员变量IDataSource的初始化,包括数据库的名字 连接字符串 以及DbPrivder类
            BuildDataSource(store);

            if (sessionFactory == null)
            {
                sessionFactory = new DefaultSessionFactory(
                    dataSource, 
                    modelStore.SessionStore,
                    new DefaultTransactionManager(new AdoTransactionFactory()));
            }
            //初始化modelStore中的ISessionFactory变量
            modelStore.SessionFactory = sessionFactory;

            //将具体SQLXML配置文件中的Alias节点对应的别名信息写入到modelStore中的TypeHandlerFactory的字典中
            BuildTypeAlias(store);

            //将TypeHanders下的子节点信息放入 modelStore.DataExchangeFactory.TypeHandlerFactory中的字典当中
            BuildTypeHandlers(store);

            //将cacheModels下子节点cacheModel加入到modelStore的CacheModel字典中
            BuildCacheModels(store);
            //将resultMap节点信息添加到modelStore的resultMaps中
            BuildResultMaps(store);

            //为resultMapping属性所在的节点信息类设置对应的ResultProperty
            for (int i = 0; i < nestedProperties.Count; i++)
            {
                ResultProperty property = nestedProperties[i];
                property.NestedResultMap = modelStore.GetResultMap(property.NestedResultMapName);
            }

            for (int i = 0; i < discriminators.Count; i++)
            {
                //完成对discriminator类中对字典的初始化
                discriminators[i].Initialize(modelStore);
            }
            //将parameter节点信息添加到modelStore类中的parameterMaps字典中
            BuildParameterMaps(store);

            //将statements下的节点添加到modelStore的statements的字典中
            BuildMappedStatements(store, configurationSetting);

            for (int i = 0; i < store.CacheModels.Length; i++)
            {
                CacheModel cacheModel = modelStore.GetCacheModel(store.CacheModels[i].Id);

                for (int j = 0; j < cacheModel.StatementFlushNames.Count; j++)
                {
                    string statement = cacheModel.StatementFlushNames[j];
                    IMappedStatement mappedStatement = modelStore.GetMappedStatement(statement);
                    if (mappedStatement != null)
                    {
                        //为IMappedStatement类的Executed制定委托事件  目的是清空缓存
                        cacheModel.RegisterTriggerStatement(mappedStatement);
                        if (logger.IsDebugEnabled)
                        {
                            logger.Debug("Registering trigger statement [" + statement + "] to cache model [" + cacheModel.Id + "]");
                        }
                    }
                    else
                    {
                        if (logger.IsWarnEnabled)
                        {
                            logger.Warn("Unable to register trigger statement [" + statement + "] to cache model [" + cacheModel.Id + "]. Statement does not exist.");
                        }
                    }

                }
            }

            if (logger.IsInfoEnabled)
            {
                logger.Info("Model Store");
                logger.Info(modelStore.ToString());
            }
        }