基于PetShop的数据可视化网站(二):缓存依赖

来源:互联网 发布:女明星的淘宝店铺 编辑:程序博客网 时间:2024/04/27 23:46

在系列(一)中,我简单的介绍了数据的提取过程,这次将简单的介绍下缓存依赖。

具体的项目文件可以参考我的github仓库

缓存依赖使用前提

在某些情况下,我们可能会不断的查询数据库,当查询的次数较多并且数据库表内容较多时,网页的加载速度将会慢的令人发指。因此当访问此数据库表的用户较多或程序访问此数据库表的频率较高时,我们可以建立数据库缓存依赖来改善加载速度。

数据库缓存依赖需要首先得到SQL数据库支持,可以参考李天平老师的博文中第二步做法进行实现。

缓存依赖的结构

和PetShop的DAL结构差不多,缓存依赖也分为缓存依赖类接口(ICacheDependency),缓存依赖实现类(TableCacheDependency)和缓存依赖类的工厂类(CacheDependencyFactory)。

缓存依赖类接口

接口文件非常简单,仅仅要求实现类实现GetDependency()方法,代码如下:

using System.Web.Caching;namespace FWSync.ICacheDependency{    public interface IFWSyncCacheDependency    {        AggregateCacheDependency GetDependency();    }}

缓存依赖实现类

在缓存依赖实现类中,TableDependency.cs是所有实现类的基类,其实现了接口中的方法,并且增加了一个读取缓存依赖数据库的方法。

同时,我们还应该为相应的数据库表建立缓存依赖实现类,具体代码如下:

TableDependency.cs

using System.Web.Caching;using System.Configuration;namespace FWSync.TableCacheDependency{    public abstract class TableDependency : FWSync.ICacheDependency.IFWSyncCacheDependency    {        protected char[] configurationSeparator = new char[] { ',' };        protected AggregateCacheDependency dependency = new AggregateCacheDependency();        protected TableDependency(string configKey)        {            string dbName = ConfigurationManager.AppSettings["CacheDatabaseName"];            string tableConfig = ConfigurationManager.AppSettings[configKey];            string[] tables = tableConfig.Split(configurationSeparator);            foreach (string tableName in tables)                dependency.Add(new SqlCacheDependency(dbName, tableName));        }        public AggregateCacheDependency GetDependency()        {            return dependency;        }    }}

Device.cs

using System.Web.Caching;namespace FWSync.TableCacheDependency{    public class Device : TableDependency    {        public Device() : base("DeviceTableDependency") { }    }}

缓存依赖类工厂类

这里工厂类的作用依然是创建相应缓存依赖类的实例,作为一种固定格式来使用即可。

工厂类包含两个类,代码分别如下:

DependencyAccess.cs

using System;using System.Reflection;using System.Configuration;using FWSync.ICacheDependency;namespace FWSync.CacheDependencyFactory{    public static class DependencyAccess    {        private static readonly string path = ConfigurationSettings.AppSettings["Cache"];        private static IFWSyncCacheDependency LoadInstance(string className)        {            string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];            string fullyQualifiedClass = path + "." + className;            return (IFWSyncCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);        }        public static IFWSyncCacheDependency CreateDependency()        {            string className = path + ".TableDependency";            return (IFWSyncCacheDependency)Assembly.Load(path).CreateInstance(className);        }        public static IFWSyncCacheDependency CreateDeviceDependency()        {            return LoadInstance("Device");        }    }}

DependencyFacade.cs

using System.Configuration;using System.Web.Caching;using System.Collections.Generic;using FWSync.ICacheDependency;namespace FWSync.CacheDependencyFactory{    public static class DependencyFacade    {        private static readonly string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];        public static AggregateCacheDependency GetDependency()        {            return DependencyAccess.CreateDependency().GetDependency();        }        public static AggregateCacheDependency GetDeviceDependency()        {            if (!string.IsNullOrEmpty(path))                return DependencyAccess.CreateDeviceDependency().GetDependency();            else                return null;        }    }}

缓存依赖在表现层的应用

上述操作个人认为是建立了一个Cache对象,在表现层中,我们可以建立一个静态方法,即每当需要访问数据库表时,首先查询下Cache对象中是否有未过期的数据,如果有,直接从Cache对象中提取需要的数据,否则将从数据库表中提取数据,并缓存到Cache对象中。下面是表现层中App_Code中DeviceDataProxy.cs的代码:

