57在分层架构中缓存数据Word文档格式.docx

上传人:b****5 文档编号:18695649 上传时间:2022-12-31 格式:DOCX 页数:18 大小:77.12KB
下载 相关 举报
57在分层架构中缓存数据Word文档格式.docx_第1页
第1页 / 共18页
57在分层架构中缓存数据Word文档格式.docx_第2页
第2页 / 共18页
57在分层架构中缓存数据Word文档格式.docx_第3页
第3页 / 共18页
57在分层架构中缓存数据Word文档格式.docx_第4页
第4页 / 共18页
57在分层架构中缓存数据Word文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

57在分层架构中缓存数据Word文档格式.docx

《57在分层架构中缓存数据Word文档格式.docx》由会员分享,可在线阅读,更多相关《57在分层架构中缓存数据Word文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

57在分层架构中缓存数据Word文档格式.docx

添加名为CL的文件夹和名为ProductsCL.cs的类

  跟BLL里的ProductsBLL类一样,ProductsCL类应该包含相同的数据访问和修改方法。

不过在本文,我们只创建GetProducts()方法(在第3步)和GetProductsByCategoryID(categoryID)方法(在第4步)。

你可以在空闲的时候对ProductsCL类进行完善,并创建相应的CategoriesCL,EmployeesCL和SuppliersCL类

第二步:

对DataCache进行读和写

  ObjectDataSource的缓存属性使用ASP.NETdatacache来存储从BLL获取的数据。

要访问datacache,可以从ASP.NET页面的code-behindclasses类或体系结构层(architecture)的类来访问。

要通过ASP.NET页面的code-behindclasses类对datacache进行读写,可使用如下模式:

?

1

2

//Readfromthecache(读)

objectvalue=Cache["

key"

];

3

4

5

//Addanewitemtothecache(写)

Cache["

]=value;

Cache.Insert(key,value);

Cache.Insert(key,value,CacheDependency);

Cache.Insert(key,value,CacheDependency,DateTime,TimeSpan);

  Cacheclass类的Insert方法可以有很多的重载。

]=value和Cache.Insert(key,value)是相同的,都是向cache添加一个条目(item),不过没有指定expiry(可以理解为缓存持续时间)。

更具代表性的是,在我们向cache添加条目的时候指定一个expiry,它要么是dependency(从属体),要么是time-basedexpiry,又或者两者兼而有之,比如上面的最后2个表达式。

  如果所需的数据存储在内存的话,首先调用缓存层的方法返回数据。

如果不在内存的话就调用BLL里相应的方法。

数据先缓存再返回。

就像下面的流程表解析的一样:

图3:

如果数据存在于内存的话就调用缓存层的方法。

上图的流程可用如下的模式:

6

7

Typeinstance=Cache["

]asType;

if(instance==null)

{

 

instance=BllMethodToGetInstance();

Cache.Insert(key,instance,...);

}

returninstance;

  其中,Type是缓存在内存中的数据的类型——具体到本文,也就是Northwind.ProductsDataTable;

此外,key用于唯一地标识缓存的每一个条目。

如果指定了key值的那个条目不在内存中,那么instance就为null,然后用BLL类的某恰当的方法来检索数据,将获得的数据缓存到内存。

将instance返回后,它将包含一个对数据的引用(referencetothedata),数据要么来自内存,要么是BLL类的返回数据。

  当访问内存时,请务必使用上述模式。

下面的这个模式,咋一看好像和上面的模式一模一样,但是有一个细微的区别,它存在一个racecondition(可以理解为不易察觉的隐式缺陷)。

racecondition很难调试,因为它只是偶尔发生,而且再次发生的可能性也小。

如下:

if(Cache["

]==null)

Cache.Insert(key,BllMethodToGetInstance(),...);

