【【【问个问题】】】
[CS:S] 【【【问个问题】】】
当前离线
81083 帖子
15 精华
0 点 子弹
5 颗 阅读权限
10 在线时间
1 小时 注册时间
2009-12-15 最后登录
2010-9-18 帖子
15 贡献
0 点 子弹
5 颗 跳转到
字体大小:
发表于 2010-2-11 21:45
[CS:S] 【【【问个问题】】】
我的CS起源怎么不能建立主机呢? 建立之后 进度条走了几个格 然后跳出 出现窗口 :Unable to load authentication library,Exiting ... 服务器也添加不了。 一点添加就HL2错误弹出! 我是正版....
信春哥,Windows永不中毒!!
当前离线
74955 帖子
714 精华
28813 贡献
1 点 子弹
28813 颗 阅读权限
90 性别
男 来自
第三次泰伯伦战争幸存者 在线时间
124 小时 注册时间
2009-3-27 最后登录
2011-7-20 帖子
714 贡献
1 点 子弹
28813 颗 发表于 2010-2-12 13:08
I got no idea
AvastBee
Call me
QQ :343156978
(FPS-CN|PYO)
当前在线
48454 帖子
2233 精华
170783 贡献
50 点 子弹
170783 颗 阅读权限
100 来自
外星 在线时间
563 小时 注册时间
2008-2-24 最后登录
2011-7-29 帖子
2233 贡献
50 点 子弹
170783 颗 发表于 2010-2-12 16:30
删除steam\steama \你的ID\Source DS\下面所有文件。
CS:S ID :FPS-CN|PYO
(飞毛腿)
当前离线
55982 帖子
713 精华
20200 贡献
0 点 子弹
20200 颗 阅读权限
90 性别
男 在线时间
196 小时 注册时间
2008-5-1 最后登录
2011-5-1 帖子
713 贡献
0 点 子弹
20200 颗 发表于 2010-2-12 19:37
当前离线
81083 帖子
15 精华
0 点 子弹
5 颗 阅读权限
10 在线时间
1 小时 注册时间
2009-12-15 最后登录
2010-9-18 帖子
15 贡献
0 点 子弹
5 颗 发表于 2010-2-13 08:14
本帖最后由 3638029 于 2010-2-13 08:38 编辑
steam\steama \我的ID\没有Source DS,只有counter-strike source.. 还有个问题 我也不能添加喷图。
信春哥,Windows永不中毒!! (
GMT+8, 2011-7-29 14:42,
Proce ed in 0.033882 second(s), 6 queries, Gzip enabled
Powered by
2001-2009( Mon, 27 Dec 2010 11:27:53 +0800 )
Description:
Today I got this error me age from Tomcat 6.0.24:
LogMananger
repositorySelector
cla reloading
NOPLoggerRepository
The reason for the error is a new listener in Tomcat 6.0.24. You can fix this error by adding this line:
org.apache.catalina.loader.Weba Cla Loader.ENABLE_CLEAR_REFERENCES=false
to the "conf/catalina.properties" file in your tomcat directory.
( Fri, 9 Jan 2009 12:17:55 +0800 )
Description:
1、选择“工具” “文件夹选项” “查看”,去掉“使用简单文件共享”前的勾
2、找到数据库所在文件夹,点击右键“属性”并切换到“安全”选项卡,添加给EveryOne 用户所有权限。
添加方法为:安全添加高级立即查找选中everyone确定点上“修改”一项
3、同理给internet来宾帐户添加修改权限
4、找到数据库,右键安全,为internet来宾帐户添加“修改”权限,确定。这项很重要,一定要做
( Wed, 19 Nov 2008 10:56:06 +0800 )
Description:
1、全球图片网 2、全景图片网 3、景象图片网 4、典匠图片网 5、西藏图片网 6、超景图片网 7、素材网 8、素材中国 9、新疆图片网 .com
10 图片库素材网
( Wed, 24 Sep 2008 11:54:35 +0800 )
Description:
右击文件夹-属性-安全-添加-高级-立即查找-IUSR_XXXX &am IWAN_XXXX -确定-打开两个用户的"写入"和"修改"的权限 注意:XXXX为你的计算机名 如果操作系统用的是XP,则需要在 工具-文件夹选项-视图 中关闭"简单文件共享" 是windows本身对IUSER用户的权限问题,尤其是2000以上NTFS格式的硬盘默认禁止写入,解决办法: 1,在文件夹(或硬盘)/安全/添加IUSER用户权限。 2,IIS更改匿名访问设置。 备注:IUSER_机器名 是你机器的internet来访者的名字。
( Mon, 15 Sep 2008 10:23:25 +0800 )
Description:
喜欢你的人:半夜会找你打***聊天到很晚。 爱你的人:半夜看你在网上会赶你下线。 喜欢你的人:他会找你出去玩,叫你放弃正事或逃课。 爱你的人:他会催你快写作业或者与你讨论功课。 喜欢你的人:在你生病时,会讲好话关心你。 爱你的人:在你生病时,他会关心到你烦,并强迫你去看医生。 喜欢你的人:他会尽量说好话来讨好你,你也会觉得很开心。 爱你的人:他所说的话,都是关心你的,但是通常象是在命令。 喜欢你的人:他什么事情都会配合你,只要你开心。 爱你的人:他会帮你辨别是非,但是你会感觉他管的太多。 喜欢你的人:他说他要给你最大的快乐。 爱你的人:他只能给你保证,你跟他在一起,他是最快乐的。 喜欢你的人:他在意你的生活细节,即使你做错了什么,他也不会指出来。 爱你的人:他在意你的一举一动,告诉你什么地方错了,什么地方该如何做,该如何与别人交往。 喜欢你的人:他会帮你买夜宵,送夜宵,载你上下课或上下班。 爱你的人:他会帮你买夜宵,不过会提醒你吃什么比较健康;他会载你上下课或上下班,但通常是顺路;因为他不会为了你而逃课或旷工。因为他知道,他要为你们的将来而努力。 喜欢你的人:他不会在意你去做什么,与什么人交往。 爱你的人:他很在意你去做什么,与什么人交往。他还会告戒你不要与什么人交往 喜欢你的人:他只想要现在 爱你的人:他已经预见未来,该怎么自我努力,好好给你幸福。 喜欢你的人:他会说“我喜欢你!” 爱你的人:他会说“我爱你!” 1. 爱是他在的时候,眼睛里只有他一人; 他不在的时候,一切都带有他的影子。 喜欢是在深夜看书时突然想起他, 想象他现在做什么,心里漾起一阵轻飘飘的温暖, 却从不主动给他打***。几分钟后, 注意力又重新被书中的情节吸引! 爱是在寂寞的夜里,思念如潮水般涌来, 手里捧着书却怎么也看不进去,心里惦记着他此时是否还在加班, 吃没吃晚饭,是不是如自己想着他一般想着自己! 2. 喜欢是和他讨论问题争的面红耳赤, 各不相让,在他面前像个刺猬一样从不认输, 但在心里却早已暗暗佩服他的见地他的才华。 爱是希望他和自己步调一致,和自己心灵相通, 他无心说的一句玩笑话也能让自己顷刻情绪低落甚至眼泪汪汪。 在他面前,自己是从不设防的。 3. 喜欢是出门在外给他发个短信,告诉他这边的天气很好, 然后把手机关掉,独自在异地疯玩一个星期, 晒成一个黑人后突然出现在他面前吓他一跳。 爱是无论到哪都希望有他陪伴。可以站在海边给他打手机,让他听听海浪的声音; 也可以因为在异乡的街道上看到一个酷似他的背影而愣在原地久久不动。 4. 喜欢是他出差前简单的道一声“一路平安”,看着他离去的背影,心中有一点不舍, 却什么也不说,只是默默等待他归来的消息. 爱是他临出差前千叮咛万嘱咐,往他的背包里塞满衣服和食物, 在车站要等到火车开走才肯离开。并且在他走后的日子里天天心神不定, 一遍遍的祈祷他能够平安归来。 5. 喜欢是在受伤的时候,不想让他看到自己脆弱的一面, 在他面前把眼泪悄悄抹掉,转过头依然是一副快乐坚强的模样。 爱是在受委屈的时候,爬在他的胸前痛哭,没有伪装没有顾虑, 把所有的烦恼统统告诉他,并渴望从他的怀抱中得到安慰. 6. 喜欢是和他周末逛街逛累了一起吃肯德基; 是在寒冷的冬天和他抢一杯热咖啡; 是和他并肩走在街上中间始终隔着半米的距离; 是陪他一起在电脑前打游戏两个人笑的像个孩子。 爱是周末利用半天时间亲手做出几道好菜满足的看他吃下去; 是在寒冷的冬天不断为他的咖啡杯里续上热水; 是和他走在街上任由他紧紧挽着自己的手; 是在他旁边安静着做着,幸福地看着他在电脑前工作时专心的样子 7. 喜欢是听他讲自己童年的趣事,然后哈哈大笑,心中涌起一阵莫名的感动。 爱是听他将自己童年的趣事,然后微微一笑, 心中更加怜惜眼前这个曾经如此调皮捣蛋的男人~! 8. 喜欢是在楼道里碰上他,愉快的和他打声招呼,再简单寒暄几句, 擦肩而过的时候看见了窗外明媚的阳光,心情无端好了起来。 爱是在楼道了看见他,脸上装出一副毫不在乎的表情, 但在擦肩而过时细心感受身边颤动的空气,于是忍不住回头望一眼! 9.
喜欢是看到他和另一个女孩牵手走过,心里有一点点疼,但很快会冲着朝阳重新扬起笑脸! 爱是一场是输不起的游戏,付出全部只后, 留下的可能仅仅是刻在心底的一道伤痕! 转载.....
( Fri, 1 Aug 2008 10:40:26 +0800 )
Description:
( Sat, 26 Jul 2008 21:10:55 +0800 )
Description:
( Tue, 8 Jul 2008 10:04:10 +0800 )
Description: 这份爱我已经失去了。 现在我懂了,但已经晚了。
如果再遇上我会珍惜的。 1真正爱你的女孩,在别人面前总是野蛮,只会为你温柔,眼泪特别多.
2.真正爱你的女孩,总是会对你说别抽烟,尽管她知道你改不了,还是不耐烦的说.
3.真正爱你的女孩,无时无刻都想知道你在干什么.
4.真正爱你的女孩,会为你晚回家而着急,然后不停的给你手机拨***,直到手机没电.
5.真正爱你的女孩,不会管你钱,而你自然会心甘情愿的把所有钱都给她.
6.真正爱你的女孩,不许你在她面前夸别的女孩子漂亮,也许她心里也那么想,但是不许你在她面前那么说.
7.真正爱你的女孩,会想尽办法给你好吃的东西,因为她们愿意和分享一切她们最好的.
8.真正爱你的女孩,会在你气她的时候,默不作声,然后红着脸,嘟着嘴,等你去哄她.
9.真正爱你的女孩,有时候会在你面前变得无理取闹,撒娇任性.
10.真正爱你的女孩,会特别在意你在兄弟面前的面子.
11.真正爱你的女孩,不会跟你生气,总是假装生气,你说两句好话便马上开心真正爱你的女孩,如果你总是在她面前提到她和别的男生,她会马上泪如雨下.
12.真正爱你的女孩,记得所有你们一起有意义的日子,并且为你送上惊喜.
13.真正爱你的女孩,希望你在每年生日的时候都许下同一个愿望,就是永远和她在一起真正爱你的女孩,不会干涉你太多,她们愿意永远做你背后的女人.
14.真正爱你的女孩,她的一切都在证明,你是她生命中唯一的男人
15.真正爱你的女孩,看完肯定回贴.不回贴的就没真爱过.
16.真真爱你的女孩,你如果还没有,回贴就会有一位女孩会真正爱你哦.不回贴你永远别想有,因为你没有爱心。
.....祝回贴的男士都会有一个真正爱你女孩.女孩都会的到幸福
转自: ( Mon, 7 Jul 2008 13:37:07 +0800 )
Description:
SQL语法整理(二)
2008-03-04 23:38 select mgr,mgr/100,ceil(mgr/100) from scott.emp ceil(n),取大于等于数值n的最小整数 select mgr, mgr/100,floor(mgr/100) from scott.emp floor(n),取小于等于数值Nde 最大整数 select mgr, mod(mgr,1000), mod(mgr,100), mod(mgr,10) from scott.emp mod(m,n),取m整除n后的余数 select mgr,power(mgr,2),power(mgr,3) from scott.em power(m,n),取m的n次方 select mgr, round(mgr/100,2),round(mgr/1000,2) from scott.emp round(m,n),四舍五入,保留n位 select mgr,mgr-7800,sign(mgr-7800) from scott.emp sign(n), gt;0,取1;n=0,取0; lt;0,取-1 select avg(mgr) 平均薪水 from scott.emp avg(字段名),求平均值要求字段为数值型 select count(*) 记录总数 from scott.emp count(字段名) 或 count(*),统计总数 select min(sal) 最少薪水 from scott.emp min(字段名),计算数值型字段最小数 select max(sal) 最高薪水 from scott.emp max(字段名),计算数值型字段最大数 select sum(sal) 薪水总和 from scott.emp sum(字段名),计算数值型字段总和
单行记录的录入:
注意:数值型字段,可以直接写值字符型字段,要加单引号日期型字段,要加上单引号
多行记录的录入:
在数据的录入中,经常要将从数据表中查询到的数据稍做修改成批录入的情况,就是多行数据的录入
I ert into 数据表 (字段名1,字段名2)values(select (字段名1或运算,字段名2或运算) from 数据表 where 查询条件)
表间数据复制: create table scott.test as ( select distinct em o,ename,hirdate from scott.emp where em o = 7000
删除记录: delete from scott.test where em o = 7500 and em o = 8000
整表数据删除: truncate table scott.test
truncate table 命令将快速删除数据表中的所有记录,但保留数据表的结构这种快速删除与delete from数据表的删除全部数据表记录不一样,delete命令删除的数据将存储在系统回滚段中,需要的时候,数据可以回滚恢复,而truncate命令删除的数据是不可以恢复的
直接赋值更新: set 字段名1 = 新的值,字段名2 = 新的值 where 条件 update scott.emp set em o = 8888,ename = TOM,hiredate = 03-9 月-2002 where em o = 7878
嵌套更新: set 字段名1 = (select 字段列表 from 数据表 where 条件),字段名2 = (select 字段列表 from 数据表 where 条件) update scott.emp set sal = ( select sal + 300 from scott.emp where em o = 8888
) where em o = 8888
2008 Baidu
引文来源 ----------------------------
一键转贴,快速捕捉生活精彩,赢每周好礼!
( Mon, 7 Jul 2008 13:36:32 +0800 )
Description:
SQL语法整理(一)
2008-03-04 23:37 现把整理和积累的SQL常用语句公开给大家,以方便大家在日常工作中使用.同时也希望各位同僚,继续提出宝贵建议,作出补充.
显示数据表的结构:
desc 数据表名
查询所有记录:
select * from 数据表
查询所有记录的某些字段:
select 字段名1,字段名2 from 数据表 select name,age from 数据表
查询某些字段的不同记录:
select distinct job from 数据表 在显示时去除相同的记录
单条件查询:
select * from数据表 where sal = 2500 select * from数据表 where job != MANAGER
select * from数据表 where job ^= MANAGER
select * from数据表 where job MANAGER
select * from 数据表 where sal ^= 1000
select * from 数据表 where sal in(2000,1000,3000) / not in
select * from 数据表 where job in(MANAGER,CLERK)
select * from 数据表 where sal between 2000 and 3000 / not between
select * from 数据表 where job between MANAGER and CLERK
select * from 数据表 where job like M% / not like
select * from 数据表 where job like M_
like 和 not like 适合字符型字段的查询,%代表任意长度的字符串,_代表一个任意的字符Like m%代表 m 开头的任意长度的字符串,like m__代表 m 开头的长度为3 的字符串
select * from 数据表 where sal is null / not null
select * from 数据表 where job is null
组合条件的查询: select * from 数据表 where job = CLERK and sal = 2000 select * from 数据表 where job = CLERK or sal = 2000 逻辑非组合查询结果 not job = CLERK 等价于 job CLERK select * from 数据表 where job = CLERK order by job asc, sal desc select * from 数据表 order by job asc, sal desc
order by 可以指定查询结果如何排序,形式为字段名排序关键词;asc 代表升序排列,desc 代表降序排列,多个排序字段之间通过逗号分割若有 where 查询条件, order by 要放在 where 语句后面
分组查询:
将查询结果按照字段分组
select em o, ename, job, sal from scott.emp group by job, em o, ename,sal having sall = 2000 select em e, ename, job, sal from scott.emp where sal =2000 group by job, em o, ename, sal
注:group by 后的字段必须与前面select 后的字段相对应
where 检查每条记录是否符合条件,having 是检查分组后的各组是否满足条件having 语句只能配合 group by 语句使用,没有 group by 时不能使用,但可以使用 where
字段运算查询: select em o , ename , sal , mgr , sal + mgr from 数据表 利用算术运算仅仅适合多个数值型字段或字段与数字之间的运算
变换查询显示:
无条件多表查询: select emp.em o, emp.ename, emp.deptno, dept.dname, dept.loc from scott.emp, scott.dept
等值多表查询: select emp.em o, emp.ename, em.deptno, dept.dname, dept.loc from scott.emp, scott.dept where scott.emp.deptno = scott.dept.deptno 等值多表查询将按照等值的条件查询多个数据表中关联的数据要求关联的多个数据表的某些字段具有相同的属性,即具有相同的数据类型,宽度和取值范围
非等值多表查询: select emp.em o, emp.ename, em.deptno, dept.dname, dept.loc from scott.emp, scott.dept where scott.emp.deptno != scott.dept.deptno and scott.emp.deptno = 10
简单嵌套查询: select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal = (select sal from scott.emp where ename = WARD) 在这段代码中,子查询select sal from scott.emp where ename = WARD的含义是从emp数据表中查询姓名为WARD的员工的薪水,父查询的含义是要找出emp数据表中薪水大于等于WARD的薪水的员工 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal in (select sal from scott.emp where ename = WARD) 查询薪水和WARD相等的员工,也可以使用 not in 来查询 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal any(select sal from scott.emp where job = MANAGER) 等价于:select sal from scott.emp where job = MANAGER 查询结果为:1000,2500 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal 1000 or sal 2500 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal = some (select sal from scott.emp where job = MANAGER) 等价于:select sal from scott.emp where job = MANAGER 查询结果为:1000,2500 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal = 1000 or sal = 2500 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal all (select sal from scott.emp where job = MANAGER) 等价于:select sal from scott.emp where job = MANAGER 查询结果为:1000,2500 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal 1000 and sal 2500 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp, scott.dept where exists (select * from scott.emp where scott.emp.deptno = scott.dept.deptno) 等价于:select sal from scott.emp where job = MANAGER 查询结果为:1000,2500 select emp.em o, emp.ename, emp.job, emp.sal from scott.emp where sal = 1000 and sal = 2500
并操作的嵌套查询: 并操作就是集合中并集的概念属于集合A 或集合B的元素总和就是并集 (select deptno from scott.emp) union (select deptno from scott.dept)
交操作的嵌套查询: 交操作就是集合中交集的概念属于集合A 且属于集合B的元素总和是并集 (select deptno from scott.emp)
intersect
(select deptno from scottdept)
差操作的嵌套查询: 差操作就是差集的概念属于集合A 且不属于集合B的元素总和是并集 (select deptno from scott.emp)
(select deptno from scottdept) 发布于2007-04-03
2008 Baidu
引文来源 ----------------------------
一键转贴,快速捕捉生活精彩,赢每周好礼!
( Mon, 7 Jul 2008 12:23:55 +0800 )
Description:
mysql-co ector-java-3.1.12
[1]New Project-Web Project-取名为
[2]将加到%TOMCAT_HOME%/common/lib下
在地址栏输入,将得到默认的index.j 说明部署成功
启动Tomcat,访问,输入用户名和密码,即可进入管理界面用户名和密码可在%Tomcat _HOME%/conf/ tomcat-users.xml中找到
左边的菜单栏时有Tomcat Server,Resources,User Definition注意,不要在Resource中配置数据源,这是配置全局的数据源
进入Tomcat Server-Service(Catalina)-Host(loalhost),就能找到刚才部署的工程-Context(/Co ecterPool)
再打开该子树,打开Resources-Data Sources,这里就是针对某个具体Context的DataSource了
JNDI Name:jdbc/testpool //设置连接池的JNDI名
Data Source URL:jdbc:mysql://localhost:3306/co ool //数据库连接字串,forpool为数据库名
JDBC Driver Cla : com.mysql.jdbc.Driver //数据库连接类
User Name:root //数据库连接时的用户名
以下默认配置 descriptio gt;DB Co ectio lt;/descriptio gt; res-ref-namejdbc/testpool/res-ref-name res-typejavax.sql.DataSource/res-type res-authContainer/res-auth res-sharing-scopeShareable/res-sharing-scope
import javax.naming.InitialContext;
import javax.sql.DataSource;
InitialContext ctx=new InitialContext();
DataSource dataSource=(DataSource)ctx.lookup("java:comp/env/jdbc/testpool");
Co ection con=dataSource.getCo ection();
通过这段代码即可完成数据库连接下面给出一个具体的测试例
[1]数据库名co ool(对Data Source URL:jdbc:mysql://localhost:3306/co ool )
[3]字段名 id [varchar(12) ,notnull]
%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%
%@ page import="java.sql.*"%
%@ page import="javax.sql.*"%
%@ page import="javax.naming.*"%
%@ page se ion="false"%
!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Tra itional//EN" meta http-equiv="Content-Type" content="text/html; charset=GB18030" titletest for DB co ectio lt;/title
"begi ing testing...");
"< r");
; InitialContext ctx =
InitialContext(); ds = (DataSource) ctx.lookup("java:comp/env/jdbc/testpool"); Co ection co = ds.getCo ection(); Statement stmt = co .createStatement(); // test是数据库已有的表, //这里的数据库是前文提及的Data Source URL配置里包含的数据库 String strSql = " select * from test"; ResultSet rs = stmt.executeQuery(strSql); while
(rs.next()) { out.print(rs.getString(1));
"< r");
"end testing.");
(Exception ex) {
"error:" + ex.getMe age()); ex.printStackTrace();
编译后,%TOMCAT_HOME%/conf/Catalina/localhost/目录下有个Co ectorPool.xml,其内容为:
?xml version='1.0' encoding='utf-8'?
Context docBase="Co ectorPool" path="/Co ectorPool"
workDir="work\Catalina\localhost\Co ectorPool" Resource auth="Container" description="DB Co ection" type="javax.sql.DataSource"/ ResourceParams < amemaxWait/name value5000/value < amemaxActive/name value4/value < ame> a word/name valueroot/value < ameurl/name valuejdbc:mysql://localhost:3306/co ool/value < amedriverCla Name/name valuecom.mysql.jdbc.Driver/value < amemaxIdle/name value2/value < ameusername/name valueroot/value
/Context
driveCla Name:JDBC驱动类的完整的名称;
maxActive:同时能够从连接池中被分配的可用实例的最大数;
本文出自 子 孑 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/51938
本文出自 51CTO.COM技术博客
引文来源 ----------------------------
一键转贴,快速捕捉生活精彩,赢每周好礼!
( Sun, 6 Jul 2008 19:46:52 +0800 )
Description: 女人总会问男人你爱我么,只是因为女人对于爱太需要。如果一个男人真的爱你,他不会不耐烦,不会说你应该成熟些了……看看下面的几条,问问自己,那个男人还爱你么,如果回答是no,即使不舍得也要学会走开……
第一条:
如果一个男人真的爱你,他的手机会为你24小时开机,在你最需要他的时候可以随时找到他,因为他爱你,所以会时时担心你。
第二条:
如果一个男人真的爱你,他会很自豪的告诉他的朋友与家人你是他最爱的女人,当然并不是时时挂在嘴上,而是用一种行动去告诉别人,你是他最爱的女人!因为有了你他觉得很骄傲,无论你是不是真的很优秀。 第三条:
如果一个男人真的爱你,他会把除了工作之外的很多时间都给你,当然会偶尔和朋友去聚会,因为他想时时刻刻都看见你。
第四条:
如果一个男人真的爱你,他会毫不吝啬的给你物质上的付出(我并不是说所有的女孩子都应该物质化,这种付出是他心甘情愿的)因为他觉得他所有辛苦的努力就是为了让你过上很幸福的生活,他爱你,不想让你过的那么艰苦。
第五条:
如果一个男人真的爱你,他绝对不会骂你,在你很任性的时候任你发泄,当你任性过去的时候,会很委屈的说:“老婆,我又作错什么了?你可以告诉我,我一定改,千万不要生气,那样会把身体气坏的”。
第六条:
如果一个男人真的爱你,你会发现你和他在一起后,不经意间发现你总有很多穿不完的衣服,因为他总是看见漂亮的东西就买给你。
第七条:
如果一个男人真的爱你,他就不在乎陪你逛街会浪费他多少出去自由的机会,因为他甘愿失去那种所谓的自由。
第八条:
如果一个男人真的爱你,无论你们在一起多久,都会陪你一起爬山,看海,看星星,看日落,因为他知道你渴望这样的浪漫。
第九条:
如果一个男人真的爱你,他绝对不会嚷嚷着叫你去减肥,但是这个时候你自己一定要去健康减肥,因为苗条的女人确实可以叫人赏心悦目。因为你的健康是他最关心的。
第十条:
如果一个男人真的爱你,他不会留恋与网络与别的***眉甜言蜜语,因为对你他都有说不完的爱,哪有那心思和别人废话。
第十一条:
如果一个男人真的爱你,他不会还和前女友有联系。
第十二条:
如果一个男人真的爱你,他在每天很辛苦的工作回到家的时候,会抱着你说“老婆,我回来了”他爱你,他绝对不会把不快乐带给你!
第十三条:
如果一个男人真的爱你,他会在清晨上班的时候,亲吻你的眼睛,满足的说:宝贝,我上班去了!”
第十四条:
如果一个男人真的爱你,他绝对不会忍心背叛你,无论出于什么样的动机。因为在他眼里,你是最美的,即便你不是。
第十五条:
如果一个男人真的爱你,在你故意说要离开的时候,撒娇的不和你分开,而在你真的想离开的时候,就会放你走,即便他真的不愿意放手。因为他爱你,只希望你幸福。
第十六条:
如果一个男人真的爱你,他绝对不会以事业忙为借口而推脱你。
第十七条:
如果一个男人真的爱你,他绝对不会一次次把你推向那冰冷的手术台,更不会让你一个人孤孤单单的去走向那冰冷的世界,他会郑重的说:“把我们的宝贝生下来吧!”
第十八条:
如果一个男人真的爱你,他会象爱他家人那样爱你的家人,也会尊重你的亲人和朋友。
第十九条:
如果一个男人真的爱你,他不会不耐烦,不会说你应该成熟些了…… ( Tue, 1 Jul 2008 14:32:35 +0800 )
Description:
用CodeSmith生成自定义模板
当生成应用程序时,无论是编写数据访问代码还是生成自定义实体自定义集合,你会发现经常需要重复完成某些特定的任务最近用CodeSmith编写了界面层到数据库访问层的模板以及用于生成存储过程的模板,感觉CodeSmith非常不错,不仅有利于提高团队的工作效率,自动完成那些最为乏味的任务,而且有利于让大家的代码保持一定的一致性和规范性下面详细介绍一下如何生成自定义模板(以自定义实体为列),以作为总结,也希望对您有所帮助
第一步是添加模板头,声明模板的语言目标语言以及简要模板说明:
以下是代码片段:
指明这是一个C#语言的模板CodeSmith 包括一个名为 SchemaExplorer 的特殊的程序集,可用来从表存储过程或几乎任何其他 SQL Server对象生成模板下面引入该集合和命名空间:
以下是代码片段:
第二步,属性声明,在这里可声明将在模板每次运行时指定的属性,以方便
设置一系列需要传入的参数:
以下是代码片段:
如上边所示,在进行代码生成时,在CodeSmith Explorer中选择模板后生成代码的窗口中,变量的名称为DataBase,类型是SchemaExplorer.DatabaseSchema,类别是Context,当用户选中这个属性时对于属性的描述Description
以下是代码片段:
如上边所示,变量的名称为TableName,NameSpace,类型是String,类别是Strings,当用户选中这个属性时对于属性的描述Description
以下是代码片段:
如上面所示,变量的名称为Author,Description,类型是String,类别为空(显示为杂项),当用户选中这个属性时对于属性的描述Description
相应属性界面显示如下图所示:
第三步,编写C#语言模板类部分代码CodeSmith
模板脚本格式:
以下是代码片段:
CodeTemplateRule rule=new CodeTemplateRule();
public cla CodeTemplateRule
实例化类CodeTemplateRule
以下是代码片段:
public ColumnSchemaCollection GetColumnCollection(DatabaseSchema dataBase,string tableName)
TableSchemaCollection tables = new TableSchemaCollection(dataBase.Tables);
ColumnSchemaCollection colum =null;
for(int i=0;i
if(tables[i].Name.ToU er()==tableName.ToU er())
TableSchema ts=tables[i];
colum =new ColumnSchemaCollection(ts.Colum );
return colum }
函数作用:输入数据库名和表名,得到列集合信息用内部函数ColumnSchemaCollection可以得到某张表的所有列的集合
以下是代码片段:
public string GetTableName(string tableName)
int i=tableName.IndexOf("_");
return tableName.Su tring(i+1,tableName.Length-(i+1));
函数作用:对输入的表名格式化,得到去掉前缀的表名,如PE_User,返回User
以下是代码片段:
public string GetType(ColumnSchema column)
if (column.Name.EndsWith("TypeCode")) return column.Name;
switch (column.DataType)
case DbType.A iString: return "string";
case DbType.A iStringFixedLength: return "string";
case DbType.Binary: return "byte[]";
case DbType.Boolean: return "bool";
case DbType.Byte: return "int";
case DbType.Currency: return "decimal";
case DbType.Date: return "DateTime";
case DbType.DateTime: return "DateTime";
case DbType.Decimal: return "decimal";
case DbType.Double: return "double";
case DbType.Guid: return "Guid";
case DbType.Int16: return "short";
case DbType.Int32: return "int";
case DbType.Int64: return "long";
case DbType.Object: return "object";
case DbType.SByte: return " yte";
case DbType.Single: return "float";
case DbType.String: return "string";
case DbType.StringFixedLength: return "string";
case DbType.Time: return "TimeSpan";
case DbType.UInt16: return "ushort";
case DbType.UInt32: return "uint";
case DbType.UInt64: return "ulong";
case DbType.VarNumeric: return "decimal";
default:
return "__UNKNOWN__" + column.NativeType;
函数作用:得到表字段的类型
以下是代码片段:
public string GetDefaultValue(ColumnSchema column)
if (column.Name.EndsWith("TypeCode")) return column.Name;
switch (column.DataType)
case DbType.A iString: return "\"\"";
case DbType.A iStringFixedLength: return "\"\"";
case DbType.Binary: return "null";
case DbType.Boolean: return "false";
case DbType.Byte: return "0";
case DbType.Currency: return "0";
case DbType.Date: return "DateTime.Parse(\"1900-1-1\")";
case DbType.DateTime: return "DateTime.Parse(\"1900-1-1\")";
case DbType.Decimal: return "0";
case DbType.Double: return "0";
case DbType.Guid: return "Guid.NewGuid().ToString()";
case DbType.Int16: return "0";
case DbType.Int32: return "0";
case DbType.Int64: return "0";
case DbType.Object: return "\"\"";
case DbType.SByte: return "0";
case DbType.Single: return "0";
case DbType.String: return "\"\"";
case DbType.StringFixedLength: return "";
case DbType.Time: return "DateTime.Parse(\"1900-1-1\")";
case DbType.UInt16: return "0";
case DbType.UInt32: return "0";
case DbType.UInt64: return "0";
case DbType.VarNumeric: return "0";
default:
return "__UNKNOWN__" + column.NativeType;
函数作用:得到表字段的默认值
以下是代码片段:
public string ConvPropertyName(string name)
return name.Su tring(0,1).ToU er() +
name.Su tring(1);
函数作用:对输入的名称格式化,得到首字母为大写的名称,如user,返回User
第四步,编写实际生成模板主体的代码,根据你需要的格式输出代码如下:
以下是代码片段:
using System;
using System.Collectio .Generic;
using System.Text;
name ace PowerEasy.Model.
/// Description:
public cla Info
ColumnSchemaCollection colum =rule.GetColumnCollection(DataBase,TableName);
for(int i=0;i
Re o e.Write(" //"+colum [i].Description+"\r\n");
Re o e.Write(" private "+rule.GetType(colum [i])+" m_"+colum [i].Name+";\r\n");
#region
for(int i=0;i
get { return m_
set { m_
=value; }
#endregion
最后,
CodeSmithStudio.exe
运行模板
填写你的参数,运行后就得到了你需要的实体代码:
以下是引用片段:
using System;
using System.Collectio .Generic;
using System.Text;
name ace AAA
/// Description:BBB实体
public cla OrderInfo
///Description
public OrderInfo()
//订单ID
private int m_OrderId;
//订单编号
private string m_OrderNum;
//用户名
private string m_UserName;
//代理商名
private string m_AgentName;
//客户ID
private int m_ClientId;
//订单总金额
private decimal m_MoneyTotal;
//购买商品合计金额
private decimal m_MoneyGood //是否需要开***
private bool m_NeedInvoice;
//发表内容,包括抬头商品名称金额等
private string m_InvoiceContent;
//是否已开***
private bool m_Invoiced;
//备注
private string m_Remark;
//已收款
private decimal m_MoneyReceipt;
//开始服务日期
private DateTime m_BeginDate;
//录入时间
private DateTime m_I utTime;
//受货人姓名
private string m_ContacterName;
//收货人地址
private string m_Addre //邮编
private string m_ZipCode;
//手机
private string m_Mobile;
//联系***
private string m_Phone;
//EMAIL
private string m_Email;
//付款方式
private int m_PaymentType;
//送货方式
private int m_DeliverType;
//订单状态
private int m_Statu //物流状态
private int m_DeliverStatu //是否开通下载
private bool m_EnableDownload;
//返还的现金券
private decimal m_PresentMoney;
//赠送点券
private int m_PresentPoint;
//得到的积分
private int m_PresentEx //付款方式的折扣
private double m_Discount_Payment;
//运费
private decimal m_Charge_Deliver;
private string m_ClientName;
#region
///订单ID
public int OrderId
get { return m_OrderId; }
set { m_OrderId = value; }
///订单编号
public string OrderNum
get { return m_OrderNum; }
set { m_OrderNum = value; }
///用户名
public string UserName
get { return m_UserName; }
set { m_UserName = value; }
///代理商名
public string AgentName
get { return m_AgentName; }
set { m_AgentName = value; }
///客户ID
public int ClientId
get { return m_ClientId; }
set { m_ClientId = value; }
///订单总金额
public decimal MoneyTotal
get { return m_MoneyTotal; }
set { m_MoneyTotal = value; }
///购买商品合计金额
public decimal MoneyGoods
get { return m_MoneyGood }
set { m_MoneyGoods = value; }
///是否需要开***
public bool NeedInvoice
get { return m_NeedInvoice; }
set { m_NeedInvoice = value; }
///发表内容,包括抬头商品名称金额等
public string InvoiceContent
get { return m_InvoiceContent; }
set { m_InvoiceContent = value; }
///是否已开***
public bool Invoiced
get { return m_Invoiced; }
set { m_Invoiced = value; }
///备注
public string Remark
get { return m_Remark; }
set { m_Remark = value; }
///已收款
public decimal MoneyReceipt
get { return m_MoneyReceipt; }
set { m_MoneyReceipt = value; }
///开始服务日期
public DateTime BeginDate
get { return m_BeginDate; }
set { m_BeginDate = value; }
///录入时间
public DateTime I utTime
get { return m_I utTime; }
set { m_I utTime = value; }
///受货人姓名
public string ContacterName
get { return m_ContacterName; }
set { m_ContacterName = value; }
///收货人地址
public string Addre {
get { return m_Addre }
set { m_Addre = value; }
///邮编
public string ZipCode
get { return m_ZipCode; }
set { m_ZipCode = value; }
///手机
public string Mobile
get { return m_Mobile; }
set { m_Mobile = value; }
///联系***
public string Phone
get { return m_Phone; }
set { m_Phone = value; }
///EMAIL
public string Email
get { return m_Email; }
set { m_Email = value; }
///付款方式
public int PaymentType
get { return m_PaymentType; }
set { m_PaymentType = value; }
///送货方式
public int DeliverType
get { return m_DeliverType; }
set { m_DeliverType = value; }
///订单状态
public int Status
get { return m_Statu }
set { m_Status = value; }
///物流状态
public int DeliverStatus
get { return m_DeliverStatu }
set { m_DeliverStatus = value; }
///是否开通下载
public bool EnableDownload
get { return m_EnableDownload; }
set { m_EnableDownload = value; }
///返还的现金券
public decimal PresentMoney
get { return m_PresentMoney; }
set { m_PresentMoney = value; }
///赠送点券
public int PresentPoint
get { return m_PresentPoint; }
set { m_PresentPoint = value; }
///得到的积分
public int PresentExp
get { return m_PresentEx }
set { m_PresentExp = value; }
///付款方式的折扣
public double DiscountPayment
get { return m_Discount_Payment; }
set { m_Discount_Payment = value; }
///运费
public decimal ChargeDeliver
get { return m_Charge_Deliver; }
set { m_Charge_Deliver = value; }
///客户姓名
public string ClientName
get { return m_ClientName; }
set { m_ClientName = value; }
#endregion
引文来源 ----------------------------
一键转贴,快速捕捉生活精彩,赢每周好礼!
( Tue, 1 Jul 2008 10:49:35 +0800 )
Description:
摩羯座.NET
TeeBye's Blog 前段时间,学习Monorail和IBatis.Net,写了个小网站,呵呵,查看demo
有一个很强烈的感觉就是使用monorail更像是自己是在写网站,也许能体会到一些php开发者的乐趣这是以前用WebForm感受不到的,WebForm开发更像Winform Monorail和IBatis.Net架构,前期的一些配置还是比较繁琐的,基本的目录结构是这样的
大家都知道,Monorail是MVC,他的官方Sample中大致上是ContentControllerComponentsViewsModel这样的目录结构;Content目录中放我们的Js image和c 文件Controller目录里只我们的控制器,View是我们的定义好的模板文件,Components里是一些自定义组件文件 为了使用Ibati et,我只好把model拿到外面,变成了和Web同级的目录,这就是上图看到的Entity
上图中的的Busine DaoEntity都是可以利用工具自动生成的下载这个工具 下面说说配置文件,还是先看目录结构 Ma 目录里Ibati et使用的sql语句的config文件,config目录里面放的都是配置文件,全部有 components.config里面是注册我们自定义的component,内容如下每个comonent id对应的cs代码文件都在在Components目录下面
?xml version="1.0" encoding="utf-8"?
configuratio gt lt;component gt lt;component id="Di layTopWe iteComponent" type="GTTOLCOM.Web.Components.Di layTopWe iteComponent, GTTOLCOM.Web"/componentcomponent id="HeaderComponent" type="GTTOLCOM.Web.Components.HeaderComponent, GTTOLCOM.Web"/componentcomponent id="Di layNoticeComponent" type="GTTOLCOM.Web.Components.Di layNoticeComponent, GTTOLCOM.Web"/componentcomponent id="FooterComponent" type="GTTOLCOM.Web.Components.FooterComponent, GTTOLCOM.Web"/componentcomponent id="Di layCategoryComponent" type="GTTOLCOM.Web.Components.Di layCategoryComponent, GTTOLCOM.Web"/componentcomponent id="Di laySiteInfoComponent" type="GTTOLCOM.Web.Components.Di laySiteInfoComponent, GTTOLCOM.Web"/componentcomponent id="Di layPathLinksComponent" type="GTTOLCOM.Web.Components.Di layPathLinksComponent, GTTOLCOM.Web"/componentcomponent id="Di layNavListComponent" type="GTTOLCOM.Web.Components.Di layNavListComponent, GTTOLCOM.Web"/componentcomponent id="Di laySubmitAttentionComponent" type="GTTOLCOM.Web.Components.Di laySubmitAttentionComponent, GTTOLCOM.Web"/componentcomponent id="Di layAddSiteInfoComponent" type="GTTOLCOM.Web.Components.Di layAddSiteInfoComponent, GTTOLCOM.Web"/componentcomponent id="Di layUserPathLinksComponent" type="GTTOLCOM.Web.Components.Di layUserPathLinksComponent, GTTOLCOM.Web"/componentcomponent id="Di layR Component" type="GTTOLCOM.Web.Components.Di layR Component, GTTOLCOM.Web"/componentcomponent id="Di layTagListComponent" type="GTTOLCOM.Web.Components.Di layTagListComponent, GTTOLCOM.Web"/componentcomponent id="Di layAllCommentsComponent" type="GTTOLCOM.Web.Components.Di layAllCommentsComponent, GTTOLCOM.Web"/componentcomponent id="Di laySpecialSiteComponent" type="GTTOLCOM.Web.Components.Di laySpecialSiteComponent, GTTOLCOM.Web"/componentcomponent id="Di layAddUrlsToolComponent" type="GTTOLCOM.Web.Components.Di layAddUrlsToolComponent, GTTOLCOM.Web"/component/component gt lt;/configuratio gt;
Controlloer.config文件内容
?xml version="1.0" encoding="utf-8"?
configuratio gt lt;component gt lt;component id="home.controller"="GTTOLCOM.Web.Controllers.HomeController, GTTOLCOM.Web"/component id="layout.controller"="GTTOLCOM.Web.Controllers.LayoutController, GTTOLCOM.Web"/component id="sitemanager.controller"="GTTOLCOM.Web.Controllers.SiteManagerController, GTTOLCOM.Web"/component id="Browse.controller"="GTTOLCOM.Web.Controllers.BrowseController, GTTOLCOM.Web"/component id="Account.controller"="GTTOLCOM.Web.Controllers.AccountController, GTTOLCOM.Web"/component id="FriendLinks.controller"="GTTOLCOM.Web.Controllers.FriendLinksController, GTTOLCOM.Web"/component id="Comments.controller"="GTTOLCOM.Web.Controllers.CommentsController, GTTOLCOM.Web"//component gt lt;/configuratio gt;
facilities.config的内容
?xml version="1.0" encoding="utf-8"?
configuratio gt lt;facilitie gt lt;facility id="rails" type="Castle.MonoRail.WindsorExte ion.MonoRailFacility, Castle.MonoRail.WindsorExte ion"/="atm"="Castle.Facilities.AutomaticTra actionManagement.Tra actionFacility, Castle.Facilities.AutomaticTra actionManagement"/="ibatis"="Castle.Facilities.IBatisNetIntegration.IBatisNetFacility, Castle.Facilities.IBatisNetIntegration"> lt qlMa id="sqlServerSqlMap" config="config/sqlMap.config"//facilityfacility id="loggingfacility" configfile="config/log4net.config" loggingapi="log4net" type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging"/facility/facilitie gt lt;/configuratio gt;
log4Net.config内容
?xml version="1.0" encoding="utf-8"?
configuratio gt lt;log4net!-- Define ome output a ender --a ender ame="RollingLogFileA ender" type="log4net.A ender.RollingFileA ender"> lt aram ame="File" value="log.txt"/> lt aram ame="A endToFile" value="true"/> lt aram ame="MaxSizeRollBacku " value="2"/> lt aram ame="MaximumFileSize" value="100KB"/> lt aram ame="RollingStyle" value="Size"/> lt aram ame="StaticLogFileName" value="true"/layout type="log4net.Layout.PatternLayout"> lt aram ame="Header" value="[Header]\r\n"/> lt aram ame="Footer" value="[Footer]\r\n"/> lt aram ame="ConversionPattern" value="%d [%t] %-5 %c [%x] - %m%n"//layout/a endera ender ame="Co oleA ender" type="log4net.A ender.Co oleA ender"layout type="log4net.Layout.PatternLayout"> lt aram ame="ConversionPattern" value="%d [%t] %-5 %c [%x] lt;%X{auth}> - %m%n"//layout/a ender!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --!-- Set root logger level to ERROR and it a ender --rootlevel value="DEBUG"/a ender-refref="RollingLogFileA ender"/a ender-refref="Co oleA ender"//root!-- Print only me age of level DEBUG or above i the ackage --logger ame="IBatisNet.DataMa er.Configuration.Cache.CacheModel"level value="DEBUG"//loggerlogger ame="IBatisNet.DataMa er.Configuration.Statements.PreparedStatementFactory"level value="OFF"//loggerlogger ame="IBatisNet.DataMa er.Commands.IPreparedCommand"level value="OFF"//loggerlogger ame="IBatisNet.DataMa er.LazyLoadInterceptor"level value="DEBUG"//loggerlogger ame="IBatisNet.DataMa er.LazyLoadProxyFactory"level value="DEBUG"//loggerlogger ame="IBatisNet.DataAcce .DaoSe ion"level value="DEBUG"//loggerlogger ame="IBatisNet.DataMa er.SqlMapSe ion"level value="DEBUG"//loggerlogger ame="IBatisNet.Common.Tra action.Tra actionScope"level value="DEBUG"//loggerlogger ame="IBatisNet.DataAcce .Configuration.DaoProxy"level value="DEBUG"//loggerlogger ame="IBatisNet.DataMa er.Commands.DefaultPreparedCommand"level value="DEBUG"//loggerlogger ame="IBatisNet.Common.Utilities.ConfigWatcherHandler"level value="DEBUG"//loggerlogger ame="IBatisNet.DataMa er.Configuration.Cache.CacheModel"level value="DEBUG"//logger/log4net
/configuratio gt;
providers.configd内容
?xml version="1.0" encoding="utf-8"?
xml ="http://ibatis.apache.org/providers"="http://www.w3.org/2001/XMLSchema-i tance"clear/> lt ame="sqlServer1.0"="Microsoft SQL Server, rovider V1.0.3300.0 i framework .NET V1.0"="false"="System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" co ectionCla ="System.Data.SqlClient.SqlCo ection"="System.Data.SqlClient.SqlCommand"="System.Data.SqlClient.SqlParameter"="System.Data.SqlDbType"="SqlDbType"="System.Data.SqlClient.SqlDataAdapter"="System.Data.SqlClient.SqlCommandBuilder"="false"="true" useParameterPrefixInParameter="true"="@"="false"/> lt ame="sqlServer1.1"="Microsoft SQL Server, rovider V1.0.5000.0 i framework .NET V1.1"="false"="true"="System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"="System.Data.SqlClient.SqlCo ection"="System.Data.SqlClient.SqlCommand"="System.Data.SqlClient.SqlParameter"="System.Data.SqlDbType"="SqlDbType"="System.Data.SqlClient.SqlDataAdapter"="System.Data.SqlClient.SqlCommandBuilder"="false"="true" useParameterPrefixInParameter="true"="@"="false"/> lt ame="sqlServer2.0"="true"="Microsoft SQL Server, rovider V2.0.0.0 i framework .NET V2.0"="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"="System.Data.SqlClient.SqlCo ection"="System.Data.SqlClient.SqlCommand"="System.Data.SqlClient.SqlParameter"="System.Data.SqlDbType"="SqlDbType"="System.Data.SqlClient.SqlDataAdapter"=" System.Data.SqlClient.SqlCommandBuilder"= "false"= "true" useParameterPrefixInParameter = "true"="@"="false"/> lt rovider ame="OleDb1.1"="OleDb, rovider V1.0.5000.0 i framework .NET V1.1"="false"="System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"="System.Data.OleDb.OleDbCo ection"="System.Data.OleDb.OleDbCommand"="System.Data.OleDb.OleDbParameter"="System.Data.OleDb.OleDbType"="OleDbType"="System.Data.OleDb.OleDbDataAdapter"="System.Data.OleDb.OleDbCommandBuilder"="true"="false" useParameterPrefixInParameter="false"=""="false"/> lt rovider ame="OleDb2.0"="OleDb, rovider V2.0.0.0 i framework .NET V2"="false"="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"="System.Data.OleDb.OleDbCo ection"="System.Data.OleDb.OleDbCommand"="System.Data.OleDb.OleDbParameter"="System.Data.OleDb.OleDbType"="OleDbType"="System.Data.OleDb.OleDbDataAdapter"="System.Data.OleDb.OleDbCommandBuilder"="true"="false" useParameterPrefixInParameter="false"=""="false"/> lt ame="Odbc1.1"="Odbc, rovider V1.0.5000.0 i framework .NET V1.1"="false"="System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"="System.Data.Odbc.OdbcCo ection"="System.Data.Odbc.OdbcCommand"="System.Data.Odbc.OdbcParameter"="System.Data.Odbc.OdbcType"="OdbcType"="System.Data.Odbc.OdbcDataAdapter"="System.Data.Odbc.OdbcCommandBuilder"="true"="false" useParameterPrefixInParameter="false"="@"="false"/> lt ame="Odbc2.0"="Odbc, rovider V2.0.0.0 i framework .NET V2"="false"="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"="System.Data.Odbc.OdbcCo ection"="System.Data.Odbc.OdbcCommand"="System.Data.Odbc.OdbcParameter"="System.Data.Odbc.OdbcType"="OdbcType"="System.Data.Odbc.OdbcDataAdapter"="System.Data.Odbc.OdbcCommandBuilder"="true"="false" useParameterPrefixInParameter="false"="@"="false"/> lt ame="oracle9.2"="Oracle, Oracle rovider V9.2.0.401"="false"="Oracle.DataAcce , Version=9.2.0.401, Culture=neutral, PublicKeyToken=89b483f429c47342" co ectionCla ="Oracle.DataAcce .Client.OracleCo ection"="Oracle.DataAcce .Client.OracleCommand"="Oracle.DataAcce .Client.OracleParameter"="Oracle.DataAcce .Client.OracleDbType"="OracleDbType"="Oracle.DataAcce .Client.OracleDataAdapter"="Oracle.DataAcce .Client.OracleCommandBuilder"="false"="true" useParameterPrefixInParameter="false"=":"="false"="false"/> lt ame="oracle10.1"="Oracle, oracle rovider V10.1.0.301"="false"="Oracle.DataAcce , Version=10.1.0.301, Culture=neutral, PublicKeyToken=89b483f429c47342" co ectionCla ="Oracle.DataAcce .Client.OracleCo ection"="Oracle.DataAcce .Client.OracleCommand"="Oracle.DataAcce .Client.OracleParameter"="Oracle.DataAcce .Client.OracleDbType"="OracleDbType"="Oracle.DataAcce .Client.OracleDataAdapter"="Oracle.DataAcce .Client.OracleCommandBuilder"="true"="true" useParameterPrefixInParameter="true"=":"="false"="false"/> lt ame="oracleClient1.0"="Oracle, Microsoft rovider V1.0.5000.0"="false"="System.Data.OracleClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" co ectionCla ="System.Data.OracleClient.OracleCo ection"="System.Data.OracleClient.OracleCommand"="System.Data.OracleClient.OracleParameter"="System.Data.OracleClient.OracleType"="OracleType"="System.Data.OracleClient.OracleDataAdapter"="System.Data.OracleClient.OracleCommandBuilder"="false"="true" useParameterPrefixInParameter="false"=":"="false"/> lt ame="ByteFx"="MySQL, ByteFx rovider V0.7.6.15073"="false"="ByteFX.MySqlClient, Version=0.7.6.15073, Culture=neutral, PublicKeyToken=f2fef6fed1732fc1" co ectionCla ="ByteFX.Data.MySqlClient.MySqlCo ection"="ByteFX.Data.MySqlClient.MySqlCommand"="ByteFX.Data.MySqlClient.MySqlParameter"="ByteFX.Data.MySqlClient.MySqlDbType"="MySqlDbType"="ByteFX.Data.MySqlClient.MySqlDataAdapter"="ByteFX.Data.MySqlClient.MySqlCommandBuilder"="false"="true" useParameterPrefixInParameter="true"="@"="false"/> lt ame="MySql"="MySQL, MySQL rovider 1.0.7.30072"="false"="MySql.Data, Version=1.0.7.30072, Culture=neutral, PublicKeyToken=c5687fc88969c44d" co ectionCla ="MySql.Data.MySqlClient.MySqlCo ection"="MySql.Data.MySqlClient.MySqlCommand"="MySql.Data.MySqlClient.MySqlParameter"="MySql.Data.MySqlClient.MySqlDbType"="MySqlDbType"="MySql.Data.MySqlClient.MySqlDataAdapter"="MySql.Data.MySqlClient.MySqlCommandBuilder"="false"="true" useParameterPrefixInParameter="true"="?"="false"/> lt rovider ame="SQLite3"="SQLite, SQLite.NET rovider V0.21.1869.3794"="false"="SQLite.NET, Version=0.21.1869.3794, Culture=neutral, PublicKeyToken=c273bd375e695f9c"="Finisar.SQLite.SQLiteCo ection"="Finisar.SQLite.SQLiteCommand"="Finisar.SQLite.SQLiteParameter"="System.Data.DbType, System.Data"="DbType"="Finisar.SQLite.SQLiteDataAdapter"="Finisar.SQLite.SQLiteCommandBuilder"="false"="true" useParameterPrefixInParameter="true"="@"="false"="false"="false"/> lt ame="Firebird1.7"="Firebird, Firebird SQL .NET rovider V1.7.0.33200"="false"="FirebirdSql.Data.Firebird, Version=1.7.0.33200, Culture=neutral, PublicKeyToken=fa843d180294369d" co ectionCla ="FirebirdSql.Data.Firebird.FbCo ection"="FirebirdSql.Data.Firebird.FbCommand"="FirebirdSql.Data.Firebird.FbParameter"="FirebirdSql.Data.Firebird.FbDbType"="FbDbType"="FirebirdSql.Data.Firebird.FbDataAdapter"="FirebirdSql.Data.Firebird.FbCommandBuilder"="false"="true" useParameterPrefixInParameter="true"="@"="false"/> lt ame="PostgreSql0.99.1.0"="PostgreSql, Npgsql rovider V0.99.1.0"="false"="Npgsql, Version=0.99.1.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7"="Npgsql.NpgsqlCo ection"="Npgsql.NpgsqlCommand"="Npgsql.NpgsqlParameter"="NpgsqlTypes.NpgsqlDbType"="NpgsqlDbType"="Npgsql.NpgsqlDataAdapter"="Npgsql.NpgsqlCommandBuilder"="false"="true" useParameterPrefixInParameter="true"=":"="true"/> lt ame="iDb2.10"="IBM DB2 Provider, V 10.0"="false"="IBM.Data.DB2.iSeries, Version=10.0.0.0,Culture=neutral, PublicKeyToken=9cdb2ebfb1f93a26, Custom=null" co ectionCla ="IBM.Data.DB2.iSeries.iDB2Co ection"="IBM.Data.DB2.iSeries.iDB2Command"="IBM.Data.DB2.iSeries.iDB2Parameter"="IBM.Data.DB2.iSeries.iDB2DbType"="iDB2DbType"="IBM.Data.DB2.iSeries.iDB2DataAdapter"="IBM.Data.DB2.iSeries.iDB2CommandBuilder"="true"="false" useParameterPrefixInParameter="false"=""="false"/> lt ame="Informix"="Informix NET Provider, 2.81.0.0"="false"="IBM.Data.Informix, Version=2.81.0.0, Culture=neutral, PublicKeyToken=7c307b91aa13d208"="IBM.Data.Informix.IfxCo ection"="IBM.Data.Informix.IfxCommand"="IBM.Data.Informix.IfxParameter"="IBM.Data.Informix.IfxType"="IfxType"="IBM.Data.Informix.IfxDataAdapter"="IBM.Data.Informix.IfxCommandBuilder"= "true"= "false" useParameterPrefixInParameter = "false"="false"="false"/
/provider gt;
sqlMap.config内容
?xml version="1.0" encoding="utf-8"?
xml ="http://ibatis.apache.org/dataMa er"="http://www.w3.org/2001/XMLSchema-i tance"> lt etting gt lt etting useStatementName aces="false"/> lt etting cacheModelsEnabled="true"/> lt etting useReflectionOptimizer="true"//setting gt lt;!--database roviders--> lt rovider resource="config/providers.config"/database> lt rovider ame="sqlServer2.0"/dataSource ame="GTTOLCOM" co ectionString="data ource=TEE\SQLEXPRESS;database=SiteDir;user id=sa a word=123;co ectio reset=false;co ectio lifetime=5 mi ool ize=1 max ool ize=100"//database!--设置sqlmap,所有实体的数据库操作--> lt qlMa gt lt qlMa resource="Ma /TbBgCla .config"/> lt qlMa resource="Ma /TbComment.config"/> lt qlMa resource="Ma /TbInfo.config"/> lt qlMa resource="Ma /TbMenu.config"/> lt qlMa resource="Ma /TbSiteConfig.config"/> lt qlMa resource="Ma /TbUser.config"/> lt qlMa resource="Ma /TbAdSite.config"/> lt qlMa resource="Ma /TbFriendLinks.config"/> lt qlMa resource="Ma /TbKey.config"//sqlMa gt lt;/sqlMapConfig
Web.config
?xml version="1.0" encoding="utf-8" ?
configuratio gt lt;configSectio gt lt ectionGrou ame="blowery.web"> lt ectio ame="httpCompre " type="blowery.Web.HttpCompre .SectionHandler, lowery.Web.HttpCompre "//sectionGrou gt lt ectio ame="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> lt ectionGrou ame="iBATIS"> lt ectio ame="logging" type="IBatisNet.Common.Logging.ConfigurationSectionHandler, IBatisNet.Common"//sectionGrou gt lt ectio ame="monorail"="Castle.MonoRail.Framework.Configuration.MonoRailSectionHandler, Castle.MonoRail.Framework"/> lt ectio ame="castle"="Castle.Windsor.Configuration.A Domain.CastleSectionHandler, Castle.Windsor"//configSectio gt lt;!----monorail mtpHost=""=""=""="true"controller gt lt;a emblyGTTOLCOM.We lt;/a embly/controller gt lt;viewEngine viewPathRoot="Views"xhtml="false"="Castle.MonoRail.Framework.Views.NVelocity.NVelocityViewEngine, Castle.MonoRail.Framework.Views.NVelocity"//viewEngine gt lt;routingrule(/home/parentdirectory/)(\w+)/index.html$/patter gt lt;replace![CDATA[ /browse/index.castle?d=$2 ]]/replace/rulerule(/home/subdirectory/)(\w+)/index.html$/patter gt lt;replace![CDATA[ /browse/index.castle?sid=$2 ]]/replace/rulerule(/home/)(\w+)/(\w+)/index.html$/patter gt lt;replace![CDATA[ /browse/index.castle?le=$2&am BID=$3 ]]/replace/rulerule(/home/)(\w+)/index.html$/patter gt lt;replace![CDATA[ /home/search.castle?search=$2 ]]/replace/rulerule(/home/)(\w+)(.)html$/patter gt lt;replace![CDATA[ /home/new.castle?list=$2 ]]/replace/rulerule(/home/ru/)(w{3}\.\w+\.\w{1,3})/index.html$/patter gt lt;replace![CDATA[ /browse/returnurl.castle?ru=$2 ]]/replace/rulerule(/home/datail/i/)(\d+)/index.html$/patter gt lt;replace![CDATA[ /browse/datail.castle?i=$2 ]]/replace/rulerule(/home/links/)(w{3}\.\w+\.\w{1,3})/index.html$/patter gt lt;replace![CDATA[ /friendlinks/index.castle?ul=$2 ]]/replace/rulerule(/home/comments/)(w{3}\.\w+\.\w{1,3})/index.html$/patter gt lt;replace![CDATA[ /comments/index.castle?ul=$2 ]]/replace/rulerule(/home/comments/all/)(w{3}\.\w+\.\w{1,3})/index.html$/patter gt lt;replace![CDATA[ /comments/all.castle?ul=$2 ]]/replace/rule/routing/monorailiBATISlogginglogFactoryAdapter type="IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, IBatisNet.Common.Logging.Log4Net"arg key="configType" value="file"/arg key="configFile" value="config/log4Net.config"//logFactoryAdapter/logging/iBATIS> lt ystem.we gt lt age enableViewState="false"/authenticatio mode="Forms"/trace enabled="false" requestLimit="10" ageOutput="false" traceMode="SortByTime" localOnly="true"/compilatio defaultLanguage="c#" debug="false"/compilatio gt lt;httpHandler gt lt;add verb="*" ath="*.castle"="Castle.MonoRail.Framework.MonoRailHttpHandlerFactory, Castle.MonoRail.Framework"/!-- lock direct user acce to template file --add verb="*" ath="*.vm" type="System.Web.HttpForbiddenHandler"/add verb="*" ath="*.vm" type="System.Web.HttpForbiddenHandler"/add verb="*" ath="*.njs" type="System.Web.HttpForbiddenHandler"/add verb="*" ath="*.brail" type="System.Web.HttpForbiddenHandler"/add verb="*" ath="*.brailjs" type="System.Web.HttpForbiddenHandler"//httpHandler gt lt;httpModule gt lt;add ame="routing" type="Castle.MonoRail.Framework.RoutingModule, Castle.MonoRail.Framework"/add ame="Compre ionModule" type="blowery.Web.HttpCompre .HttpModule, lowery.web.HttpCompre "/!-- Remove u ece ary Htt Module for faster ipeline --remove ame="WindowsAuthentication"/remove ame="Pa ortAuthentication"/remove ame="UrlAuthorization"/remove ame="FileAuthorization"//httpModule gt lt;/system.we gt lt;a Setting gt lt;add key="defaultR Ttl" value="10"/add key="r TempDir" value="./cache/"//a Setting gt lt;castleinclude uri="file://config/facilities.config"/include uri="file://config/components.config"/include uri="file://config/controllers.config"//castle!-- config ectio for my htt module --> lt lowery.we gt lt;!-- Here' a example o how to change the algorithm or compre io level lt;compre ionModule referredAlgorithm="deflate|gzip" compre ionLevel="high|normal|low"/ o, to use deflate y default, and high compre ion, you would use the following line
--httpCompre referredAlgorithm="gzip" compre ionLevel="high"!--excludedMimeType 包含的在此的Mime类型将不被压缩--excludedMimeType gt lt;add type="image/jpeg"/add type="image/gif"//excludedMimeType gt lt;!--excludedPath 包含的在此的a x将不被压缩--excludedPath gt lt;add ath="NoCompre .a x"//excludedPath gt lt;/httpCompre gt lt;/blowery.we gt;
/configuratio gt;
ContainerBLL.cs和GlobalA lication.cs文件,这俩文件存放与Web根目录下面
usingusingusing Castle.Facilities.AutomaticTra actionManagement;
using Castle.Facilities.IBatisNetIntegratio usingusingusing Castle.Windsor.Configuration.Interpreter usingusingusingusingusingname acepubliccla GlobalA licatio : HttpA lication, IContainerAcce or
privatestaticpublicIContainerAcce orpublicvoid=new WindsorContainer(new XmlInterpreter()); RegisterComponents(); }publicvoid///< ummary///////summary
protectedvoid{ container.AddComponent("TbBgCla Dao", typeof(ITbBgCla Dao), typeof(TbBgCla Dao)); container.AddComponent("TbBgCla BLL", typeof(TbBgCla BLL)); container.AddComponent("TbCommentDao", typeof(ITbCommentDao), typeof(TbCommentDao)); container.AddComponent("TbCommentBLL", typeof(TbCommentBLL)); container.AddComponent("TbInfoDao", typeof(ITbInfoDao), typeof(TbInfoDao)); container.AddComponent("TbInfoBLL", typeof(TbInfoBLL)); container.AddComponent("ITbMenuDao", typeof(ITbMenuDao), typeof(TbMenuDao)); container.AddComponent("TbMenuBLL", typeof(TbMenuBLL)); container.AddComponent("TbSiteConfigDao", typeof(ITbSiteConfigDao), typeof(TbSiteConfigDao)); container.AddComponent("TbSiteConfigBLL", typeof(TbSiteConfigBLL)); container.AddComponent("TbUserDao", typeof(ITbUserDao), typeof(TbUserDao)); container.AddComponent("TbUserBLL", typeof
usingusingusing Castle.Facilities.AutomaticTra actionManagement;
using Castle.Facilities.IBatisNetIntegratio usingusingusing Castle.Windsor.Configuration.Interpreter usingusingusingusingusingname acepublicsealedcla rivatestaticvolatile GlobalA licatio _global =nullprivatestaticobject _syncRoot =newprivatestaticvoid=newprivatestaticif (_global ==nulllockif (_global ==null) // double-check{ InitGlobalA lication(); }retur ublicstatic
posted on 2008-03-07 21:04 TeeBye 阅读(50) 评论(0) 编辑 收藏 所属分类: MyCode
[使用Ctrl+Enter键可以直接提交]该文被作者在 2008-03-07 21:08 编辑过
导航统计常用链接留言簿文章分类Monorail搜索
引文来源 ----------------------------
一键转贴,快速捕捉生活精彩,赢每周好礼!
( Tue, 1 Jul 2008 10:00:29 +0800 )
Description:
本页内容 数据层性能 技巧 1 返回多个结果集 技巧 2 分页的数据访问 技巧 3 连接池 技巧 4 ASP.NET 缓存 API 技巧 5 每请求缓存 技巧 6 后台处理 技巧 7 页输出缓存和代理服务器 技巧 8 运行 IIS 6.0(只要用于内核缓存) 技巧 9 使用 Gzi 压缩 技巧 10 服务器控件视图状态 小结 使用 ASP.NET 编写 We 应用程序的简单程度令人不敢相信正因为如此简单,所以很多开发人员就不会花时间来设计其应用程序的结构,以获得更好的性能了在本文中,我将讲述 10 个用于编写高性能 We 应用程序的技巧但是我并不会将这些建议仅局限于 ASP.NET 应用程序,因为这些应用程序只是 We 应用程序的一部分本文不作为对 We 应用程序进行性能调整的权威性指南 一整本书恐怕都无法轻松讲清楚这个问题请将本文视作一个很好的起点 成为工作狂之前,我原来喜欢攀岩在进行任何大型攀岩活动之前,我都会首先仔细查看指南中的路线,阅读以前游客提出的建议但是,无论指南怎么好,您都需要真正的攀岩体验,然后才能尝试一个特别具有挑战性的攀登与之相似,当您面临修复性能问题或者运行一个高吞吐量站点的问题时,您只能学习如何编写高性能 We 应用程序 我的个人体验来自在 Microsoft 的 ASP.NET 部门作为基础架构程序经理的经验,在此期间我运行和管理 www.ASP.NET,帮助设计社区服务器的结构,社区服务器是几个著名 ASP.NET 应用程序(组合到一个平台的 ASP.NET Forums.Text 和 Gallery)我确信有些曾经帮助过我的技巧对您肯定也会有所帮助 您应该考虑将应用程序分为几个逻辑层您可能听说过 3 层(或者 层)物理体系结构一词这些通常都是规定好的体系结构方式,将功能在进程和/或硬件之间进行了物理分离当系统需要扩大时,可以很轻松地添加更多的硬件但是会出现一个与进程和机器跳跃相关的性能下降,因此应该避免所以,如果可能的话,请尽量在同一个应用程序中一起运行 ASP.NET 页及其相关组件
因为代码分离以及层之间的边界,所以使用 We 服务或远程处理将会使得性能下降 20% 甚至更多
数据层有点与众不同,因为通常情况下,最好具有专用于数据库的硬件然而进程跳跃到数据库的成本依然很高,因此数据层的性能是您在优化代码时首先要考虑的问题
在深入应用程序的性能修复问题之前,请首先确保对应用程序进行剖析,以便找出具体的问题所在主要性能计数器(如表示执行垃圾回收所需时间百分比的计数器)对于找出应用程序在哪些位置花费了其主要时间也非常有用然而花费时间的位置通常非常不直观
本文讲述了两种类型的性能改善:大型优化(如使用 ASP.NET 缓存),和进行自身重复的小型优化这些小型优化有时特别有意思您对代码进行一点小小的更改,就会获得很多很多时间使用大型优化,您可能会看到整体性能的较大飞跃而使用小型优化时,对于某个特定请求可能只会节省几毫秒的时间,但是每天所有请求加起来,则可能会产生巨大的改善
数据层性能
谈到应用程序的性能调整,有一个试纸性的测试可用来对工作进行优先级划分:代码是否访问数据库?如果是,频率是怎样的?请注意,这一相同测试也可应用于使用 We 服务或远程处理的代码,但是本文对这些内容未做讲述
如果某个特定的代码路径中必需进行数据库请求,并且您认为要首先优化其他领域(如字符串操作),则请停止,然后执行这个试纸性测试如果您的性能问题不是非常严重的话,最好花一些时间来优化一下与数据库返回的数据量进出数据库的往返频率相关的花费时间
了解这些常规信息之后,我们来看一下可能会有助于提高应用程序性能的十个技巧首先,我要讲述可能会引起最大改观的更改
返回页首
技巧 1 返回多个结果集
仔细查看您的数据库代码,看是否存在多次进入数据库的请求路径每个这样的往返都会降低应用程序可以提供的每秒请求数量通过在一个数据库请求中返回多个结果集,可以节省与数据库进行通信所需的总时间长度同时因为减少了数据库服务器管理请求的工作,还会使得系统伸缩性更强
虽然可以使用动态 SQL 返回多个结果集,但是我首选使用存储过程关于业务逻辑是否应该驻留于存储过程的问题还存在一些争议,但是我认为,如果存储过程中的逻辑可以约束返回数据的话(缩小数据集的大小缩短网络上所花费时间,不必筛选逻辑层的数据),则应赞成这样做
使用 SqlCommand 实例及其 ExecuteReader 方法填充强类型的业务类时,可以通过调用 NextResult 将结果集指针向前移动图 1 显示了使用类型类填充几个 ArrayList 的示例会话只从数据库返回您需要的数据将进一步减少服务器上的内存分配
技巧 2 分页的数据访问
ASP.NET DataGrid 具有一个很好的功能:数据分页支持在 DataGrid 中启用分页时,一次会显示固定数量的记录另外,在 DataGrid 的底部还会显示分页 UI,以便在记录之间进行导航该分页 UI 使您能够在所显示的数据之间向前和向后导航,并且一次显示固定数量的记录
还有一个小小的波折使用 DataGrid 的分页需要所有数据均与网格进行绑定例如,您的数据层需要返回所有数据,那么 DataGrid 就会基于当前页筛选显示的所有记录如果通过 DataGrid 进行分页时返回了 100,000 个记录,那么针对每个请求会放弃 99,975 个记录(假设每页大小为 25 个记录)当记录的数量不断增加时,应用程序的性能就会受到影响,因为针对每个请求必须发送越来越多的数据
要编写性能更好的分页代码,一个极佳的方式是使用存储过程图 2 显示了针对 Northwind 数据库中的 Order 表进行分页的一个示例存储过程简而言之,您此时要做的只是传递页索引和页大小然后就会计算合适的结果集,并将其返回
在社区服务器中,我们编写了一个分页服务器控件,以完成所有的数据分页您将会看到,我使用的就是技巧 1 中讨论的理念,从一个存储过程返回两个结果集:记录的总数和请求的数据
返回记录的总数可能会根据所执行查询的不同而有所变化例如,WHERE 子句可用来约束返回的数据为了计算在分页 UI 中显示的总页数,必须了解要返回记录的总数例如,如果总共有 1,000,000 条记录,并且要使用一个 WHERE 子句将其筛选为 1000 条记录,那么分页逻辑就需要了解记录的总数才能正确呈现分页 UI
技巧 3 连接池
在 We 应用程序和 SQL Server? 之间设置 TCP 连接可能是一个非常消耗资源的操作Microsoft 的开发人员到目前为止能够使用连接池已经有一段时间了,这使得他们能够重用数据库连接他们不是针对每个请求都设置一个新的 TCP 连接,而是只在连接池中没有任何连接时才设置新连接当连接关闭时,它会返回连接池,在其中它会保持与数据库的连接,而不是完全破坏该 TCP 连接
当然,您需要小心是否会出现泄漏连接当您完成使用连接时,请一定要关闭这些连接再重复一遍:无论任何人对 Microsoft.NET Framework 中的垃圾回收有什么评论,请一定要在完成使用连接时针对该连接显式调用 Close 或 Di ose不要相信公共语言运行库 (CLR) 会在预先确定的时间为您清除和关闭连接尽管 CLR 最终会破坏该类,并强制连接关闭,但是当针对对象的垃圾回收真正发生时,并不能保证
要以最优化的方式使用连接池,需要遵守一些规则
首先打开连接,执行操作,然后关闭该连接如果您必须如此的话,可以针对每个请求多次打开和关闭连接(最好应用技巧 1),但是不要一直将连接保持打开状态并使用各种不同的方法对其进行进出传递
第二,使用相同的连接字符串(如果使用集成身份验证的话,还要使用相同的线程标识)如果不使用相同的连接字符串,例如根据登录的用户自定义连接字符串,那么您将无法得到连接池提供的同一个优化值如果您使用集成身份验证,同时还要模拟大量用户,连接池的效率也会大大下降尝试跟踪与连接池相关的任何性能问题时,.NET CLR 数据性能计数器可能非常有用
每当应用程序连接资源时,如在另一个进程中运行的数据库,您都应该重点考虑连接该资源所花时间发送或检索数据所花时间,以及往返的数量,从而进行优化优化应用程序中任何种类的进程跳跃都是获得更佳性能的首要一点
应用层包含了连接数据层将数据转换为有意义类实例和业务流程的逻辑例如社区服务器,您要在其中填充Forum 或 Threads集合,应用业务规则(如权限);最重要的是要在其中执行缓存逻辑
技巧 4 ASP.NET 缓存 API
编写应用程序代码行之前,一个首要完成的操作是设计应用层的结构,以便最大化利用 ASP.NET 缓存功能
如果您的组件要在 ASP.NET 应用程序中运行,则只需在该应用程序项目中包括一个 System.Web.dll 引用当您需要访问该缓存时,请使用 HttpRuntime.Cache 属性(通过 Page.Cache 和 HttpContext.Cache 也可访问这个对象)
对于缓存数据,有几个规则首先,如果数据可能会多次使用时,则这是使用缓存的一个很好的备选情况第二,如果数据是通用的,而不特定于某个具体的请求或用户时,则也是使用缓存的一个很好的备选情况如果数据是特定于用户或请求的,但是寿命较长的话,仍然可以对其进行缓存,但是这种情况可能并不经常使用第三,一个经常被忽略的规则是,有时可能您缓存得太多通常在一个 x86 计算机上,为了减少内存不足错误出现的机会,您会想使用不高于 800MB 的专用字节运行进程因此缓存应该有个限度换句话说,您可能能够重用某个计算结果,但是如果该计算采用 10 个参数的话,您可能要尝试缓存 10 个排列,这样有可能给您带来麻烦一个要求 ASP.NET 的最常见支持是由于过度缓存引起的内存不足错误,尤其是对于大型数据集
图 3 ASP.NET缓存
缓存有几个极佳的功能,您需要对它们有所了解首先,缓存会实现最近最少使用的算法,使得 ASP.NET 能够在内存运行效率较低的情况下强制缓存清除 - 从缓存自动删除未使用过的项目第二,缓存支持可以强制失效的过期依赖项这些依赖项包括时间密钥和文件时间经常会用到,但是对于 ASP.NET 2.0,引入了一个功能更强的新失效类型:数据库缓存失效它指的是当数据库中的数据发生变化时自动删除缓存中的项有关数据库缓存失效的详细信息,请参阅 MSDN?Magazine 2004 年 7 月的 Dino E osito Cutting Edge 专栏要了解缓存的体系结构,请参阅图 3
技巧 5 每请求缓存
在本文前面部分,我提到了经常遍历代码路径的一些小改善可能会导致较大的整体性能收益对于这些小改善,其中有一个绝对是我的最爱,我将其称之为每请求缓存
缓存 API 的设计目的是为了将数据缓存较长的一段时间,或者缓存至满足某些条件时,但每请求缓存则意味着只将数据缓存为该请求的持续时间对于每个请求,要经常访问某个特定的代码路径,但是数据却只需提取应用修改或更新一次这听起来有些理论化,那么我们来举一个具体的示例
在社区服务器的论坛应用程序中,页面上使用的每个服务器控件都需要个性化的数据来确定使用什么外观使用什么样式表,以及其他个性化数据这些数据中有些可以长期缓存,但是有些数据却只针对每个请求提取一次,然后在执行该请求期间对其重用多次,如要用于控件的外观
为了达到每请求缓存,请使用 ASP.NET HttpContext对于每个请求,都会创建一个 HttpContext 实例,在该请求期间从 HttpContext.Current 属性的任何位置都可访问该实例该 HttpContext 类具有一个特殊的 Item 集合属性;添加到此 Item 集合的对象和数据只在该请求持续期间内进行缓存正如您可以使用缓存来存储经常访问的数据一样,您也可以使用 HttpContext.Item 来存储只基于每个请求使用的数据它背后的逻辑非常简单:数据在它不存在的时候添加到 HttpContext.Item 集合,在后来的查找中,只是返回 HttpContext.Item 中的数据
技巧 6 后台处理
通往代码的路径应该尽可能快速,是吗?可能有时您会觉得针对每个请求执行的或者每 个请求执行一次的任务所需资源非常多发送电子邮件或者分析和验证传入数据就是这样的一些例子
剖析 ASP.NET Forum 1.0 并重新构建组成社区服务器的内容时,我们发现添加新张贴的代码路径非常慢每次添加新张贴时,应用程序首先需要确保没有重复的张贴,然后必须使用坏词筛选器分析该张贴,分析张贴的字符图释,对张贴添加标记并进行索引,请求时将张贴添加到合适的队列,验证附件,最终张贴之后,立即向所有订阅者发出电子邮件通知很清楚,这涉及很多操作
经研究发现,大多数时间都花在了索引逻辑和发送电子邮件上对张贴进行索引是一个非常耗时的操作,人们发现内置的 System.Web.Mail 功能要连接 SMYP 服务器,然后连续发送电子邮件当某个特定张贴或主题领域的订阅者数量增加时,执行 AddPost 功能所需的时间也越来越长
并不需要针对每个请求都进行电子邮件索引理想情况下,我们想要将此操作进行批处理,一次索引 25 个张贴或者每五分钟发送一次所有电子邮件我们决定使用以前用于对数据缓存失效进行原型设计的代码,这个失效是用于最终进入 Visual Studio® 2005 的内容的
System.Threading 命名空间中的 Timer 类非常有用,但是在 .NET Framework 中不是很有名,至少对于 We 开发人员来说是这样创建之后,这个 Timer 类将以一个可配置的间隔针对 ThreadPool 中的某个线程调用指定的回调这就表示,您可以对代码进行设置,使其能够在没有对 ASP.NET 应用程序进行传入请求的情况下得以执行,这是后台处理的理想情况您还可以在此后台进程中执行如索引或发送电子邮件之类的操作
但是,这一技术有几个问题如果应用程序域卸载,该计时器实例将停止触发其事件另外,因为 CLR 对于每个进程的线程数量具有一个硬性标准,所以可能会出现这样的情形:服务器负载很重,其中计时器可能没有可在其基础上得以完成的线程,在某种程度上可能会造成延迟ASP.NET 通过在进程中保留一定数量的可用线程,并且仅使用总线程的一部分用于请求处理,试图将上述情况发生的机会降到最低但是,如果您具有很多异步操作时,这可能就是一个问题了
这里没有足够的空间来放置该代码,但是您可以下载一个可以看懂的示例,网址是 www.rob-howard.net请了解一下 Blackbelt TechEd 2004 演示中的幻灯片和演示
技巧 7 页输出缓存和代理服务器
ASP.NET 是您的表示层(或者说应该是您的表示层);它由页用户控件服务器控件(HttpHandler 和 HttpModules)以及它们生成的内容组成如果您具有一个 ASP.NET 页,它会生成输出(HTMLXML图像或任何其他数据),并且您针对每个请求运行此代码时,它都会生成相同的输出,那么您就拥有一个可用于页输出缓存的绝佳备选内容
将此行内容添加页的最上端 %@ Page OutputCache VaryByParams="none" Duration="60" %> 就可以高效地为此页生成一次输出,然后对它进行多次重用,时间最长为 60 秒,此时该页将重新执行,输出也将再一次添加到 ASP.NET 缓存通过使用一些低级程序化 API 也可以完成此行为对于输出缓存有几个可配置的设置,如刚刚讲到的 VaryByParam 属性VaryByParam 刚好被请求到,但还允许您指定 HTTP GET 或 HTTP POST 参数来更改缓存项例如,只需设置 VaryByParam="Report" 即可对 default.a x?Report=1 或 default.a x?Report=2 进行输出缓存通过指定一个以分号分隔的列表,还可以指