using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Collections.Generic;using System.Web.Caching;using FWSync.Model;using FWSync.BLL;using FWSync.CacheDependencyFactory;namespace FWSync.Web{    public static class DeviceDataProxy    {        private static readonly int DeviceTimeout = int.Parse(ConfigurationManager.AppSettings["DeviceCacheDuration"]);        private static readonly bool enableCaching = bool.Parse(ConfigurationManager.AppSettings["EnableCaching"]);        public static IList<DeviceInfo> GetDevices()        {            Device dev = new Device();            if (!enableCaching)                return dev.GetDevices();            string key = "device_all";            IList<DeviceInfo> data = (IList<DeviceInfo>)HttpRuntime.Cache[key];            if (data == null)            {                data = dev.GetDevices();                AggregateCacheDependency cd = DependencyFacade.GetDeviceDependency();                HttpRuntime.Cache.Add(key, data, cd, DateTime.Now.AddHours(DeviceTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);            }            return data;        }        public static DeviceInfo GetDeviceByID(int deviceid)        {            Device dev = new Device();            if (!enableCaching)                return dev.GetDeviceByID(deviceid);            string key = "device_" + deviceid;            DeviceInfo data = (DeviceInfo)HttpRuntime.Cache[key];            if (data == null)            {                data = dev.GetDeviceByID(deviceid);                AggregateCacheDependency cd = DependencyFacade.GetDeviceDependency();                HttpRuntime.Cache.Add(key, data, cd, DateTime.Now.AddHours(DeviceTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);            }            return data;        }    }}

这时,我们可以将系列(一)中DeviceDemo.aspx.cs的代码进行修改,即将:

Device dev = new Device();dinfo = dev.GetDevices();

改为:

dinfo = DeviceDataProxy.GetDevices();

这里附上web.config的代码

<?xml version="1.0"?><configuration>    <appSettings>        <!-- Pet Shop DAL configuration settings -->        <add key="WebDAL" value="FWSync.SQLServerDAL"/>        <!-- Enable data caching -->        <add key="EnableCaching" value="true"/>        <!-- Cache duration (in hours-whole number only) -->    <add key="DeviceCacheDuration" value="12"/>    <add key="OriginalDataCacheDuration" value="12"/>    <add key="ParamCacheDuration" value="12"/>    <add key="UserCacheDuration" value="12"/>        <!-- Cache dependency options. Possible values: PetShop.TableCacheDependency - SQL Server and keep empty for ORACLE -->        <add key="CacheDependencyAssembly" value="FWSync.TableCacheDependency"/>        <!-- CacheDatabaseName should match the name under caching section, when using TableCacheDependency -->        <!--<add key="CacheDatabaseName" value="FWMoniterSqlCache"/>-->    <add key="CacheDatabaseName" value="ArduinoTestDB"/>        <!-- *TableDependency lists table dependency for each instance separated by comma -->    <add key="DeviceTableDependency" value="Device"/>    <add key="OriginalDataTableDependency" value="OriginalData"/>    <add key="ParamTableDependency" value="Param"/>    <add key="UserTableDependency" value="User"/>        <!-- Application Error Log -->        <add key="Event Log Source" value=".NET Pet Shop 4.0"/>        <add key="Cache" value="TableCacheDependency"/>        <add key="dbName" value="ArduinoTestDB"/>        <add key="tbStrs" value="Device|OriginalData|Param|User"/>    </appSettings>    <connectionStrings>        <add name="SQLConnString1" connectionString="server=172.18.128.66;user id=my;password=my;database=ArduinoTestDB;min pool size=4;max pool size=4;packet size=3072" providerName="System.Data.SqlClient"/>        <!-- SQL connection string for handling transactions on the Inventory database-->        <add name="SQLConnString2" connectionString="server=172.18.128.66;user id=my;password=my;database=ArduinoTestDB;min pool size=4;max pool size=4;packet size=3072" providerName="System.Data.SqlClient"/>        <!-- SQL connection string for Orders database-->        <add name="SQLConnString3" connectionString="server=172.18.128.66;user id=my;password=my;database=ArduinoTestDB;min pool size=4;max pool size=4;packet size=3072" providerName="System.Data.SqlClient"/>    </connectionStrings>    <system.web>        <httpHandlers>            <add path="Reserved.ReportViewerWebControl.axd" verb="*" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="false"/>        </httpHandlers>        <caching>            <outputCache enableOutputCache="true"/>            <outputCacheSettings>                <outputCacheProfiles>                    <add name="FWMoniterPageCache" duration="10" enabled="true"/>                </outputCacheProfiles>            </outputCacheSettings>            <sqlCacheDependency enabled="true" pollTime="10000">                <databases>                    <add name="ArduinoTestDB" connectionStringName="SQLConnString1" pollTime="10000"/>                </databases>            </sqlCacheDependency>        </caching>        <compilation debug="true" targetFramework="4.0">            <assemblies>                <add assembly="Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="Microsoft.ReportViewer.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>                <add assembly="System.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>                <add assembly="System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>                <add assembly="System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>                <add assembly="System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.DirectoryServices.Protocols, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>                <add assembly="System.Web.RegularExpressions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="System.Data.OracleClient, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>                <add assembly="System.Runtime.Serialization.Formatters.Soap, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>                <add assembly="Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies>            <buildProviders>                <add extension=".rdlc" type="Microsoft.Reporting.RdlBuildProvider, Microsoft.ReportViewer.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>            </buildProviders>    </compilation>    <membership defaultProvider="MyMemberShip">      <providers>        <clear/>        <add name="MyMemberShip" type="FWSync.BLL.MemberShipProvider,FWSync.BLL"/>      </providers>    </membership>    <authentication mode="Forms">      <forms name="Ticker"></forms>    </authentication>    <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">            <error statusCode="403" redirect="NoAccess.htm"/>            <error statusCode="404" redirect="FileNotFound.htm"/>    </customErrors>    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/></system.web>    <system.webServer>        <validation validateIntegratedModeConfiguration="false"/>    </system.webServer></configuration>
0 0
原创粉丝点击