基于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>
- 基于PetShop的数据可视化网站(二):缓存依赖
- 基于PetShop的数据可视化网站(三):可视化插件
- 基于PetShop的数据可视化网站(一):基本结构
- 基于PetShop的数据可视化网站(五):关于登录的理解
- 基于PetShop的数据可视化网站(四):自定义成员资格
- 使用基于轮询的SQL数据缓存依赖
- 基于内存缓冲区的流媒体数据缓存排序(二)
- 基于hadoop生态圈的数据仓库实践 —— OLAP与数据可视化(二)
- 基于hadoop生态圈的数据仓库实践 —— OLAP与数据可视化(二)
- 数据可视化matplotlib的应用(二)
- petshop的缓存输出
- PetShop缓存的实现
- 『数据可视化』基于Python的数据可视化工具
- 数据可视化漫谈(二)
- python 数据可视化(二)
- PYTHON数据可视化(二)
- 基于ggplot2的R 语言数据可视化(一)
- 企业库缓存依赖的实现-基于文件依赖
- 【 bzoj 1014 】 [JSOI2008]火星人prefix
- CLLocation定位
- poj3614 二分图最大匹配 or 贪心
- 3DES加密—java/OC
- springmvc(十三)springmvc注解开发-springmvc参数绑定-包装类型pojo参数绑定
- 基于PetShop的数据可视化网站(二):缓存依赖
- cvCalcEMD2() 直方图匹配
- 闲聊:项目延期,怎么回事?
- 集合_数组_字典
- ZooKeeper架构
- HDU 3415 Max Sum of Max-K-sub-sequence - dp&单调队列优化
- 嵌入式开发与ARM基础 s3c2440
- 【 bzoj 3545 】 [ONTAK2010]Peaks - Treap快速合并
- hdoj--1533--Going Home(KM)