分析PetShop

本文分析了PetShop项目的架构,包括BLL、ConfigTool、Utility等组件的功能。重点介绍了DALFactory中的Product类实现,以及通过配置文件灵活切换不同数据库的支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

以前就把petShop这个实例DOWN下来了,这是微软主要针对SUN公司的petStore而发布的一款源代码,好了,不多说.现在来看看此源码的主要内容.
它由多个项目组合而成,大致分为以下几层:
BLL。专门处理前台页面的所需功能.
ConfigTool和Utility主要负处理连库字符加密及其它工作.
DALFactory负责创建对象
就看Product这个类吧

 1 ExpandedBlockStart.gif ContractedBlock.gif public   static  PetShop.IDAL.IProduct Create()  dot.gif {
 2InBlock.gif            
 3ExpandedSubBlockStart.gifContractedSubBlock.gif            /**//// Look up the DAL implementation we should be using
 4InBlock.gif            string path = System.Configuration.ConfigurationSettings.AppSettings["WebDAL"];
 5InBlock.gif            string className = path + ".Product";
 6InBlock.gif            //PetShop.SQLServerDAL.Product
 7InBlock.gif
 8InBlock.gif            // Using the evidence given in the config file load the appropriate assembly and class
 9InBlock.gif            return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
10ExpandedBlockEnd.gif        }