returnCache["

  再一个就是,上述模式不是在局部变量里存储缓存条目的引用,而是在条件语句里直接访问数据,在return语句里直接返回数据。

设想这种情况,开始运行代码时Cache["

]是non-null的,但在运行return语句前,系统将其从内存里清除掉,那么代码就会返回一个null值,而不是我们期望的某种类型的对象。

  注意:

如果仅仅是对datacache进行读或写访问,你没有必要进行同步访问(synchronizethreadaccess);

当然,如果你需要对内存里的数据进行多重操作(multipleoperations),你还是应该实施锁定(lock),或其它的机制。

如果要从datacache里清除某个条目,可以用Remove方法,比如:

Cache.Remove(key);

第三步:

从ProductsCL类返回产品信息

  在本文,我们要在ProductsCL类里用2个方法来返回产品信息:

GetProducts()和GetProductsByCategoryID(categoryID).和业务逻辑层里的ProductsBL类相似,缓存层里的GetProducts()方法返回一个Northwind.ProductsDataTable对象,来获取所有产品的信息;

而GetProductsByCategoryID(categoryID)方法返回的是某个特定类别的所有产品。

如下的代码是ProductsCL类里的部分方法:

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

[System.ComponentModel.DataObject]

publicclassProductsCL

privateProductsBLL_productsAPI=null;

protectedProductsBLLAPI

get

if(_productsAPI==null)

_productsAPI=newProductsBLL();

return_productsAPI;

[System.ComponentModel.DataObjectMethodAttribute(DataObjectMethodType.Select,true)]

publicNorthwind.ProductsDataTableGetProducts()

conststringrawKey="

Products"

;

//Seeiftheitemisinthecache

Northwind.ProductsDataTableproducts=_

GetCacheItem(rawKey)asNorthwind.ProductsDataTable;

if(products==null)

//Itemnotfoundincache-retrieveitandinsertitintothecache

products=API.GetProducts();

AddCacheItem(rawKey,products);

returnproducts;

[System.ComponentModel.DataObjectMethodAttribute(DataObjectMethodType.Select,false)]

publicNorthwind.ProductsDataTableGetProductsByCategoryID(intcategoryID)

if(categoryID<

0)

returnGetProducts();

else

stringrawKey=string.Concat("

ProductsByCategory-"

categoryID);

products=API.GetProductsByCategoryID(categoryID);

  首先,注意运用到类(class)和方法(methods)上的属性DataObject和DataObjectMethodAttribute;

这些属性服务于ObjectDataSource的设置向导,指出那些类和方法应该出现在向导的设置步骤里。

因为ObjectDataSource控件要在表现层访问这些类和方法,所以我添加了这些属性,方便向导设置。

关于这些属性及其作用,请参阅本教程第2章《创建一个业务逻辑层》。

  在GetProducts()和GetProductsByCategoryID(categoryID)方法里,GetCacheItem(key)返回的数据赋值给一个局部变量。

GetCacheItem(key)方法根据指定的key值在内存查找对应的缓存条目;

如果没找到,则用ProductsBLL类里相应的方法来检索数据,并用AddCacheItem(key,value)方法将获取的数据缓存到内存。

GetCacheItem(key)和AddCacheItem(key,value)方法分别对datacache进行读、写操作。

GetCacheItem(key)相对简单,它根据传入的key值,从Cache类返回数据,如下:

privateobjectGetCacheItem(stringrawKey)

returnHttpRuntime.Cache[GetCacheKey(rawKey)];

privatereadonlystring[]MasterCacheKeyArray={"

ProductsCache"

};

privatestringGetCacheKey(stringcacheKey)

returnstring.Concat(MasterCacheKeyArray[0],"

-"

cacheKey);

  GetCacheItem(key)并没有直接使用我们提供的key值,而是调用GetCacheKey(key)方法,因为该方法根据“ProductsCache-”返回key;

在上述代码中,MasterCacheKeyArray用于存储字符串“ProductsCache”。

当然,AddCacheItem(key,value)方法也会用到MasterCacheKeyArray,我们稍后会看到。

  在ASP.NET页面后台代码类(code-behindclass),我们可以使用Page类的Cache属性来访问datacache,就像我们在第2步里的表达式:

]=value一样;

