• 缓存依赖


    16.3  缓存依赖类:CacheDependency类

    CacheDependency类是架设在Cache类和实际数据之间的桥梁。本节将详细介绍如何利用CacheDependency类实现数据缓存的及时更新。

    16.3.1  功能说明

    CacheDependency类被称为是缓存依赖类,其具体意义表现在当缓存对象的实际数据发生改变时,它能及时通知缓存对象。例如缓存对象“Category”保存的是一个XML文件的数据,如果XML文件发生了变化,那么系统通过CacheDependency类就会及时更新缓存对象“Category”的内容,这样就能保证用户读取的永远是最新的数据。

    16.3.2  语法定义

    CacheDependency类的语法定义如下:

    public class CacheDependency : IDisposable

    其中继承了接口“IDisposable”,此接口主要用来定义释放分配的非托管资源的方法。继承此接口必须实现方法Dispose,以实现资源的释放。

    CacheDependency类的构造函数实现了8个重载,下面的代码列出了这些重载的函数,并详细说明了各函数的参数。了解这些函数就可以知道CacheDependency究竟能为缓存带来什么优势。

        //假设缓存的来源文件是当前目录下的data.xml文件

        //缓存依赖的文件路径

        CacheDependency mydep = new CacheDependency("data.xml");

        //缓存依赖的文件可以有多个

        CacheDependency mydep1=new CacheDependency(new string []{"data.xml","data1.xml"});

        //检查缓存依赖更改的依据时间

        CacheDependency mydep2 = new CacheDependency("data.xml", DateTime.Now);

        //检查多个依赖文件更改的依据时间

        CacheDependency mydep3 = new CacheDependency(new string[] { "data.xml", "data1.xml" }, DateTime.Now);

        //检查依赖多个文件,也依赖多个缓存键值

        CacheDependency mydep4 = new CacheDependency(new string[] { "data.xml", "data1.xml" },

            new string[] { "Category", "Category1" });

        //关联依赖,还可以依赖于另一个文件缓存依赖

        CacheDependency mydep5 = new CacheDependency(new string[] { "data.xml", "data1.xml" },

            new string[] { "Category", "Category1" }, mydep);

        //文件和键值上次修改的依据时间

        CacheDependency mydep6 = new CacheDependency(new string[] { "data.xml", "data1.xml" },

            new string[] { "Category", "Category1" }, DateTime.Now);

        //文件、另一个缓存依赖和键值上次修改的依据时间

        CacheDependency mydep6 = new CacheDependency(new string[] { "data.xml", "data1.xml" },

    new string[] { "Category", "Category1" }, mydep,DateTime.Now);

    16.3.3  方法和属性

    虽然CacheDependency类完成了很重要的功能,但其组成结构却比较简单,主要有两个属性和一个方法。

    — 属性“HasChanged”:判断CacheDependency对象是否已更改。

    — 属性“UtcLastModified”:返回上次依赖项的修改日期

    — 方法“Dispose”:释放CacheDependency对象所占有的资源。因为缓存类继承了接口“IDispose”,所以必须实现此方法。

    由于缓存类的构成比较简单,本节并没有给出演示代码,属性和方法的使用将在下一节的实例中演示。

    注意:只有Cache类的Insert和Add方法才可以为缓存添加依赖项。

    16.3.4  典型应用:用CacheDependency获取最新的数据

    本例主要演示如何使用CacheDependency类实现数据的及时更新。实例中使用一个GridView控件显示XML文件的数据,当XML文件的数据发生改变时,客户端可以及时更新。其实现的功能如图16-3所示。

     

    图16-3  用CacheDependency获取最新数据的功能实现图

    演示的详细步骤如下所述。

         打开VS2005,创建一个网站,命名为“CacheDependencySample”。

         在网站根目录下,添加一个XML文件,用来为控件提供数据,内容如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <book>

         <bookinfo>

             <name>英国古代</name>

             <price>28.00</price>

         </bookinfo>

         <bookinfo>

             <name>中国历史</name>

             <price>20.00</price>

         </bookinfo>

    </book>

         打开默认生成的Default.aspx页,添加一个GridView控件和一个按钮控件。

         按F7键切换到窗体的代码视图,在Page_Load事件中书写生成缓存的代码。详细内容如下:

    private static CacheDependency mydepen;

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!IsPostBack)

        {

            //创建XML数据源

            DataSet myds = new DataSet();

            //数据源来自文件data.xml

            myds.ReadXml(this.MapPath(Request.ApplicationPath + @"/data.xml"));

            //判断是否存在缓存

            if (Cache["BOOKS"] == null)

            {

                //创建缓存依赖

               mydepen = new CacheDependency(this.MapPath(Request.ApplicationPath

                    + @"/data.xml"));

                //添加缓存项

                Cache.Add("BOOKS", myds, mydepen, DateTime.Now.AddSeconds(10), TimeSpan.Zero,

                    CacheItemPriority.Normal, null);

            }

        }

    }

    注意:使用XML文件读取方法,必须添加XML操作方法所在的命名空间“System.Xml”。

         切换回设计视图,再双击按钮控件,此时光标停靠在按钮的Click事件内。在此事件内书写代码,判断XML文件的数据是否已更新,如果已更新则给出提示,并重新添加缓存依赖项,否则直接从缓存读取GridView控件的数据。

         在“Button1_Click”事件内书写的详细代码如下:

    protected void Button1_Click(object sender, EventArgs e)

    {

        //判断缓存是否发生了变化

        if (mydepen.HasChanged)

        {

            Response.Write("Sorry,数据发生了变化!上次修改时间是:" + mydepen.UtcLastModified);

        }

        //判断缓存项是否还在

        if (Cache["BOOKS"] == null)

            {

            //重新设置缓存项

                DataSet myds = new DataSet();

                myds.ReadXml(this.MapPath(Request.ApplicationPath + @"/data.xml"));

                mydepen = new CacheDependency(this.MapPath(Request.ApplicationPath + @"/ data.xml"));

            Cache.Add("BOOKS", myds, mydepen, DateTime.Now.AddSeconds(10), TimeSpan.Zero,

    CacheItemPriority.Normal, null);

            }

            GridView1.DataSource = Cache["BOOKS"];

            GridView1.DataBind();

    }

    注意:当XML文件发生改变后,其实缓存依赖和缓存项都被移除了,必须重新定义。

         按Ctrl+S组合键保存代码的修改。再按F5键运行程序,单击“获取数据”按钮,GridView就会显示XML文件的内容。

         程序运行正常后,在后台修改XML文件的内容,然后再单击“获取数据”按钮,则出现更改数据的提示,同时GridView显示了新的内容。图16-4和图16-5是数据更改前和更改后的效果对比。

        

    图16-4  初次获取的数据效果图                 图16-5  更改数据后的显示效果图

    16.4  数据库缓存依赖类:SqlCacheDependency类

    数据库缓存依赖主要解决的是当数据库的内容发生改变时,如何及时通知缓存,并更新缓存中的数据的问题。本节就介绍如何使用SQL Server 2005和.NET 2.0实现数据库的缓存依赖。

    16.4.1  功能说明

    SqlCacheDependency类的使用需要结合SQL Server 2005数据库,目前还没有Oracle数据库的缓存依赖。

    16.4.2  语法定义

    SqlCacheDependency类的使用语法如下:

    public class SqlCacheDependency : IDisposable

    其中继承了接口“IDisposable”,此接口主要用来定义释放分配的非托管资源的方法。继承此接口必须实现方法Dispose,用来实现资源的释放。

    SqlCacheDependency类主要的构造函数如下:

    public SqlCacheDependency(string database,string table)

    其中参数一代表要启用缓存的数据库,参数二表示缓存的表。在实际使用过程中,只需要指明缓存的数据库和表即可。

    16.4.3  方法和属性

    SqlCacheDependency类的方法和属性同CacheDependency类相同,主要有三个。

    —  HasChanged:判断数据库缓存依赖是否发生了变化。

    —  UtcLastModified:获取缓存依赖上次更改的时间。

    —  Dispose:释放缓存依赖所占用的资源。

    这三个成员的使用方法同CacheDependency类的成员相似,本节不再赘述。

    在下节要介绍的使用实例中,将不再使用代码的方式实现缓存依赖,而是使用“OutputCache”在.NET 2.0中提供的SqlCacheDependency参数实现数据库表的缓存。如果要使用编程的方式实现此功能,可参考CacheDependency类的实例。

    16.4.4  使用SqlCacheDependency类的操作流程

    要实现数据库缓存依赖,必须结合数据库的操作。在使用数据库缓存依赖前,必须进行5步操作。详细流程如图16-6所示。

    只有具备了上述条件,才可以正常地使用数据库缓存依赖。下一节将结合这5步操作演示如何实现数据库的缓存依赖。

    创建数据库链接

     

    图16-6  使用数据库缓存依赖的流程

    16.4.5  典型应用:获取数据库表最新数据的实例

    本例要实现的功能是当数据库的内容发生变化时,保存在缓存中的数据项被更新。具体演示的步骤如下所述。

         在数据库中创建数据库“testCache”。

         在数据库“testCache”中添加表“CacheTable”,其信息如表16-3所示。

    表16-3  CacheTable表的信息

       

    字段类型

       

    id

    int

    自增长数据标识

    Name

    nvarchar(20)

    书名

    bookPublish

    nvarchar(50)

    出版社

    Price

    decimal(6,2)

    书的价格

         为数据库启用缓存通知。打开“开始”|“所有程序”|“Microsoft Visual Studio 2005”|“Visual Studio Tools”|“Visual Studio 2005命名提示”菜单命令。

         输入如下命令,其中“-ed”和“-et”分别代表启用缓存依赖数据库和启用缓存数据表。

    aspnet_regsql.exe -S  CGJ-57F90CCA64C\SQLEXPRESS -E -ed -d  testCache -et -t  CacheTable

    注意如果使用的数据库验证方式是“SQL Server身份验证”,则需要使用如下的启动命令:

    aspnet_regsql.exe -S  CGJ-57F90CCA64C\SQLEXPRESS  -U <Username> -P <Password> -ed -d testCache -et -t CacheTable

       输入命令后,按回车键。如果执行成功,效果如图16-7所示。

         打开VS2005,新建一个网站,命名为“SqlCacheDependency”。

         按F5键运行程序,主要目的是生成一个默认的Web.Config文件。然后关闭运行的程序。

         在Web.config中配置数据库连接字符串,代码如下:

         <connectionStrings>

             <add name="TestCacheConnectionString" connectionString="Data Source=CGJ-57F90 CCA64C\sqlexpress;Initial Catalog=testCache;Integrated Security=True" providerName= "System.

    Data.SqlClient"/>

         </connectionStrings>

     

    图16-7  启用数据库缓存依赖成功的提示图

         在“system.web”节点内,添加数据库缓存依赖的配置,详细代码如下所示。注意配置中的“connectionStringName”属性,要与前面创建的数据库连接字符串的名字相对应。

    <caching>

         <sqlCacheDependency enabled = "true" pollTime = "1000" >

             <databases>

                  <add name="testCache"

                     connectionStringName="TestCacheConnectionString"

                     pollTime = "1000"      />

             </databases>

         </sqlCacheDependency>

    </caching>

         按Ctrl+S组合键保存配置文件的更改。

         打开默认生成的Default.aspx页,在设计视图中添加一个GridView控件,用来显示从数据库获取的数据。再添加一个Literal控件,主要用来显示时间,通过时间判断显示的是否是缓存中的数据。

         为GridView配置数据源。单击其任务列表,在“选择数据源”下拉框中,单击“新建数据源”命令,打开数据源的配置向导。

         在打开的数据源类型窗口中,选择“数据库”,单击“确定”按钮,出现选择连接字符串窗口,通过下拉列表选择刚刚创建的“TestCacheConnectionString”连接串。

         单击“下一步”按钮,出现“配置Select语句”对话框,在“列”列表框中选择“*”,表示选中所有列。

         单击“下一步”按钮出现测试查询对话框,然后单击“完成”按钮。

         按F7键切换到到代码视图,在“Page_Load”事件中添加如下代码(主要是显示当前的时间,用来判断是否是缓存数据):

    Literal1.Text = DateTime.Now.ToString();

         按Ctrl+S组合键保存当前页的设计,再按F5键运行程序。当刷新页面时,可以看到时间是不断变化的,这说明数据并没有来自缓存。

         打开Default.aspx页,在源代码视图的“<@page ”行下面,添加如下所示代码。其中使用的参数“SqlDependency”,就是用来添加数据库缓存依赖的。

     <%@ OutputCache Duration="3600" SqlDependency="testCache:CacheTable" VaryByParam="none" %>

    注意:Duration参数是表示缓存的过期时间,单位是毫秒。

         按F5键运行程序,此时再刷新页面,发现当前的时间已经不再变化,因为整个页的数据被缓存了起来。

         此时修改数据库的内容,然后刷新运行着的页面,可以发现,数据跟着发生了变化。这就是数据库缓存依赖的体现。当数据库内容更新时,不管缓存的时间有没有到,缓存的内容都会被更新。

    16.5  Session和Cache的区别

    以前实现数据的缓存有很多种方法,有客户端的Cookie,有服务器端的Session和Application。其中Cookie是保存在客户端的一组数据,主要用来保存用户名等个人信息。Session则保存对话信息。Application则是保存在整个应用程序范围内的信息,相当于全局变量。通常使用最频繁的是Session,那么Session和Cache又有什么区别呢?

    本节结合使用经验,详细介绍Session缓存和Cache缓存的区别。

    (1)最大的区别是Cache提供缓存依赖来更新数据,而Session只能依靠定义的缓存时间来判断缓存数据是否有效。

    (2)即使应用程序终止,只要Cache.Add方法中定义的缓存时间未过期,下次开启应用程序时,缓存的数据依然存在。而Session缓存只是存在于一次会话中,会话结束后,数据也就失效了。

    (3)Session容易丢失,导致数据的不确定性,而Cache不会出现这种情况。

    (4)由于Session是每次会话就被加载,所以不适宜存放大量信息,否则会导致服务器的性能降低。而Cache则主要用来保存大容量信息,如数据库中的多个表。

    (5)VS2005的测试版提供了将缓存保存在硬盘上的参数,但正式版中取消了这个功能,估计其在以后版本中会重新实现。而Session目前只能保存在内存中,对其性能有影响。

    为了提高Cache的有效利用率,建议对于不经常改动的数据使用Cache。

    16.6  小结

    本章主要介绍了如何使用System.Web.Caching命名空间下的类,主要包括以下三个:Cache, CacheDependency和SqlCacheDependency。Cache类主要用来创建缓存项,主要针对的是数据不经常改变,但又使用频繁的数据表或文件。另两个类是.NET 2.0新添加的缓存依赖服务。通过文件依赖或数据库依赖,可以实现缓存数据的及时更新。

    通过本章的学习,希望可以提高读者编写的网站的数据读取速度,节约带宽,为Web 2.0时代的到来打下坚实的基础。

  • 相关阅读:
    Tomcate配置单向双向SSL
    webkit和xcode
    bouncycastle创建csr
    JAVA 日期
    JS Date日期
    U盘安装RedHat linux 5.3
    Linux安装JRE tomcat配置java环境
    linux 下查看某个端口是否被占用
    Redhat下 Apache, php, mysql的默认安装路径
    VM 修改 virtualHW.version
  • 原文地址:https://www.cnblogs.com/systemxgl/p/1559828.html
Copyright © 2020-2023  润新知