path值为PetShop.SQLServerDAL从web.config文件读取
主要负责创建PetShop.SQLServerDAL.Product这个类的实例;
 (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
到了这里就可以看IDAL.IProduct这个接口

 1 ExpandedBlockStart.gif ContractedBlock.gif public   interface  IProduct dot.gif {
 2InBlock.gif    
 3ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 4InBlock.gif        /// Method to search products by category name
 5InBlock.gif        /// </summary>
 6InBlock.gif        /// <param name="category">Name of the category to search by</param>
 7ExpandedSubBlockEnd.gif        /// <returns>Interface to an arraylist of search results</returns>

 8InBlock.gif        IList GetProductsByCategory(string category);
 9InBlock.gif
10InBlock.gif
11ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
12InBlock.gif        /// Method to search products by a set of keyword
13InBlock.gif        /// </summary>
14InBlock.gif        /// <param name="keywords">An array of keywords to search by</param>
15ExpandedSubBlockEnd.gif        /// <returns>Interface to an arraylist of search results</returns>

16InBlock.gif        IList GetProductsBySearch(string[] keywords);
17ExpandedBlockEnd.gif    }

声明了两个方法.接口有了。当然要找实现接口的这个类.个人理解接口与类之间只是定义一种规则.接口内声明的方法,实现这个接口的类必须去实现接口里面的方法.假如在大型项目中有多人开发.可以有专门的人写好接口里面的方法.然后另外的人去写实现接口的类.可以做到分工明确.开发效率也会高点。好了.找到了实现接口的这个类.

 1 ExpandedBlockStart.gif ContractedBlock.gif public   class  Product : IProduct dot.gif {
 2InBlock.gif
 3InBlock.gif        //Static constants
 4InBlock.gif        private const string SQL_SELECT_PRODUCTS = "SELECT ProductId, Name, Descn FROM Product";
 5InBlock.gif        private const string SQL_SELECT_PRODUCTS_BY_CATEGORY = "SELECT ProductId, Name FROM Product WHERE Category = @Category";
 6InBlock.gif        private const string SQL_SELECT_PRODUCTS_BY_SEARCH1 = "SELECT ProductId, Name, Descn FROM Product WHERE ((";
 7InBlock.gif        private const string SQL_SELECT_PRODUCTS_BY_SEARCH2 = "LOWER(Name) LIKE '%' + {0} + '%' OR LOWER(Category) LIKE '%' + {0} + '%'";
 8InBlock.gif        private const string SQL_SELECT_PRODUCTS_BY_SEARCH3 = ") OR (";
 9InBlock.gif        private const string SQL_SELECT_PRODUCTS_BY_SEARCH4 = "))";
10InBlock.gif        private const string PARM_CATEGORY = "@Category";
11InBlock.gif        private const string PARM_KEYWORD = "@Keyword";
12InBlock.gif
13ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
14InBlock.gif        /// Query for products by category
15InBlock.gif        /// </summary>
16InBlock.gif        /// <param name="category">category name</param>
17ExpandedSubBlockEnd.gif        /// <returns></returns>

18ExpandedSubBlockStart.gifContractedSubBlock.gif        public IList GetProductsByCategory(string category) dot.gif{
19InBlock.gif
20InBlock.gif            IList productsByCategory = new ArrayList();
21InBlock.gif
22InBlock.gif            SqlParameter parm = new SqlParameter(PARM_CATEGORY, SqlDbType.Char, 10);
23InBlock.gif            parm.Value = category;
24InBlock.gif            
25InBlock.gif            //Execute a query to read the products
26ExpandedSubBlockStart.gifContractedSubBlock.gif            using (SqlDataReader rdr = SQLHelper.ExecuteReader(SQLHelper.CONN_STRING_NON_DTC, CommandType.Text, SQL_SELECT_PRODUCTS_BY_CATEGORY, parm)) dot.gif{
27ExpandedSubBlockStart.gifContractedSubBlock.gif                while (rdr.Read())dot.gif{
28InBlock.gif                    ProductInfo product = new ProductInfo(rdr.GetString(0), rdr.GetString(1), null);
29InBlock.gif                    productsByCategory.Add(product);
30ExpandedSubBlockEnd.gif                }

31ExpandedSubBlockEnd.gif            }

32InBlock.gif
33InBlock.gif            return productsByCategory;
34ExpandedSubBlockEnd.gif        }

35InBlock.gif
36ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
37InBlock.gif        /// Query for products by keywords. 
38InBlock.gif        /// The results will include any product where the keyword appears in the category name or product name
39InBlock.gif        /// </summary>
40InBlock.gif        /// <param name="keywords">string array of keywords</param>
41ExpandedSubBlockEnd.gif        /// <returns></returns>

42ExpandedSubBlockStart.gifContractedSubBlock.gif        public IList GetProductsBySearch(string[] keywords) dot.gif{
43InBlock.gif            
44InBlock.gif            IList productsBySearch = new ArrayList();
45InBlock.gif
46InBlock.gif            int numKeywords = keywords.Length;
47InBlock.gif
48InBlock.gif            //Create a new query string
49InBlock.gif            StringBuilder sql = new StringBuilder(SQL_SELECT_PRODUCTS_BY_SEARCH1);
50InBlock.gif
51InBlock.gif            //Add each keyword to the query
52ExpandedSubBlockStart.gifContractedSubBlock.gif            for (int i = 0; i < numKeywords; i++dot.gif{
53InBlock.gif                sql.Append(string.Format(SQL_SELECT_PRODUCTS_BY_SEARCH2, PARM_KEYWORD + i));
54InBlock.gif                sql.Append(i + 1 < numKeywords ? SQL_SELECT_PRODUCTS_BY_SEARCH3 : SQL_SELECT_PRODUCTS_BY_SEARCH4);
55ExpandedSubBlockEnd.gif            }

56InBlock.gif
57InBlock.gif            string sqlProductsBySearch = sql.ToString();
58InBlock.gif            SqlParameter[] parms = SQLHelper.GetCachedParameters(sqlProductsBySearch);
59InBlock.gif            
60InBlock.gif            // If the parameters are null build a new set
61ExpandedSubBlockStart.gifContractedSubBlock.gif            if (parms == nulldot.gif{
62InBlock.gif                parms = new SqlParameter[numKeywords];
63InBlock.gif
64InBlock.gif                for (int i = 0; i < numKeywords; i++)
65InBlock.gif                    parms[i] = new SqlParameter(PARM_KEYWORD + i, SqlDbType.VarChar, 80);
66InBlock.gif
67InBlock.gif                SQLHelper.CacheParameters(sqlProductsBySearch, parms);
68ExpandedSubBlockEnd.gif            }

69InBlock.gif
70InBlock.gif            // Bind the new parameters
71InBlock.gif            for (int i = 0; i < numKeywords; i++)
72InBlock.gif                parms[i].Value = keywords[i];
73InBlock.gif            
74InBlock.gif            //Finally execute the query
75ExpandedSubBlockStart.gifContractedSubBlock.gif            using (SqlDataReader rdr = SQLHelper.ExecuteReader(SQLHelper.CONN_STRING_NON_DTC, CommandType.Text, sqlProductsBySearch, parms)) dot.gif{
76ExpandedSubBlockStart.gifContractedSubBlock.gif                while (rdr.Read())dot.gif{
77InBlock.gif                    ProductInfo product = new ProductInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));
78InBlock.gif                    productsBySearch.Add(product);
79ExpandedSubBlockEnd.gif                }

80ExpandedSubBlockEnd.gif            }

81InBlock.gif
82InBlock.gif            return productsBySearch;
83ExpandedSubBlockEnd.gif        }

84ExpandedBlockEnd.gif    }

说实话,当初第一眼看里面的代码觉得眼花头昏,咋会这么乱呢.仔细一看.嗯.好处还是蛮多多的.仔细一分析,然后再对比以前自己写的东西.禁不住老脸都红了一下.呵呵

1 None.gif private   const   string  SQL_SELECT_PRODUCTS  =   " SELECT ProductId, Name, Descn FROM Product " ;
2 None.gif         private   const   string  SQL_SELECT_PRODUCTS_BY_CATEGORY  =   " SELECT ProductId, Name FROM Product WHERE Category = @Category " ;
3 None.gif         private   const   string  SQL_SELECT_PRODUCTS_BY_SEARCH1  =   " SELECT ProductId, Name, Descn FROM Product WHERE (( " ;
4 None.gif         private   const   string  SQL_SELECT_PRODUCTS_BY_SEARCH2  =   " LOWER(Name) LIKE '%' + {0} + '%' OR LOWER(Category) LIKE '%' + {0} + '%' " ;
5 None.gif         private   const   string  SQL_SELECT_PRODUCTS_BY_SEARCH3  =   " ) OR ( " ;
6 None.gif         private   const   string  SQL_SELECT_PRODUCTS_BY_SEARCH4  =   " )) " ;
7 None.gif         private   const   string  PARM_CATEGORY  =   " @Category " ;
8 None.gif         private   const   string  PARM_KEYWORD  =   " @Keyword " ;

上面这一段声明了对数据库操作所需的SQL语句.第一次编译后,下次直接调用.然后这个类实现了IDAL.IProduct这个类的方法.
Model这层主要是实现了实体层。
可能是语文小学的时候没学好的.表达得连我自己都觉得乱了呢.
web.config里面的

1 None.gif      < add key = " SQLConnString1 "  value = " AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAiwM8Jc97B06fnNOg4m/cVAQAAAACAAAAAAADZgAAqAAAABAAAAC3dV/gT+/P3E69y1tuF6KtAAAAAASAAACgAAAAEAAAAJD/aFezVi9pgy9VPlwlXt1IAAAAQ/n2oxIiXxjnkg1gke77sbuNn++S/FOG0qiIxZcc1ft7U6xBrQIQEySfprnW/Xr2zjtwLubA4nLRh3C5/4r5VJ1f2Ri9jtpeFAAAAAK2kmoE+wHWuy2SV7AFaUdc4k1T "   />
2 None.gif     < add key = " SQLConnString2 "  value = " AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAiwM8Jc97B06fnNOg4m/cVAQAAAACAAAAAAADZgAAqAAAABAAAADBe+0s4RDV1kFfEajzSk6yAAAAAASAAACgAAAAEAAAAO5mVnnO8ixwTntVMZz1OyhIAAAAy+dStcznTM4kq705oDiKVp1TkUw4mozYbuvp+BNXr4bN3rPzVbvbjgeYNE9RHa69rxUppvtb/YDRbj1oV2hsu5tX9dtIHik/FAAAAOpCMs+ujLIaxSalUd+bwkpNNBe6 "   />
3 None.gif     < add key = " SQLConnString3 "  value = " AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAiwM8Jc97B06fnNOg4m/cVAQAAAACAAAAAAADZgAAqAAAABAAAACnoyDL679IUCTKmdAuovLtAAAAAASAAACgAAAAEAAAAMuza8eq1dAanascPjy/tr5YAAAAcJK4ehxVfY931JX9iG3TkPCYDqbKbUZ0Pp/OFNqJBNr313ije2WrKdqfPXWcERENx57wQ/IjSAnljOUzNdWAW2HPVERq6eMsbsz+l0P8xFJEMjOTEpNXbBQAAAB7TXfLAKGq+4CZ5ISo8Yngg6xczw== "   />
4 None.gif     < add key = " OraConnString1 "  value = ""   />
5 None.gif     < add key = " OraConnString2 "  value = ""   />
6 None.gif     < add key = " OraConnString3 "  value = ""   />
7 None.gif     < add key = " WebDAL "  value = " PetShop.SQLServerDAL "   />
8 None.gif     < add key = " OrdersDAL "  value = " PetShop.SQLServerDAL "   />
9 None.gif     < add key = " Event Log Source "  value = " .NET Pet Shop "   />

主要是存放连库字符串.和Factory所需的信息.刚刚不是说了下面这一段的么
 string path = System.Configuration.ConfigurationSettings.AppSettings["WebDAL"];
 5InBlock.gif            string className = path + ".Product";
 6InBlock.gif            //PetShop.SQLServerDAL.Product
 7InBlock.gif
 8InBlock.gif            // Using the evidence given in the config file load the appropriate assembly and class
 9InBlock.gif            return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
只要把WebDAL改成OracleDAL就可以实现针对ORACLE数据库的操作.实现了多数据.娘的.真好.为啥我以前就没有想到呢.所以说书看得多.不如分析实例.边想边写.
还有差不多它的返回结果都IList类型.主要是用DataReader执行后的结果返回个另外的对象.这样做的话可以节省资源,小巧.不像自己以前动不动返回一个DataSet,要是应用到大项目中.不把服务器卡死才怪呢.

posted on 2006-10-22 14:03 我就是烟鬼 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/paleyyang/archive/2006/10/22/536377.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值