而在体系结构的类(注:

具体到本文,就是缓存层类(ProductsCL),我们可以通过2种方式来访问:

HttpRuntime.Cache或HttpContext.Current.Cache;

在PeterJohnson的博客里有一篇文章《HttpRuntime.Cachevs.HttpContext.Current.Cache》(

注意:

如果你是使用的类库工程(ClassLibraryprojects),一定要记得引用System.Web才能使用HttpRuntime和HttpContext类。

  如果没有在内存找到数据,ProductsCL类将从业务逻辑层BLL获取数据,并使用AddCacheItem(key,value)对数据进行缓存,可以用下面的代码向内存添加缓存数据,其缓存时间为60秒:

constdoubleCacheDuration=60.0;

privatevoidAddCacheItem(stringrawKey,objectvalue)

HttpRuntime.Cache.Insert(GetCacheKey(rawKey),value,null,

DateTime.Now.AddSeconds(CacheDuration),Caching.Cache.NoSlidingExpiration);

  其中,DateTime.Now.AddSeconds(CacheDuration)指定了缓存时间—60秒;

而System.Web.Caching.Cache.NoSlidingExpiration指明了不存在可变缓存时间(noslidingexpiration).虽然Insert()方法可以包含绝对时间和可变时间(absoluteandslidingexpiry)2种定义缓存时间的输入参数,但是你只能指定其中一个,如果你同时指定绝对时间和可变时间2个参数的话,Insert()方法会抛出一ArgumentException异常。

直接执行AddCacheItem(key,value)方法会有一些弊端,我们将在第4步解释并修正。

第4步:

当数据被修改时使缓存失效

  除了数据检索方法外,缓存层还应该包含插入、更新、删除数据的方法。

缓存层的数据修改方法并不是修改缓存的数据,而是调用业务逻辑层的相应方法,然后使缓存数据失效。

就像前面章节探讨的那样,当激活ObjectDataSource的缓存属性时,便可调用它的Insert,Update或Delete方法。

下面的UpdateProduct方法,说明了如何在缓存层CL执行数据修改方法:

[System.ComponentModel.DataObjectMethodAttribute(DataObjectMethodType.Update,false)]

publicboolUpdateProduct(stringproductName,decimal?

unitPrice,intproductID)

boolresult=API.UpdateProduct(productName,unitPrice,productID);

//TODO:

Invalidatethecache

returnresult;

  在业务逻辑层的方法返回数据以前,我们需要将缓存的数据失效。

不过,这并非易事,无论ProductsCLclass'

sGetProducts()还是GetProductsByCategoryID(categoryID)都会向内存添加条目,并且GetProductsByCategoryID(categoryID)方法会为每种类别添加几个条目(因为每种类别有几种甚至更多的产品)。

  要使缓存数据失效,我们需要将ProductsCL类添加的所有条目删除。

为此,在AddCacheItem(key,value)方法里,当添加条目时为其指定一个缓存从属体(cachedependency)。

一般来说,缓存从属体可以是内存里的另一个条目;

文件系统里的一个文件;

又或者是MicrosoftSQLServerdatabase数据库里的数据。

当从属体发生改变,或者从内存里移除时,其对应的缓存条目会自动的从内存删除。

在本教程,当ProductsCL类向内存添加条目时,我们创建一个额外的条目作为其从属体。

由此,要删除缓存条目,仅仅移除这些从属体即可。

  我们来更改AddCacheItem(key,value)方法,当用该方法向内存添加缓存数据时,使每个条目与一个从属体(cachedependency)对应起来。

System.Web.Caching.CacheDataCache=HttpRuntime.Cache;

//MakesureMasterCacheKeyArray[0]isinthecache-ifnot,addit

if(DataCache[MasterCacheKeyArray[0]]==null)

DataCache[MasterCacheKeyArray[0]]=DateTime.Now;

//AddaCacheDependency

System.Web.Caching.CacheDependencydependency=

newCacheDependency(null,MasterCacheKeyArray);

DataCache.Insert(GetCacheKey(rawKey),value,dependency,

DateTime.Now.AddSeconds(CacheDuration),

System.Web.Caching.Cache.NoSlidingExpiration);

  MasterCacheKeyArray是一个字符串数组,用来存储“ProductsCache”.首先检查MasterCacheKeyArray,如果其为null,用当前date和time对其赋值。

然后,创建一个从属体。

CacheDependency类的构造器(constructor)可以有很多重载(overloads),本文使用的重载接受2个字符串数组作为输入参数。

第一个参数指定文件作为从属体,但本文我们不大算用文件来做从属体,所以我们将第一个输入参数设为null;

第二个参数指定cachekeys作为从属体,本文我们指定为MasterCacheKeyArray。

然后将该CacheDependency传递给Insert方法。

对AddCacheItem(key,value)方法做了上述修改后,要使缓存失效,很简单,将从属体移除即可:

//Invalidatethecache

InvalidateCache();

publicvoidInvalidateCache()

//Removethecachedependency

HttpRuntime.Cache.Remove(MasterCacheKeyArray[0]);

第五步:

在表现层调用缓存层

  保存对ProductsCL类的修改,打开Caching文件夹里的FromTheArchitecture.aspx页面,并添加一个GridView控件。

从GridView控件的智能标签里创建一个新的ObjectDataSource,在向导的第一步,从下拉列表里选择ProductsCL,如下图:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1