回顾与说明
本文是 DotNET企业架构应用实践系列中的一篇文章,同时也是 一步一步教你使用AgileEAS.NET基础类库进行应用开发系统中的一篇文章,所以本文应该还有一个副标题“一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-在商口入库业务中使用缓存与缓存查询”,为什么会是这样呢?这个原因主要是我希望我在讲企业架的时候有结合具体的实例进行讲解,而不是泛泛而谈,而在AgileEAS.NET平台的案例开发中也正好涉及这样的内容。
在前面的WinForm篇前面我用了四篇文章实例演示了一个基于AgileEAS.NET实现两个应用模块:商品字典的管理和商品入库模块,这两个模块是一个典型的进销存系统中的两个经典而必须存在的两个模块。
在前面 DotNET企业架构应用实践系统中,我用了两篇文章简单的和大家了解了性能优化的基础知道与性能优化中的缓存技术,并且在前面 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-复杂业务的实现(商品入库)-附案例操作视频一文及其附加的案例,我们可以知道这么一个应用场景:商品入库模块中,系统根据操作员输入产品的拼音检索商品字典,并在此基础之上输入产品价格与入量数量以完成产品入库,我们从案例可以知道,每次检索商品字典都要访问数据库,同时我们知道,在进销存系统中,商品字典这样的基础数据的变更不是很频繁,那么我们是否根据这样的场景使用缓存与缓存查询进行性能优化呢?答案当然是肯定的,本文的目的就在于此,结合案例讲解一个典型的场景。
本文的内容
本文的内容是在 DotNET企业架构应用实践-系统架构与性能-缓存技术与ORM中的缓存
查询技术与 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-复杂业务的实现(商品入库)-附案例操作视频两篇文章基础之上进行的,主要完成以下三个目标:
1.结合缓存技术一文,在今天的本例中,实现了个极其简单的ICacheManager,其提供了基于Key-Value的对象缓存,只提供了最基本的缓存处理,不提供缓存技术中的同步写回机制,也不提供缓存技术中的命中也缓存淘汰机制,关于这些内容有兴趣的朋友可以找我私下交流。
2.结合案例我详细的介绍AgileEAS.NET平台中的ORM缓存查询的详细使用方法。
3.基于应用案例讨论缓存的典型应用场景,进而了解性能优化的一些原则和基本发点。
ICacheManager的最简单实现
我们来动手实现一个最简单的ICacheManager,在Product解决方案之中增加了一个Product.Cache项目,增加ICacheManager接口和一个简单的实现CacheManager,代码如下:
1
public
class
CacheManager : ICacheManager
2 {
3 Dictionary < string , object > objectList = new Dictionary < string , object > ();
4
5 #region ICacheManager 成员
6
7 public void Set( string key, object value)
8 {
9 this .objectList.Add(key, value);
10 }
11
12
13 public object Get( string key)
14 {
15 if ( this .Exist(key))
16 return this .objectList[key];
17 else
18 return null ;
19 }
20
21 public bool Exist( string key)
22 {
23 return this .objectList.ContainsKey(key);
24 }
25
26 public void Remove( string key)
27 {
28 if ( this .Exist(key))
29 this .objectList.Remove(key);
30 }
31
32 public void Clear()
33 {
34 this .Clear();
35 }
36
37 #endregion
38 }
2 {
3 Dictionary < string , object > objectList = new Dictionary < string , object > ();
4
5 #region ICacheManager 成员
6
7 public void Set( string key, object value)
8 {
9 this .objectList.Add(key, value);
10 }
11
12
13 public object Get( string key)
14 {
15 if ( this .Exist(key))
16 return this .objectList[key];
17 else
18 return null ;
19 }
20
21 public bool Exist( string key)
22 {
23 return this .objectList.ContainsKey(key);
24 }
25
26 public void Remove( string key)
27 {
28 if ( this .Exist(key))
29 this .objectList.Remove(key);
30 }
31
32 public void Clear()
33 {
34 this .Clear();
35 }
36
37 #endregion
38 }
这个ICacheManager实现只提供最简单的Key-Value,提供最基本的缓存服务,缓存对象与取缓存,而不提供命中、淘汰、同步与写回技术。
案例中的缓存查询场景
本文的缓存查询优化场景是这样的,前面案例中在商品入库的过程中,系统根据操作员输入的拼音简码检索数据库,在产品字典输入选择界面中当检查输入的条件发生变动时就去访问数据库,这样呢会频繁的访问数据库,如果有大量的客户短使用数据库,那么因为频繁的数据库查询会严重的影响数据库服务器的性能,而我们今天改造这个案例达到什么目的呢,第一次使用系统时,客户段会把商品字典记录一次性取回来,缓存在缓存系统之中,而在其后的拼音码检索中,不再访问数据库,而是直接使用缓存中的字典记录执行缓存查询,为了这个场景的方便展示我做了一个简单的视频,我把视频简单的分为不使用缓存系统与使用缓存系统,并且在演示的过程中打开SQLServer的事件探查器进行对比:
从视频中我们可以看了使用缓存与缓存查询性能带来的提省,极大的减少了数据库服务器的SQL查询请求。
关于实现代码
在视频中,我也简单的给大家看了一个程序代码,在这次的代码之中,增加了一个Product.Cache,用于定义和实现了一个简单的缓存系统,在Product.UI中增加了一个关于缓存上下文的辅助类CacheContext,其他最主要是提供了商品字典的缓存处理,代码如下:
1
static
class
CacheContext
2 {
3 ///
4 /// Orm访问器。
5 ///
6 public static ICacheManager CacheManager
7 {
8 get
9 {
10 return ContextHelper.GetContext().Container.GetComponentInstance( " CacheManager " ) as ICacheManager;
11 }
12 }
13
14 ///
15 /// 处理产品字典缓存。
16 ///
17 ///
18 public static IProductList GetProductListCache()
19 {
20 string key = " ProductList " ;
21 if ( ! CacheManager.Exist(key))
22 {
23 IProductList table = DALHelper.DALManager.CreateProductList();
24 table.Query();
25 CacheManager.Set(key, table);
26 }
27
28 return CacheManager.Get(key) as IProductList;
29 }
30 }
2 {
3 ///
4 /// Orm访问器。
5 ///
6 public static ICacheManager CacheManager
7 {
8 get
9 {
10 return ContextHelper.GetContext().Container.GetComponentInstance( " CacheManager " ) as ICacheManager;
11 }
12 }
13
14 ///
15 /// 处理产品字典缓存。
16 ///
17 ///
18 public static IProductList GetProductListCache()
19 {
20 string key = " ProductList " ;
21 if ( ! CacheManager.Exist(key))
22 {
23 IProductList table = DALHelper.DALManager.CreateProductList();
24 table.Query();
25 CacheManager.Set(key, table);
26 }
27
28 return CacheManager.Get(key) as IProductList;
29 }
30 }
在这里面,使用了IOC方面的知识,在此我就不详细的再给大家了解,大家可以参考前面的文章了解和学习配置,在使用ORM的缓存查询时,需要在系统配置文件的IOC配置信息中配置缓存查询访问器的信息:
配置文件
1
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
2 < configuration >
3 < configSections >
4 < section name = " EAS.Objects " type = " EAS.Objects.ConfigHandler,EAS.IOCContainer " />
5 configSections >
6 < EAS.Objects >
7 < object name = " DataConnection " assembly = " EAS.Data " type = " EAS.Data.Access.SqlClientConnection " LifestyleType = " Thread " >
8 < property name = " ConnectionString " type = " string " value = " Data Source=vm2003;Initial Catalog=eas;User ID=sa " />
9 object >
10 < object name = " OrmAccessor " assembly = " EAS.Data " type = " EAS.Data.ORM.OrmAccessor " LifestyleType = " Thread " >
11 < property name = " DbConnection " type = " object " value = " DataConnection " />
12 object >
13 < object name = " DataAccessor " assembly = " EAS.Data " type = " EAS.Data.Access.SqlClientAccessor " LifestyleType = " Thread " >
14 < property name = " Connection " type = " object " value = " DataConnection " />
15 object >
16
17
20 < object name = " CacheAccessor " assembly = " EAS.Data " type = " EAS.Data.ORM.CacheAccessor " LifestyleType = " Thread " />
21
22
25 < object name = " CacheManager " type = " Product.Cache.CacheManager,Product.Cache " LifestyleType = " Singleton " />
26
27 < object name = " Product.DAL " assembly = " Product.DAL.SQLServer " type = " Product.DAL.SQLServer.DALManager " LifestyleType = " Singleton " />
28 EAS.Objects >
29 configuration >
2 < configuration >
3 < configSections >
4 < section name = " EAS.Objects " type = " EAS.Objects.ConfigHandler,EAS.IOCContainer " />
5 configSections >
6 < EAS.Objects >
7 < object name = " DataConnection " assembly = " EAS.Data " type = " EAS.Data.Access.SqlClientConnection " LifestyleType = " Thread " >
8 < property name = " ConnectionString " type = " string " value = " Data Source=vm2003;Initial Catalog=eas;User ID=sa " />
9 object >
10 < object name = " OrmAccessor " assembly = " EAS.Data " type = " EAS.Data.ORM.OrmAccessor " LifestyleType = " Thread " >
11 < property name = " DbConnection " type = " object " value = " DataConnection " />
12 object >
13 < object name = " DataAccessor " assembly = " EAS.Data " type = " EAS.Data.Access.SqlClientAccessor " LifestyleType = " Thread " >
14 < property name = " Connection " type = " object " value = " DataConnection " />
15 object >
16
17
20 < object name = " CacheAccessor " assembly = " EAS.Data " type = " EAS.Data.ORM.CacheAccessor " LifestyleType = " Thread " />
21
22
25 < object name = " CacheManager " type = " Product.Cache.CacheManager,Product.Cache " LifestyleType = " Singleton " />
26
27 < object name = " Product.DAL " assembly = " Product.DAL.SQLServer " type = " Product.DAL.SQLServer.DALManager " LifestyleType = " Singleton " />
28 EAS.Objects >
29 configuration >
在现阶段的AgileEAS.NET平台中,内置了一个缓存查询访问器实现EAS.Data.ORM.CacheAccessor,大家可以在应用中直接使用上面的配置,当然了,不安排除在后面提供其他缓存查询访问器,敬请大家期待。
本文今天就到这儿,对这东西感兴趣的朋友呢,可以下载了完整代码之后自己看看,有问题请及时的和我联系。
有关本例所涉及的数据表结构请参考 基于AgileEAS.NET平台基础类库进行应用开发-总体说明及数据定义一文,有关数据对象模型定义文件、文档、DDL脚本请下载: http://files.cnblogs.com/eastjade/demo.db.doc.sql.rar,本例完整代码下载: Product.Demo.rar。
链接
一步一步教你使用AgileEAS.NET基础类库进行应用开发-系列目录
AgileEAS.NET平台开发指南-系列目录
AgileEAS.NET应用开发平台介绍-文章索引
AgileEAS.NET平台应用开发教程-案例计划
AgileEAS.NET官方网站
敏捷软件工程实验室
QQ群:116773358