??xml version="1.0" encoding="utf-8" standalone="yes"?>BlogJava-JAVA学习W记http://www.dentisthealthcenter.com/lingy/zh-cnThu, 07 Dec 2023 17:31:21 GMTThu, 07 Dec 2023 17:31:21 GMT60vim 替换http://www.dentisthealthcenter.com/lingy/archive/2012/05/09/377726.html林光?/dc:creator>林光?/author>Wed, 09 May 2012 09:28:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2012/05/09/377726.html:%s/143250/143120/g

http://www.linux521.com/2009/system/201106/15135_2.html 

]]>
[端口被占?环境起不来]常见试环境问题解决http://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369065.html林光?/dc:creator>林光?/author>Tue, 31 Jan 2012 03:29:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369065.html大家是否遇到部v环境的时?端口被占?环境起不来的问题呢?遇到q个情况,我们该如何解军_Q?/span>

下面我把我遇到这个问题解决的Ҏȝ下:

现象是这L:

1. 面讉K出现: Http 500

2. 后台启动日志提示: 

vodka init successfully!!! ...

start apache ......

(98)Address already in use: make_sock: could not bind to address [::]:5071

no listening sockets available, shutting down

Unable to open logs

解决Ҏ: 杀掉占用的q程

首先,需要用root账号登陆,登陆?输入: netstat -plan |grep 5070

出现如下:


[Intranet root@qa-kernal-143-41 /root]

#netstat -plan |grep 5070

tcp 0 0 :::5070 :::* LISTEN 28002/httpd 

tcp 1 0 ::ffff:10.20.143.41:5070 ::ffff:10.16.46.75:4654 CLOSE_WAIT 28406/httpd 

最后杀掉占用的q程,输入:   lsof -i:5070 卛_ (?070是端口号)

[Intranet root@qa-kernal-143-41 /root]

#lsof -i:5070

]]>
linux用户l相关知?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369064.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Tue, 31 Jan 2012 03:28:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369064.html</guid><description><![CDATA[<span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">用root用户登陆输入命ocd /homeQ再用ll查看发现drwxr-xr-x 12 622   622    4096 Apr 18 19:21 aurora  aurora用户属主不正?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">用命令chown aurora.aurora aurora修改用户属主</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">知识点:</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">1.查看用户l信?cat /etc/passwd</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">/etc/passwd中一行记录对应着一个用P每行用冒号隔开分ؓ7个字D,具体字段说明如下Q?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(255,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">name:password:uid:gid:comment:home:shell<br style="outline-style: none" />用户?口o:用户标识?l标识号:注释性描q?ȝ?dShell</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">home: 指定用户的主目录的绝对\?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">shell: 用户登陆后启动的一个进E,q个q程是用L录到pȝ后运行的命o解释器或某个特定的程序,即Shell?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">例子Q?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">aurora:x:707:707::/home/aurora:/bin/bash</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">   pȝ首先会查?/etc/passwd 文gQ看是否有aurora q个账号Q然后确定aurora的UIDQ通过UID 来确认用户和w䆾Q?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">   如果存在则读?etc/shadow 影子文g中所对应的aurora的密码;  <span class="Apple-converted-space"> </span></span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">   用户名:xQuidQgidQ用户名全称Q用LӞ用户所用的shellcd</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">  x指向映射</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">uid? 则ؓroot  </span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">2.aurora:$1$nC4FzXJz$OP5LS0Evj4uMsLvMHP1eZ/:15082:0:99999:7:::</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">etc/shadow文g?etc/passwd 的媄子文Ӟq个文gq不?etc/passwd 而生的Q这两个文g是应该是对应互补的;</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">shadow内容包括用户及被加密的密码及其他/etc/passwd 不能包括的信息?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">用户Q密码:上次修改密码的时?Q两ơ修改口令间隔最的天数Q两ơ修改口令间隔最多的天数</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">3.aurora:x:707:</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">用户名:用户l密码:GID :用户列表</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">W四字段Q用户列表,每个用户之间?号分Ԍ本字D能为空Q?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">如果字段为空表示用户lؓGID的用户名</span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">4.chown 修改文g和文件夹的用户和用户l属?/span><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><br style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; outline-style: none; font: 14px/24px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" /><span style="widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; display: inline !important; font: 14px/24px Arial; white-space: normal; orphans: 2; float: none; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">5.passwd aurora 修改密码</span><img src ="http://www.dentisthealthcenter.com/lingy/aggbug/369064.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2012-01-31 11:28 <a href="http://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369064.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux之用L录环境变量分?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369057.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Tue, 31 Jan 2012 02:53:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369057.html</guid><description><![CDATA[<strong>昨天遇见一个问题,与大家分享一下。现象如下,当从一个用户切换到另外一个用戗或者直接登录的时候会出现如错误:bash-3.2</strong>  <p><strong>分析Q?/strong></p> <p><strong>而且bpmq个用户以前都是好的Qؓ什么呢Q我们来分析一下用Ld的一些原理就明白了:</strong></p> <p><strong>用户在刚dLinuxӞ步骤如下Q?/strong></p> <p><strong>1</strong><strong>、首先启?/etc/profile 文gQ?/strong></p> <p><strong>2</strong><strong>、然后再启动用户目录下的 ~/.bash_profile?~/.bash_login?~/.profile文g中的其中一个,</strong></p> <p><strong>执行的顺序ؓQ~/.bash_profile?~/.bash_login?~/.profile?如果 ~/.bash_profile文g存在的话Q一般还会执?~/.bashrc文g?/strong></p> <p><strong>因ؓ?~/.bash_profile文g中一般会有下面的代码:</strong></p> <p>if [ -f ~/.bashrc ] ; then</p> <p> . ./bashrc</p> <p>fi</p> <p> 因ؓ?~/.bash_profile文g中一般会有下面的代码Q?br />if [ -f ~/.bashrc ] ; then<br />. ./bashrc<br />fi<br />所以,~/.bashrc会调?/etc/bashrc文g?/p> <p><strong>3</strong><strong>、最后,在退出shellӞq会执行 ~/.bash_logout文g?/strong></p> <p><strong>所以一个用户从d到登出的执行序为:/etc/profile -> (~/.bash_profile | ~/.bash_login | ~/.profile) -> ~/.bashrc ->/etc/bashrc -> ~/.bash_logout</strong></p> <p><strong>当我们查看当前用L隐藏文g【ls -al】是否有q些文g的时候,q些文g都丢׃Q所以就会出现bash-3.2的错误。也是取不到当前登录用L变量D?/strong></p> <p><strong>备注Q关于各个文件的作用域,在网上找C以下说明Q?/strong></p> <p><strong>Q?Q?etc/profileQ?此文件ؓpȝ的每个用戯|环境信?当用L一ơ登录时,该文件被执行. q从/etc/profile.d目录的配|文件中搜集shell的设|?/strong></p> <p><strong>Q?Q?etc/bashrc: 为每一个运行bash shell的用h行此文g.当bash shell被打开?该文件被d?/strong></p> <p><strong>Q?Q~/.bash_profile: 每个用户都可使用该文件输入专用于自己使用的shell信息,当用L录时,该文件仅仅执行一?默认情况?他设|一些环境变?执行用户?bashrc文g?/strong></p> <p><strong>Q?Q~/.bashrc: 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell?该该文g被读取?/strong></p> <p><strong>Q?Q?/strong><strong><sub>/.bash_logout:当每ơ退出系l?退出bash shell)?执行该文? 另外,/etc/profile中设定的变量(全局)的可以作用于M用户,?/sub></strong><strong>/.bashrc{中讑֮的变?局?只能l承/etc/profile中的变量,他们?父子"关系?/strong></p> <p><strong>Q?Q?/strong><strong><sub>/.bash_profile 是交互式、login 方式q入 bash q行?/sub></strong><strong>/.bashrc 是交互式 non-login 方式q入 bash q行的通常二者设|大致相同,所以通常前者会调用后者?/strong></p> <p><strong> </strong></p> <p><strong>解决ҎQ?/strong></p> <p><strong> </strong> <strong>从正的环境copyq?/strong><strong>.bash_profile</strong><strong>?bashrc?bash_logout</strong><strong>三个文g中Q一丢失的文件到当前目录下面。让其生效即可?/strong></p> <p><strong>但ؓ什么这三个文g丢失我没有找到其丢失的原因,最Ҏ的猜就是大家不心删除了。另外linux的问题我个h的经验就是顺藤摸瓜、掌握原理之后就很多解决了!</strong></p><img src ="http://www.dentisthealthcenter.com/lingy/aggbug/369057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2012-01-31 10:53 <a href="http://www.dentisthealthcenter.com/lingy/archive/2012/01/31/369057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle DDL,DML,DCL,TCL 基础概念 http://www.dentisthealthcenter.com/lingy/archive/2010/08/17/329116.html林光?/dc:creator>林光?/author>Tue, 17 Aug 2010 08:50:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2010/08/17/329116.htmlDDL
Data Definition Language (DDL) statements are used to define the database structure or schema. Some examples:
  • CREATE - to create objects in the database
  • ALTER - alters the structure of the database
  • DROP - delete objects from the database
  • TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed
  • COMMENT - add comments to the data dictionary
  • RENAME - rename an object

DML

Data Manipulation Language (DML) statements are used for managing data within schema objects. Some examples:
  • SELECT - retrieve data from the a database
  • INSERT - insert data into a table
  • UPDATE - updates existing data within a table
  • DELETE - deletes all records from a table, the space for the records remain
  • MERGE - UPSERT operation (insert or update)
  • CALL - call a PL/SQL or Java subprogram
  • EXPLAIN PLAN - explain access path to data
  • LOCK TABLE - control concurrency

DCL

Data Control Language (DCL) statements. Some examples:
  • GRANT - gives user's access privileges to database
  • REVOKE - withdraw access privileges given with the GRANT command

TCL

Transaction Control (TCL) statements are used to manage the changes made by DML statements. It allows statements to be grouped together into logical transactions.
  • COMMIT - save work done
  • SAVEPOINT - identify a point in a transaction to which you can later roll back
  • ROLLBACK - restore database to original since the last COMMIT
  • SET TRANSACTION - Change transaction options like isolation level and what rollback segment to use


作者:李敬ӞGnieQ?br /> 出处Q?a >{GnieTech} Qhttp://www.cnblogs.com/gnielee/Q?br /> 版权声明Q本文的版权归作者与博客园共有。{载时L明本文的详细链接Q否则作者将保留q究其法律责仅R?/p>

]]>
linux 命ohttp://www.dentisthealthcenter.com/lingy/archive/2010/08/17/329113.html林光?/dc:creator>林光?/author>Tue, 17 Aug 2010 08:28:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2010/08/17/329113.html 

insert into ali_zeus_access_area
select * from ali_zeus_access_area@zeus_dev;

script -q tty.log

sqlplus /nolog
conn rnd/mCQe88il@crmintsb
conn rnd/mCQe88il@crmint


scp tty.log guangyan.lingy@10.20.130.14:/home/guangyan.lingy/tty0601.log

export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
sqlplus rnd/mCQe88il@crmg

for remote in \
172.16.131.47 172.16.131.48 172.16.131.49 172.16.131.50 172.16.131.51 172.16.131.52 172.16.131.53 172.16.131.54 172.16.131.55 172.16.131.2 172.16.131.3 172.16.131.4 172.16.131.5 172.16.131.6 172.16.131.7 172.16.131.41 172.16.131.42 172.16.131.56 172.16.131.57 172.16.131.58 \
;do echo $remote; ssh $remote "grep 'sms webService visitor IP is' output/logs/user/martini_sales_tool.log"; done

 

daisy.louy
 louying
 
 
carvin hello123
http://svn.alibaba-inc.com/repos/crm/martini/branches/20091209_dcs_guangyan.lingy_dev

weiming.shi
jinbo.yu
1234567890 alibaba-guest
我刚又试?/p>


中国的十大宜居小?中午的时候看?br /> http://focus.news.163.com/10/0531/09/680LGN5L00011SM9.html
有泉?)

数据模型资源手册

需要低烟无卤阻燃电~料的电~企?/p>

]]>
《设计模式》之Java解读--桥接Bridge http://www.dentisthealthcenter.com/lingy/archive/2010/07/29/327422.html林光?/dc:creator>林光?/author>Thu, 29 Jul 2010 05:56:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2010/07/29/327422.html阅读全文

]]>
无法定位E序输入点_except_handler4_common于动态链接库msvcrt.dll?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2010/07/05/325279.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Mon, 05 Jul 2010 06:12:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2010/07/05/325279.html</guid><description><![CDATA[<p>最q,多种软g都出C一个启动时的错误提C?“无法定位E序输入点_except_handler4_common于动态链接库msvcrt.dll?#8221;?/p> <p>出现q个提示情况是:Windows Xp pȝQ?软g包括Qwindow live writer 2009, windows messenger 2009, firefox 3.5 {非常新的版本?/p> <p>q个提示出现后,点击定Qƈ不媄响程序的使用。这个问题出现的原因Q其实微软自q问题。可谓是微Y的Vista 后遗症吧?/p> <p>?Vista pȝ里,有个挺酷的功能,是“E序~略?#8221;Q有?D效果Q这个功能,调用?dwmapi.dll q个库,?dwmapi.dll 又引用了 msvcrt.dll 中的 _except_handler4_common 功能?/p> <p>然而,在XPpȝ中,pȝ自带?msvcrt.dll  ?Vista 中的 msvcrt.dll 版本不同Q?q没有这?_except_handler4_common Q结果就出现了启动程序时Q遇到的 “无法定位E序输入点_except_handler4_common于动态链接库msvcrt.dll?#8221;的错误提C?/p> <p><strong>解决Ҏ</strong>Q?/p> <div class="content-sub-title">      ?c:\windows\system32 下的 dwmapi.dll 改名Q例如:改ؓ dwmapi.dll.bak?/div> <img src ="http://www.dentisthealthcenter.com/lingy/aggbug/325279.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2010-07-05 14:12 <a href="http://www.dentisthealthcenter.com/lingy/archive/2010/07/05/325279.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle 回滚 sql操作http://www.dentisthealthcenter.com/lingy/archive/2010/06/02/322585.html林光?/dc:creator>林光?/author>Wed, 02 Jun 2010 08:31:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2010/06/02/322585.html

]]>
Eclipse 启动q行速度调优 http://www.dentisthealthcenter.com/lingy/archive/2009/10/01/297077.html林光?/dc:creator>林光?/author>Thu, 01 Oct 2009 03:24:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/10/01/297077.html

JVM 提供了各U用于调整内存分配和垃圾回收行ؓ的标准开兛_非标准开兟뀂其中一些设|可以提?JAVA IDE 的性能?
注意Q由?-X Q尤其是 -XX JVMQ开关通常?JVM ?JVM 供应商特定的Q本部分介绍的开兛_用于 Sun Microsystems J2SE 1.4.2?/p>

以下讄在大多数pȝ上将产生比工厂更好的讄性能?
-vmargs - 表示后面的所有参数直接传递到所指示?Java VM?/p>

-Xverify:none - 此开兛_闭Java字节码验证,从而加快了c装入的速度Qƈ使得在仅为验证目的而启动的q程中无需装入cR此开关羃短了启动旉Q因此没有理׃使用它?

-Xms24m - 此设|指C?Java 虚拟机将其初始堆大小讄?24 MB。通过指示 JVM 最初应分配l堆的内存数量,可以?JVM 不必?IDE 占用较多内存时增加堆大小?

-Xmx96m - 此设|指?Java 虚拟机应对堆使用的最大内存数量。ؓ此数量设|上限表C?Java q程消耗的内存数量不得过可用的物理内存数量。对于具有更多内存的pȝ可以增加此限Ӟ96 MB 讄有助于确?IDE 在内存量?128MB ?256MB 的系l上能够可靠地执行操作。注意:不要该D|ؓ接近或大于系l的物理内存量,否则在主要回收q程中导致频J的交换操作?

-XX:PermSize=20m - ?JVM 开关不仅功能更为强大,而且能够~短启动旉。该讄用于调整内存"怹区域"Q类保存在该区域中)的大。因此我们向 JVM 提示它将需要的内存量。该讄消除了许多系l启动过E中的主要垃圾收集事件。SunONE Studio 或其它包含更多模块的 IDE 的用户可能希望将该数D|得更高?
下面列出了其它一些可能对 ECLIPSE 在某些系l(不是所有系l)上的性能产生d或明昑֪响的 JVM 开兟뀂尽用它们会产生一定的影响Q但仍值得一试?

-XX:CompileThreshold=100 - 此开兛_降低启动速度Q原因是与不使用此开关相比,HotSpot 能够更快地将更多的方法编译ؓ本地代码。其l果是提高了 IDE q行时的性能Q这是因为更多的 UI 代码被~译而不是被解释。该DC方法在被编译前必须被调用的ơ数?

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC - 如果垃圾回收频繁中断Q则请尝试用这些开兟뀂此开兛_?JVM 对主要垃圑֛收事Ӟ如果在多处理器工作站上运行,则也适用于次要回收事Ӟ使用不同的算法,q些法不会影响整个垃圾回收q程。注意:目前不定此收集器是提高还是降低单处理器计机的性能?

-XX:+UseParallelGC - 某些试表明Q至在内存配置相当良好的单处理器系l中Q用此回收法可以次要垃圑֛收的持箋旉减半。注意,q是一个矛盄问题Q事实上此回收器主要适用于具有千兆字节堆的多处理器。尚无可用数据表明它对主要垃圑֛收的影响。注意:此回收器?-XX:+UseConcMarkSweepGC 是互斥的?/p>

我的机器?12MB的内?br /> 下面是我的eclipse启动参数Qeclipse.exe -vmargs -Xverify:none -Xms64M -Xmx256M -XX:PermSize=20M  -XX:+UseParallelGC

-----

我的电脑?G内存, 有一ơ内存不了... MyEclipse 推荐我使用一个启动参? 现在我的启动参数?


eclipse.exe -vmargs -Xverify:none -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M -XX:+UseParallelGC



]]>
树结构和它的专用函数SYS_CONNECT_BY_PATHhttp://www.dentisthealthcenter.com/lingy/archive/2009/09/20/295773.html林光?/dc:creator>林光?/author>Sun, 20 Sep 2009 13:32:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/09/20/295773.html 关于树的普通应?br /> 学习了下q个函数, 用ORGINDUSTRIES的表做了个测?
正常的树型结?br /> select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=1
connect by pindid=prior indid
l果昄如下
                 Indlevel  indid    pindid
        服装与服?nbsp;              1             1             0
              服装               2             2               1
                    奌        3             3               2

倒型?br /> 下面q个例子是个”倒数”—倒过来的树型l构
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=20
connect by indid=prior pindid;
q是标准l果:
                             Indlevel indid    pindid
二手服装                      3        20       2
      服装                    2        2        1
            服装与服?nbsp;       1        1        0
l论
无论正树q是倒树, 关键在于connect by的条?
正树:  必须?nbsp; ‘?#8217;= prior ‘?#8217;
倒树:  必须?nbsp; ‘?#8217;= prior ‘?#8217;

树型l构的条件过?br /> 采用树型l构的话, 如果我们惛_树上的一个分支砍?  分支后面的l构都抛弃掉, q个可以实现麽?当然可以?但是不是用whereQ?where条g只能去除单一的条件?br /> 所以, q种树型的过滤条件就需要加在connect by上面?br />
试如下Q由于用真实环境比较贴近实际Q所以提前用下SYS_CONNECT_BY_PATH函数来显CZ环境

不加M条g的环境:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
start with areaname='中国大陆'
connect by parentareaid=prior areaid  

l果Q?br /> 1        中国大陆,中国大陆
2        北京        ,中国大陆,北京
3        北京        ,中国大陆,北京,北京
4        东城?nbsp;       ,中国大陆,北京,东城?br /> 5        西城?nbsp;       ,中国大陆,北京,西城?br /> 22        q东        ,中国大陆,q东
23        q州        ,中国大陆,q东,q州
24        汕尾        ,中国大陆,q东,汕尾
25        潮阳        ,中国大陆,q东,潮阳
46        上v        ,中国大陆,上v
47        上v        ,中国大陆,上v,上v
48        黄?nbsp;       ,中国大陆,上v,黄?br /> 49        闸北?nbsp;       ,中国大陆,上v,闸北?br />

加了whereqo条g的SQL:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中国大陆'
connect by parentareaid=prior areaid

l果为:
2        北京        ,中国大陆,北京
3        北京        ,中国大陆,北京,北京
4        东城?nbsp;       ,中国大陆,北京,东城?br /> 5        西城?nbsp;       ,中国大陆,北京,西城?br /> 22        q东        ,中国大陆,q东
23        q州        ,中国大陆,q东,q州
24        汕尾        ,中国大陆,q东,汕尾
25        潮阳        ,中国大陆,q东,潮阳
46        上v        ,中国大陆,上v
47        上v        ,中国大陆,上v,上v
48        黄?nbsp;       ,中国大陆,上v,黄?br /> 49        闸北?nbsp;       ,中国大陆,上v,闸北?br />
l论Q去掉了“1        中国大陆,中国大陆”数据

加了connect by的过滤条Ӟ
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中国大陆'
connect by parentareaid=prior areaid  and areaname<>'q东'

l果为:
2        北京        ,中国大陆,北京
3        北京        ,中国大陆,北京,北京
4        东城?nbsp;       ,中国大陆,北京,东城?br /> 5        西城?nbsp;       ,中国大陆,北京,西城?br /> 46        上v        ,中国大陆,上v
47        上v        ,中国大陆,上v,上v
48        黄?nbsp;       ,中国大陆,上v,黄?br /> 49        闸北?nbsp;       ,中国大陆,上v,闸北?br />
l论Q去掉了整个q东的分支,  在结果集中只有北京和上v


SYS_CONNECT_BY_PATH函数
采用SYS_CONNECT_BY_PATH函数?

select industry,sys_connect_by_path(industry,'/')
from ORGINDUSTRIES
start with indid=3
connect by indid=prior pindid;

l果?
奌               /奌
服装               /奌/服装
服装与服?nbsp;           /奌/服装/服装与服?br />
q样的话, 可以实? 树结构的l果集的单行拼接:

我们只需要取最大的字段OK?br />
试如下Q?br />
select max(sys_connect_by_path(industry,'/'))
from ORGINDUSTRIES
start with indid=3
connect by indid=prior pindid;

l果为:
/奌/服装/服装与服?br />

复杂的树型结构――多列变单列
树型l构也分单树和多?我的U呼,实际上就是指单支和多?
对于下面的这U情况, 我们必须要构造的树就属于单支树?br /> 原始环境
环境如下Q?br /> select * from testQ?br />
l果为:
1        n1
1        n2
1        n3
1        n4
1        n5
3        t1
3        t2
3        t3
3        t4
3        t5
3        t6
2        m1

造树
脚本如下Q?br /> select no,q,
       no+row_number() over( order by no) rn,
       row_number() over(partition by no order by no) rn1
from test

l果如下Q?br /> No  Q  RN RN1
1        n1        2        1
1        n2        3        2
1        n3        4        3
1        n4        5        4
1        n5        6        5
2        m1        8        1
3        t1        10        1
3        t2        11        2
3        t3        12        3
3        t4        13        4
3        t5        14        5
3        t6        15        6

每列的目的是Q?br /> RN1列主要的目的是分l, 按照value?#8216;1’Q我们可以start with使用它?br />
RN列主要用来做connect by使用?实际上它是我们要的树?br /> W一个支Q?2Q?Q?Q?Q?
W二个支Q?8
W三个支Q?10Q?1Q?2Q?3Q?4Q?5

中间Z么要断掉Q?,9  目的是Z区别每个分支?到后面看具体的SQLQ就明白q里的说法了?br />
杀手锏
既然我们有了树, 可以用树型函数SYS_CONNECT_BY_PATH和connect by啦,来拼接我们所需要的多列倹{?br />
脚本如下Q?br /> select no,sys_connect_by_path(q,',')
from (
select no,q,
       no+row_number() over( order by no) rn,
       row_number() over(partition by no order by no) rn1
from test
)
start with rn1=1
connect by rn-1=prior rn

l果为:
1        ,n1
1        ,n1,n2
1        ,n1,n2,n3
1        ,n1,n2,n3,n4
1        ,n1,n2,n3,n4,n5
2        ,m1
3        ,t1
3        ,t1,t2
3        ,t1,t2,t3
3        ,t1,t2,t3,t4
3        ,t1,t2,t3,t4,t5
3        ,t1,t2,t3,t4,t5,t6

l极武器
最l我们要的|是单列| 其实xQ?也就是最长的一行咯?那么好办了?我们直接GROUP BY Q然后取MAX倹{?br /> 脚本如下Q?br /> select no,max(sys_connect_by_path(q,','))
from (
select no,q,
       no+row_number() over( order by no) rn,
       row_number() over(partition by no order by no) rn1
from test
)
start with rn1=1
connect by rn-1=prior rn
group by no

l果为:
1        ,n1,n2,n3,n4,n5
2        ,m1
3        ,t1,t2,t3,t4,t5,t6

如果觉得前面?#8216;Q?#8217;不好看,可以使用ltrimL?或者用substr也可以?br /> 如下Q?br /> ltrim(max(sys_connect_by_path(q,',')),',')
或?br /> substr(max(sys_connect_by_path(q,',')),2)


]]>
vim 到指定行 :3305http://www.dentisthealthcenter.com/lingy/archive/2009/09/02/293577.html林光?/dc:creator>林光?/author>Wed, 02 Sep 2009 04:28:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/09/02/293577.html :number
eg:
:3305

]]>
Vim查找操作http://www.dentisthealthcenter.com/lingy/archive/2009/09/02/293576.html林光?/dc:creator>林光?/author>Wed, 02 Sep 2009 04:25:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/09/02/293576.html 

" 搜烦
/joe/e : 讄光标到匹?joe"的末?br /> /joe/e+1 : 讄光标到匹?joe"的末ֆ后移一?br /> /joe/s-2 : 讄光标到匹?joe“的开头再前移两位
/^joe.*fred.*bill/ : 匚w?j'开头且"joe"?fred"?bill"之间臛_有一个字W?br /> /^[A-J]\+/ : 搜烦'A'?#8217;J‘重复两次以上的开头行
/begin\_.*end : 多行匚w
/fred\_s*joe/i : 可以是Q何空白字W包括\n,\t{等
/fred\|joe : 搜烦fred或者joe
/.*fred\&.*joe : 搜烦同时包括fred跟joe的行
/\<fred\>/i : 搜烦独立的单词fred
/\<\d\d\d\d\> : 搜烦独立?位数?br /> /\D\d\d\d\d\D : 搜烦6位字W串中间4位数字前后两位不能ؓ数字
/\<\d\{4}\> : ?\<\d\d\d\d\>
" 查找I
/^\n\{3} : 匚w三连l的I
" 使用正则表达式组查找
/\(fred\).*\(joe\).*\2.*\1
" 正则表达式重?br /> /^\([^,]*,\)\{8}
" visual searching
:vmap // y/<C-R>"<CR> : visually模式下的键盘映射Q把//映射成匹配当前选中的文?br /> :vmap <silent> // y/<C-R>=escape(@", '\\/.*$^~[]')<CR><CR> : 包括I白字符
" \zs ?\ze 匚w?:h /\zs
/<\zs[^>]*\ze> : 匚w括号中的内?br /> " 零宽度匹?:h /\@=
/<\@<=[^>]*>\@= : search for tag contents, ignoring chevrons
/<\@<=\_[^>]*>\@= : search for tags across possible multiple lines
" 多行查找 \_ 的意思是包括换行W?br /> /<!--\_p\{-}--> : 匚w<!--开始到-->l尾的所有内?br /> /fred\_s*joe/i : 匚wfred开始到joeQ之间一定得是空白字W?br /> /bugs\(\_.\)*bunny : 匚w所有bugs到bunny的字W串
:h \_ : help
" 查找函数声明Qnmap为normal模式下的键盘映射
:nmap gx yiw/^\(sub\<bar>function\)\s\+<C-R>"<CR>
" 查找多个文g
:bufdo /searchstr/ : 在多个文件缓冲区里执行查?br /> " 更好的多文g查找定位Ҏ
:bufdo %s/searchstr/&/gic : 在多个文件缓冲区里查找,按下n停止
" 怎样不?/ 来查扄址
?
http://www.vim.org/ : 向后查找
" 查找指定字符以外的字W串
/\c\v([^aeiou]&\a){4} : 查找4个辅韛_?br /> ----------------------------------------
#替换
:%s/fred/joe/igc : 普通替换命?br /> :%s/\r//g : 删除 DOS 的换行符 ^M
" 你的文本文g是否׃八糟的排成一行?使用如下命o
:%s/\r/\r/g : 转换 DOS 回RW?^M 为真正的回RW?br /> :%s= *$== : 删除行尾I白
:%s= \+$== : 同上
:%s#\s*\r\?$## : 删除NI白和dos换行W?br /> :%s#\s*\r*$## : 同上
" 删除I
:%s/^\n\{3}// : 删除q箋3个空?br /> :%s/^\n\+/\r/ : 压羃IQ多个替换ؓ一?br /> %s#<[^>]\+>##g : 删除html的tag部分
" IF YOU ONLY WANT TO KNOW ONE THING
:'a,'bg/fred/s/dick/joe/igc : 非常有用
# 译释Q?'a,''b指定一个范_mark a ~ mark b
# g//用一个正则表辑ּ指出了进行操作的行必d以被fred匚w
# 看后面,g//是一个全局昄命o
# s/dick/joe/igc则对于这些满x件的行进行替?br /> " 复制?br /> :%s= [^ ]\+$=&&= : 复制最后一?br /> :%s= \f\+$=&&= : 一?br /> :%s= \S\+$=&& : 晕,q一P
" 记忆Q反向引用)
:s/\(.*\):\(.*\)/\2 : \1/ : 两个字D颠?br /> :%s/^\(.*\)\n\1$/\1/ : 删除重复?br /> " 非贪婪匹?\{-}
:%s/^.\{-}pdf/new.pdf/ : 删除W一个pdf
" use of optional atom \?
:%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc : lowercase with optional leading characters
" 跨越量多的?br /> :%s/<!--\_.\{-}-->// : 删除多行注释
:help /\{-} : 查看非贪婪匹配的更多帮助
" 使用寄存器替?br /> :s/fred/<c-r>a/g : fred替换为寄存器a里的内容
:s/fred/<c-r>asome_text<c-r>s/g
:s/fred/\=@a/g : better alternative as register not displayed
" 在一行里写多U命?br /> :%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/
:%s/a/but/gie|:update|:next : 当?@: 来重?br /> " 或运?br /> :%s/suck\|buck/loopy/gc : 替换suck或者buckQ这里|不是道Q?br /> " 调用vim函数
:s/__date__/\=strftime("%c")/ : __date__替换成当前日期,使用strftime函数
" 处理列,替换所有在W三列中的str1
:%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:
" 交换W一列跟W四?br /> :%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:
" qoform中的内容攑֜寄存器里
:redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END
:nmap ,z :redir @*<Bar>sil exec 'g@<\(input\<Bar>select\<Bar>textarea\<Bar>
/\=form\)\>@p'<Bar>redir END<CR>
" 两位以上的数字减三(带进位。这个命令挺有趣Q?br /> :%s/\d\+/\=(submatch(0)-3)/
" 包含loc或者functions的行中的数字?
:g/loc\|function/s/\d/\=submatch(0)+6/
" 比上面更好的Ҏ
:%s#txtdev\zs\d#\=submatch(0)+1#g
:h /\zs 查看帮助
" 前缀为gg的数字加6
:%s/\(gg\)\@<=\d\+/\=submatch(0)+6/
:h zero-width 查看帮助
" 替换一个特定字W串为数?br /> :let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1 # yy转换?0Q?1Q?2{等
" 比上面的更精?br /> :let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # xxyy 转换?xx11,xx12,
xx13
" find replacement text, put in memory, then use \zs to simplify substitute
:%s/"\([^.]\+\).*\zsxx/\1/
" Pull word under cursor into LHS of a substitute
:nmap <leader>z :%s#\<<c-r>=expand("<cword>")<cr>\>#
" Pull Visually Highlighted text into LHS of a substitute
:vmap <leader>z :<C-U>%s/\<<c-r>*\>/
----------------------------------------
" all following performing similar task, substitute within substitution
" Multiple single character substitution in a portion of line only
:%s,\(all/.*\)\@<=/,_,g : replace all / with _ AFTER "all/"
" Same thing
:s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')#
" Substitute by splitting line, then re-joining
:s#all/#&^M#|s#/#_#g|-j!
" Substitute inside substitute
:%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/
----------------------------------------
" 全局昄命o
:g/gladiolli/# : 查找q显C匹配的行号
:g/fred.*joe.*dick/ : 昄所有含?fred,joe & dick的行
:g/\<fred\>/ : 昄单一单词fred
:g/^\s*$/d : 删除所有空?br /> :g!/^dd/d : 删除不含字符?'dd''的行
:v/^dd/d : 同上
:g/fred/,/joe/d : 删除所有的从fred到joe
:g/-------/.-10,.d : ?------为标记删除之前的10?br /> :g/{/ ,/}/- s/\n\+/\r/g : 删除 {...}之间的空?br /> :v/\S/d : Delete empty lines (both types)
:v/./,/./-j : 压羃I
:g/^$/,/./-j : 同上
:g/<input\|<form/p : 或运?br /> :g/^/put_ : 双倍行?(pu = put)
:g/^/m0 : 颠倒文?(m = move)
:'a,'bg/^/m'b : 颠倒选中?a ?b
:g/^/t. : 重复?br /> :g/fred/t$ : 拯行从fred到结?br /> :g/stage/t'a : 拯行从stage ?marker aQa为标记的位置Q?br /> :g/\(^I[^^I]*\)\{80}/d : 删除最包?0个tab的行
" perform a substitute on every other line
:g/^/ if line('.')%2|s/^/zz /
" match all lines containing "somestr" between markers a & b
" copy after line containing "otherstr"
:'a,'bg/somestr/co/otherstr/ : co(py) or mo(ve)
" as above but also do a substitution
:'a,'bg/str1/s/str1/&&&/|mo/str2/
:%norm jdd : 隔行删除
" 增加数字 (键入 <c-a>)
:.,$g/^\d/exe "norm! \<c-a>": 增加从当前行首到l尾的数?br /> :'a,'bg/\d\+/norm! ^A : 增加数字
" 保存全局命o的结?(注意必须使用d模式) 你需要?qaq 清空寄存器a.
"save results to a register/paste buffer 存储l果?寄存?_脓 ?a
:g/fred/y A : d配备行到寄存器到 a
:g/fred/y A | :let @*=@a : 攑օ复制~冲?br /> :let @a=''|g/Barratt/y A |:let @*=@a
:'a,'b g/^Error/ . w >> errors.txt
" 复制每一行,然后在复制出来的每一行两侧加上一?print '复制出来的内?
:g/./yank|put|-1s/'/"/g|s/.*/Print '&'/
" 用文件中的内Ҏ换字W串Q?d 表示删除“标记”
:g/^MARK$/r tmp.ex | -d
" display prettily
:g/<pattern>/z#.5 : display with context
:g/<pattern>/z#.5|echo "==========" : display beautifully
" Combining g// with normal mode commands
:g/|/norm 2f|r* : replace 2nd | with a star
"send output of previous global command to a new window
:nmap <F3> :redir @a<CR>:g//<CR>:redir END<CR>:new<CR>:put! a<CR><CR>
----------------------------------------
" 全局命o和替换命令联?(强大的编辑能?
:'a,'bg/fred/s/joe/susan/gic : 可以使用反向引用来匹?br /> :g/fred/,/joe/s/fred/joe/gic : non-line based (ultra)
----------------------------------------
" 先找fredQ然后找joe
:/fred/;/joe/-2,/sid/+3s/sally/alley/gIC
----------------------------------------
" create a new file for each line of file eg 1.txt,2.txt,3,txt etc
:g/^/exe ".w ".line(".").".txt"
----------------------------------------
" Absolutely essential
----------------------------------------
* # g* g# : 查找当前光标下的单词Q单个单词) (<cword>) (向前/向后)
% : 匚w括号 {}[]()
. : 重复上次操作
@: : 重复上次的命?br /> matchit.vim : ?能匹?<script> <?php{标?br /> <C-N><C-P> : 插入模式下自动完成填?br /> <C-X><C-L> : 行自动完成(有用Q?br /> /<C-R><C-W> : 把单?lt;cword>单词攑օ搜烦或者命令行
/<C-R><C-A> : 把字W串中有的单?lt;CWORD>攑օ搜烦或者命令行
:set ignorecase : 忽略大小?br /> :syntax on : 打开语法高亮 Perl,HTML,PHP {等
:h regexp<C-D> : 按ctrl+d得到包含regexp的列?br /> (按tab自动不齐)
----------------------------------------
" 单编辑更?_vimrc文g
:nmap ,s :source $VIM/_vimrc :普通模式下的键盘映?,s映射成加载用L录下?br /> _vimrc文g
:nmap ,v :e $VIM/_vimrc :,v映射成打开_vimrc文g
----------------------------------------
#VISUAL 模式 (方便增加 HTML 标签)
:vmap sb "zdi<C-R>z<ESC> : ?VISUALLY模式下将选中的文本前后分别加?br /> :vmap st "zdi<?= <C-R>z ?><ESC> : 加上 <?= ?>
----------------------------------------
" 览
:Exp(lore) : 览文g
:Sex(plore) : 分割H口览文g
:ls : 昄~冲?br /> :cd .. : 讄当前目录位置
:args : 查看当前打开的所有文?br /> :lcd %:p:h : 改变路径到当前编辑的文g
:autocmd BufEnter * lcd %:p:h : 攑օ.vimrc自动完成上面的命?br /> ----------------------------------------
" ~冲区浏?一直排名前10的vim脚本)
" 需?bufexplorer.vim
http://www.vim.org/script.php?script_id=42
\be : ~冲览器中查看~冲列表
\bs : 同上Q但是分割窗?br /> ----------------------------------------
" 转换大小?br /> guu : 正行的字母转换成小?br /> gUU : 正行的字母转换成大?br /> Vu : 转换选中的行Q小写)
VU : 转换选中的行Q大写)
g~~ : 反向转换
vEU : 转换词大?br /> vE~ : 反向转换?br /> ggguG : 当前编辑文件内容全部{换成写
" Visually 模式下选择所有的字母及数?(攑օ .vimrc文g?
vmap ,c :s/\<\(.\)\(\k*\)\>/\u\1\L\2/g<CR>
" 大写所有句子的W一个字?br /> :%s/[.!?]\_s\+\a/\U&\E/g
----------------------------------------
gf : 打开当前光标下或后的文g
:nnoremap gF :view <cfile><cr> : 打开当前光标下或后的文g, 如果不存在则创徏
ga : 昄当前光标下单个字的ascii,十进Ӟ十六q制……
ggVGg? : 整个文件用rot13~码……Q谁看得懂啊~~hoho)
ggg?G : 同上 (针对大文?
:8 | normal VGg? : 第八行用rot13~码
:normal 10GVGg? : 同上
<C-A>,<C-X> : 增加Q减当前光标下的数?br /> win32 用户需要重定义 CNTRL-A
<C-R>=5*5 : 插入25 (型计算?
----------------------------------------
" 几个彩蛋……
:h 42 : also
http://www.google.com/search?q=42
:h holy-grail
:h!
----------------------------------------
" 标记 & Ud
'. : 跛_最后编辑的?(有?
`. : 同上Q但是定位编辑点
g; : 跌{到比较旧的编辑位|(如果有的话) (vim6.3后的新功?
g, : q个是较心的位置 (同上)
:changes :打出改变?br /> :h changelist : 查看“改变表蟩?#8221;的帮?br /> <C-O> : 依次沿着你的跌{记录向回?(从最q的一ơ开?
<C-I> : 依次沿着你的跌{记录向前?br /> :ju(mps) : 列出跌{轨迹
:help jump-motions
:history : 列出历史记录
:his c : 命o行历?br /> :his s : 搜烦历史
q/ : 搜烦命o历史的窗?br /> q: : 命o行命令历史的H口
:<C-F> : 历史H口
----------------------------------------
" ~写 & 映射
:map <f7> :'a,'bw! c:/aaa/x
:map <f8> :r c:/aaa/x
:map <f11> :.w! c:/aaa/xr<CR>
:map <f12> :r c:/aaa/xr<CR>
:ab php : 查看以php开头的~写
:map , : 列出所有的映射Q以逗号开始的Q?br /> " 允许映射 F10 (win32)
set wak=no : :h winaltkeys
" 映射中常使用的表C?br /> <CR> : 回R
<ESC> : Esc
<LEADER> : x?br /> <BAR> : 道W号
<BACKSPACE> : 退格键
<SILENT> : 不回?br /> #昄自定义的 RGB 颜色昄当前光标下的字符?例如 #445588
:nmap <leader>c :hi Normal guibg=#<c-r>=expand("<cword>")<cr><cr>
map <f2> /price only\\|versus/ :in a map need to backslash the \
----------------------------------------
" Simple PHP debugging display all variables yanked into register a
" 单的 PHP 调试所有显C的变量攑օ寄存器a
iab phpdb exit("<hr>Debug <C-R>a ");
----------------------------------------
" 使用寄存器来映射 (攑օ .vimrc文g自动加蝲)
:let @m=":'a,'bs/"
:let @s=":%!sort -u"
----------------------------------------
" 列出寄存?br /> :reg : 昄当前所有的寄存?br /> :reg a : 昄寄存器a中的内容
"1p.... : 引用一个叫1的寄存器
:let @y='yy@"' : pre-loading registers (put in .vimrc)
qqq : 清空寄存?"q"
----------------------------------------
" 一些有用的决窍
"ayy@a : 把当前行作ؓ命o执行
yy@" : 上面的匿名寄存器
u@. : 只执行键入的命o
----------------------------------------
" 从其它命令处获得输入Q需要外部命令)
:r!ls.exe : 从ls 获得输入插入到当前位|?br /> !!date : 从date获得输入Q删除当前行Q?br /> " 使用外部sort排序
:%!sort -u : 用sort排序整个文gQ结果覆盖整个文Ӟ
:'a,'b!sort -u : 从mark a到mark b之间的内容进行排?br /> !1} sort -u : 排序一个段?br /> :g/^$/;,/^$/-1!sort : Sort each block (note the crucial ;)
----------------------------------------
" 多文件管?(基本?
:bn : 跌{C一个buffer
:bp : 跌{到前一个buffer
:wn : 保存当前bufferq蟩转到下一个buffer (有?
:wp : 保存当前bufferq蟩转到前一个buffer
:bd : 把当前文件从bufferUd (有?
:bun : 卸蝲当前buffer (关闭q个H口但是不移?
:badd file.c : dfile.c到buffer列表
:b 3 : 前往W三?buffer
:b main : 前往含有main的buffer?比如?main.c
:sav php.html : 把当前文件存为php.htmlq打开
:sav! %<.bak : 换一个后~名保?(旧方?
:sav! %:r.cfm : 同上
:sav %:s/fred/joe/ : 替换文g?br /> :sav %:s/fred/joe/:r.bak2 : 替换文g和后~
:!mv % %:r.bak : 重命名当前文?br /> :e! : 打开未修改之前的文g
:w c:/aaa/% : 存储文g到指定位|?br /> :e # : ~辑标记?的文件在buffer?br /> :rew : q回到第一个可~辑的文?br /> :brew : 回到W一个buffer
:sp fred.txt : 分割H口打开fred.txt
:sball,:sb : 把所有的 buffers分割昄在一个窗口中 (有?
:scrollbind : in each split window
:map <F5> :ls<CR>:e # : 按F5昄所有buffer, q显C?br /> :set hidden : 允许不保存当前buffer而进行切?br /> ----------------------------------------
" 在分割窗口中快速切?br /> map <C-J> <C-W>j<C-W>_
map <C-K> <C-W>k<C-W>_
----------------------------------------
" 录制命o (最好的技?
qq # 录制命o攑օ q寄存?br /> 输入一些命?br /> q # 录制l束
@q :执行攑օ寄存器q中的内容
@@ Q重?br /> 5@@ Q重??br /> " ~辑一?寄存?录制
"qp :昄寄存器q中的内容(普通模式下)
<ctrl-R>q :昄寄存器q中的内容 (插入模式?
" 你现在可以看到记录内容,随便~辑
"qdd :删除Q重新存入q
@q :执行 录制/寄存?q
" 在可视块中运行记?br /> 1) 定义记录/寄存?br /> qq:s/ to/ from/g^Mq
2) 定义可视?br /> V}
3) 键入 : 显CZ面信?br /> :'<,'>
4)完成如下操作
:'<,'>norm @q
----------------------------------------
"combining a recording with a map (to end up in command mode)
nnoremap ] @q:w!<bar>bd
----------------------------------------
" 可视化模式提供一U灵zL用的Ҏ选择一块文本供操作W?br /> " 记出
v : q入可视化模?br /> V : q入可视化行选择模式
<C-V> : q入可视化块选择模式
gv : 重新选择
o : 选择的区域头?br /> "*y : 复制选择区域到paste buffer
V% : 选择一个匹配段
V}J : 合ƈ一个段?br /> V}gJ : 合ƈ一个段落,q保留空?br /> ----------------------------------------
" 删除选中?0行的前两个字W(不过q里应该假设是紧凑的排版格式Q不能包含空根{?br /> tab{字W的Q可是经实验应该是钱3个字W才对啊Q?Q?br /> 0<c-v>10j2ld
----------------------------------------
" 如何用可视块拯几列
" 可视?q通常?v 命o)
<C-V>Q然后通过Ud命o选择?(win32 <C-Q>)
然后执行 c,d,y,r {命?br /> ----------------------------------------
" how to overwrite a visual-block of text with another such block
Pick the first block: ctrl-v move "ay
Pick the second block: ctrl-v move c ctrl-o "aP <esc>
----------------------------------------
" _vimrc 基本讄
:set incsearch : 输入搜烦命oӞ立即昄目前输入的模式对应的匚w。匹配的字符?br /> 被高亮?br /> :set wildignore=*.o,*.obj,*.bak,*.exe : tab补全时忽略这些忽略这?br /> :set shiftwidth=3 : 讄自动~进?个字W?br /> :set vb t_vb=". : 安静模式Q关闭响铃跟闪烁
:set browsedir=buffer : 讄文g览使用的目?br /> “注:
”last 使用文g览器最q访问相同的目录?br /> “buffer 使用相关~冲区的目录?br /> ”current 使用当前目录?br /> “{path} 使用指定目录?br /> ----------------------------------------
" 启动windows中的IE
:nmap ,f :update<CR>:silent !start c:\progra~1\intern~1\iexplore.exe
file://%:p<CR>
:nmap ,i :update<CR>: !start c:\progra~1\intern~1\iexplore.exe <cWORD><CR>
----------------------------------------
" 在vim里打开ftp
cmap ,r :Nread
ftp://209.51.134.122/public_html/index.html
cmap ,w :Nwrite ftp://209.51.134.122/public_html/index.html
gvim ftp://www.somedomain.com/index.html # 使用 netrw.vim
----------------------------------------
" 向寄存器中添加内?(使用相应寄存器名U的大写)
" 复制5行放入a寄存器,然后向下跌{10行再复制5?br /> "a5yy
10j
"A5yy
----------------------------------------
[I : 昄当前行中字符的所有匹?有用)
----------------------------------------
" 常规~进
:'a,'b>> Q将mark a到mark b之间的内容进行两ơ羃q?br /> " 虚拟模式下羃q?(可重?
:vnoremap < <gv
”q是一个虚拟模式下的键盘映?< 映射?lt;gv
"< 意ؓ向内~进Qgv 上面已有解释Qؓ重复上次选区
“<gv 也就是先向内~进然后再选择刚才的选区
“q样可以只?< 实现重复~进?br /> :vnoremap > >gv Q向内羃q,原理同上
" 块羃q?br /> >i{
>a{
" also
>% and <%
”自己试试看吧Q涉及到?{ 的语a很有用,比如c,c++{?br /> ----------------------------------------
" 重定?& _脓到寄存器 * Q?为寄存器名称Q?br /> :redir @* : 重定向命令到paste~冲?br /> :redir END : l束
:redir >> out.txt : 重定向到文g
" 操作_脓~冲?br /> "*yy : 复制到寄存器
"*p : 从寄存器中粘贴一?br /> " 复制到粘贴缓冲区 (扩展模式)
:'a,'by* : 复制一个范围到_脓寄存?br /> :%y* : 复制一个括号匹配到_脓~冲?br /> :.y* : 复制当前行到_脓~冲?br /> " 从剪贴板上过滤非可打印字W?br /> " 当从一?GUI E序_脓时会有用?br /> :nmap <leader>p :let @* = substitute(@*,'[^[:print:]]','','g')<cr>"*p
----------------------------------------
" 重新格式化文?br /> gq} : 合ƈ一个段?br /> gqap : 当前D落
ggVGgq : 全部D落
Vgq : 当前?br /> " ?0列的时候换?br /> :s/.\{,69\};\s*\|.\{,69\}\s\+/&\r/g
----------------------------------------
" 命o使用于多个文?br /> :argdo %s/foo/bar/e : 在所有文件上操做 :args
:bufdo %s/foo/bar/e
:windo %s/foo/bar/e
:argdo exe '%!sort'|w! : 包含外部命o
----------------------------------------
" 命o行技?br /> gvim -h : 昄帮助
ls | gvim - : 道操作
cat xx | gvim - -c "v/^\d\d\|^[3-9]/d " : 从管道出qo内容
gvim -o file1 file2 : 分割H口昄两个文g
" 打开文g后执行一条命?br /> gvim.exe -c "/main" joe.c : 打开 joe.c & 跌{?"main"
" 在打开一个文件时执行多条命o
vim -c "%s/ABC/DEF/ge | update" file1.c
" 在一l文件上执行多条命o
vim -c "argdo %s/ABC/DEF/ge | update" *.c
" 从一pd文g中删除一块区?br /> vim -c "argdo /begin/+1,/end/-1g/^/d | update" *.c
" 自动~辑文g (~辑命o序列Ex commands已经包含在convert.vim中了)
vim -s "convert.vim" file.c
#不加?vimrc跟Q何plugin(q净清新?VIM^_^)
gvim -u NONE -U NONE -N
" Access paste buffer contents (put in a script/batch file)
gvim -c 'normal ggdG"*p' c:/aaa/xp
" paste中的内容送往默认的打印机
gvim -c 's/^/\=@*/|hardcopy!|q!'
" gvim 里的 grep (win32 or *nix)
:grep somestring *.php : 创徏匚w的文件列?br /> " 使用 :cn(向后? :cp(向前) 操纵列表
:h grep Q查看帮?br /> ----------------------------------------
" GVIM 的差异比?br /> gvim -d file1 file2 : vimdiff (比较不差?
dp : 把光标处的不同放到另一个文?br /> do : 在光标处从另一个文件取得不?br /> ----------------------------------------
" Vim traps
在正则表辑ּ?+ | ( { 都要加上转义W?反斜?
/fred\+/ : 匚w fred/freddy 但不匚w free
/\(fred\)\{2,3}/ : note what you have to break
----------------------------------------
" \v Q或叫做very magic (通常都是q么?可以取消转义W?br /> /codes\(\n\|\s\)*where : 普通的正则表达?br /> /\vcodes(\n|\s)*where : very magic
----------------------------------------
" 把对象送到命o行或者搜索行
<C-R><C-W> : 执行当前光标下的单个单词
<C-R><C-A> : 执行当前光标下尽可能多的单词
<C-R>- : 送至一个小型寄存器Q同样用于插入模式Q?br /> <C-R>[0-9a-z] : 送至一个命名寄存器 (括弧同上)
<C-R>% : 送至文g?#也行) (同上)
<C-R>=somevar : 送至一个变?(例如 :let sray="ray[0-9]")
----------------------------------------
" 控制寄存?br /> :let @a=@_ : 清除寄存?a
:let @a="" : 同上 a
:let @*=@a : 拯寄存?a ?paste buffer
:let @*=@: : 拯最后执行的命o?paste buffer
:let @*=@/ : 拯最后执行的查找命o到paste buffer
:let @*=@% : 拯当前文g?paste buffer

map <f11> "qyy:let @q=@q."zzz"
----------------------------------------
" 帮助的帮助? (使用 TAB)
:h quickref : VIM 快速参考页
:h tips : Vim'自己的技巧帮?br /> :h visual<C-D><tab> : 虚拟模式的帮助列?br /> : 然后使用tab选择它们
:h ctrl<C-D> : 所有关于ctrl键的帮助列表
:helpg uganda : qo帮助文g 使用 :cn, :cp 查找下一个及后一?br /> :h :r : 关于 :ex 的命令帮?br /> :h CTRL-R : 普通模式相?br /> :h /\r : \r是什么的意?br /> :h \\zs : 使用双反斜线查找关于 \zs 的帮?br /> :h i_CTRL-R : 在插入模式中 <C-R>的解?br /> :h c_CTRL-R : 在命令模式中 <C-R> 的解?br /> :h v_CTRL-V : 虚拟模式
:h tutor : VIM 快速指?br /> <C-[>, <C-T> : Move back & Forth in HELP History
gvim -h : VIM 命o行帮?br /> ----------------------------------------
" 选项讄在那?br /> :scriptnames : 列出所有已l加载的 plugins, _vimrcs文g
:verbose set history? :昄 history的值ƈ昄在那里定义的
:function : 列出所有函?br /> :func SearchCompl : 昄指定函数的细?br /> ----------------------------------------
" 制作你自qVIM 帮助
:helptags /vim/vim64/doc : 重新~译所?*.txt 的帮助文件在q个目录?br /> :help add-local-help Q如何添加本地帮?br /> ----------------------------------------
" 用外部程序运行文?(例如 php)
map <f9> :w<CR>:!c:/php/php.exe %<CR>
map <f2> :w<CR>:!perl -c %<CR>
----------------------------------------
" 在另一个buffer中,捕捉当前脚本的输?br /> :new | r!perl # : 新徏一个bufferQ从另一个buffer中读入结?br /> :new! x.out | r!perl # : 同上Qƈ指定一个新文g?br /> :new+read!ls
----------------------------------------
" create a new buffer, paste a register "q" into it, then sort new buffer
:new +put q|%!sort
----------------------------------------
" 插入DOS换行W?br /> :%s/$/\<C-V><C-M>&/g : (that's what you type
:%s/$/\<C-Q><C-M>&/g : for Win32) 对于Win32应该q样
:%s/$/\^M&/g : 你看到的^M是一个字W?br /> ----------------------------------------
" 自动删除行尾 Dos回RW和I格
autocmd BufRead * silent! %s/[\r \t]\+$//
autocmd BufEnter *.php :%s/[ \t\r]\+$//e
----------------------------------------
" Ҏ定文件或文gcd执行某个动作
autocmd VimEnter c:/intranet/note011.txt normal! ggVGg?
autocmd FileType *.pl exec('set fileformats=unix')
----------------------------------------
" 把最后一个命令脓到当前位|?br /> i<c-r>:
" 把最后一个搜索指令脓到当前位|?br /> i<c-r>/
----------------------------------------
" 更多的完成功?br /> <C-X><C-F> :插入当前目录下的一个文件名到当前位|?br /> # 在insert模式下?br /> # 然后?Ctrl-P/Ctrl-N 页
----------------------------------------
" 替换一个visual区域
" 选择一个区域,然后输入 :s/Emacs/Vim/ {等Qvim会自动进?模式
:'<,'>s/Emacs/Vim/g : 前面? '<.'> 是vim自动d?br /> gv : 重新选择前一个可视区?(ULTRA)
----------------------------------------
" 在文件中插入行号
:g/^/exec "s/^/".strpart(line(".")." ", 0, 4)
:%s/^/\=strpart(line(".")." ", 0, 5)
:%s/^/\=line('.'). ' '
----------------------------------------
#用VIM的方式来~号?br /> :set number : 昄行号
:map <F12> :set number!<CR> : Show linenumbers flip-flop
:%s/^/\=strpart(line('.')." ",0,&ts)
#从Q意行开始编?需要perl)
:'a,'b!perl -pne 'BEGIN{$a=223} substr($_,2,0)=$a++'
#产生数字列表
#Type in number on line say 223 in an empty file
qqmnYP`n^Aq : in recording q repeat with @q
" 递增已存在数字到文g?br /> :.,$g/^\d/exe "normal! \<c-a>"
" 高递增Q参见:
http://vim.sourceforge.net/tip_view.php?tip_id=150
----------------------------------------
" 高递增 (真的很有?
" 把下面几句放?_vimrc
let g:I=0
function! INC(increment)
let g:I =g:I + a:increment
return g:I
endfunction
" 例如从mark a 到mark b 递增Q从223开始,步长?
:let I=223
:'a,'bs/^/\=INC(5)/
" create a map for INC
cab viminc :let I=223 \| 'a,'bs/$/\=INC(5)/
----------------------------------------
" 生成?23-64 的数字列?br /> o23<ESC>qqYp<C-A>q40@q
----------------------------------------
" 在当前插入模式下~辑/Ud (真得很有?
<C-U> : 删除全部
<C-W> : 删除最后一个单?br /> <HOME><END> : Ud到行?行尾
<C-LEFTARROW><C-RIGHTARROW> : 向前/后移动一个单?br /> <C-X><C-E>,<C-X><C-Y> : scroll while staying put in insert
----------------------------------------
#加密(心使用Q不要忘了密?
:X : vim会提CZ输入密码
:h :X
----------------------------------------
" 模式?(使文件只ȝ)Q必d??5行内
// vim:noai:ts=2:sw=4:readonly:
" vim:ft=html: : 使用 HTML 语法高亮
:h modeline
----------------------------------------
" 建立你自q菜单?br /> amenu Modeline.Insert\ a\ VIM\ modeline <Esc><Esc>ggOvim:ff=unix ts=4 ss=4<CR>
vim60:fdm=marker<esc>gg
----------------------------------------
" 一个保存当前光标下的狭义字C个文件的函数
function! SaveWord()
normal yiw
exe ':!echo '.@0.' >> word.txt'
endfunction
map ,p :call SaveWord()
----------------------------------------
" 删除重复行的函数
function! Del()
if getline(".") == getline(line(".") - 1)
norm dd
endif
endfunction

:g/^/ call Del() #使用该函数的一个例?br /> ----------------------------------------
" 双字节编?(non alpha-numerics)
:digraphs : 昄~码?br /> :h dig : 帮助
i<C-K>e' : 输入 é
i<C-V>233 : 输入 é (Unix)
i<C-Q>233 : 输入 é (Win32)
ga : 查看字符的hex?br /> #删除?ascii 字符
:%s/[<C-V>128-<C-V>255]//gi : where you have to type the Control-V
:%s/[?-?]//gi : Should see a black square & a dotted y
:%s/[<C-V>128-<C-V>255<C-V>01-<C-V>31]//gi : All pesky non-asciis
:exec "norm /[\x00-\x1f\x80-\xff]/" : same thing
#Pull a non-ascii character onto search bar
yl/<C-R>" :
/[^a-zA-Z0-9_[:space:][:punct:]] : search for all non-ascii
----------------------------------------
" 文g名自动完?(例如 main_c.c)
:e main_<tab> : tab 键完?br /> gf : 打开光标处广义字命名的文?(normal模式)
main_<C-X><C-F> : 文g名自动完?insert模式)
----------------------------------------
" Vim复杂使用
" 交换两个单词
:%s/\<\(on\|off\)\>/\=strpart("offon", 3 * ("off" == submatch(0)), 3)/g
" 交换两个单词
:vnoremap <C-X> <Esc>`.``gvP``P
----------------------------------------
" 把text文g转换成html文g(oh,ft)
:runtime! syntax/2html.vim : 转换 txt ?html
:h 2html
----------------------------------------
" VIM 有一个内部自带的 grep 命o
:grep some_keyword *.c : 得到一个包含some_keyword的c文g名列?br /> :cn : M一个出现的位置
----------------------------------------
" 强制无扩展名的文件的语法着色方?br /> :set syntax=perl
" 取消语法着?(很有?
:set syntax off
" 改变色彩主题 (在~vim/vim??/colors中的M文g)
:colorscheme blue
" 通过使用模式行强q?HTML 语法高亮
# vim:ft=html:
" 强制自动语法加亮(非标准的文g扩展)
au BufRead,BufNewFile */Content.IE?/* setfiletype html
----------------------------------------
:set noma (non modifiable) : 防止修改
:set ro (Read Only) : 只读保护
----------------------------------------
" 对话 (打开一堆文?
gvim file1.c file2.c lib/lib.h lib/lib2.h : ?对话"中加载这些文?br /> :mksession : 生成一个Session文g (默认是Session.vim)
:q
gvim -S Session.vim : 重新加蝲所有文?br /> ----------------------------------------
#标记(tags) (跌{到子E序/函数)
taglist.vim : 很流行的插g
:Tlist : 昄标记 (函数列表)
<C-]> : 跌{到光标处的函?br /> ----------------------------------------
" columnise a csv file for display only as may crop wide columns
:let width = 20
:let fill=' ' | while strlen(fill) < width | let fill=fill.fill | endwhile
:%s/\([^;]*\);\=/\=strpart(submatch(1).fill, 0, width)/ge
:%s/\s\+$//ge
" Highlight a particular csv column (put in .vimrc)
function! CSVH(x)
execute 'match Keyword /^\([^,]*,\)\{'.a:x.'}\zs[^,]*/'
execute 'normal ^'.a:x.'f,'
endfunction
command! -nargs=1 Csv :call CSVH(<args>)
" call with
:Csv 5 : highlight fifth column
----------------------------------------
" 折叠Q隐藏某些片断,使查看更Ҏ
zf} : 使用动作命o折叠一个段?br /> v}zf : 使用可视模式折叠一个段?br /> zf'a : 折叠C个标C
zo : 打开折叠
zc : 重新关闭折叠
----------------------------------------
" 昄"不可见字W?
:set list
:h listchars
----------------------------------------
" 如何在不q入插入模式的情况下_脓"普通模式的命o"
:norm qqy$jq
----------------------------------------
" 处理文g?br /> :h filename-modifiers : 帮助
:w % : 写入当前文g
:w %:r.cfm : 改变文g扩展名ؓ .cfm
:!echo %:p : 昄完整路径和文件名
:!echo %:p:h : 只显C完整\?br /> :!echo %:t : 只显C文件名
:reg % : 昄文g?br /> <C-R>% : 插入文g?(插入模式)
"%p : 插入文g?(普通模?
/<C-R>% : 在文本中查找文g?br /> ----------------------------------------
" 删除Q但不破?buffer 内容
"_d : 你一直想要的东西
"_dw : 例如Q删除一个单?(使用黑洞???)
----------------------------------------
" 送完整的路径名到剪脓板,用于邮g附g{?br /> nnoremap <F2> :let @*=expand("%:p")<cr> :unix
nnoremap <F2> :let @*=substitute(expand("%:p"), "/", "\\", "g")<cr> :win32
----------------------------------------
" 不用d Vim p修改文g名的?shell 脚本
$ vim
:r! ls *.c
:%s/\(.*\).c/mv & \1.bla
:w !sh
:q!
----------------------------------------
" 在一个文本里计算单词?br /> g<C-G>
----------------------------------------
" 你自p|高亮显C的例子
:syn match DoubleSpace " "
:hi def DoubleSpace guibg=#e0e0e0
----------------------------------------
" reproduce previous line word by word
imap ] @@@<ESC>hhkyWjl?@@@<CR>P/@@@<CR>3s
nmap ] i@@@<ESC>hhkyWjl?@@@<CR>P/@@@<CR>3s
" Ҏ文gcd映射快捷?br /> :autocmd bufenter *.tex map <F1> :!latex %<CR>
:autocmd bufenter *.tex map <F2> :!xdvi -hush %<.dvi&<CR>
----------------------------------------
" d MS-Word 文Q需?antiword
:autocmd BufReadPre *.doc set ro
:autocmd BufReadPre *.doc set hlsearch!
:autocmd BufReadPost *.doc %!antiword "%"
----------------------------------------
" a folding method
vim: filetype=help foldmethod=marker foldmarker=<<<,>>>
A really big section closed with a tag <<<
--- remember folds can be nested ---
Closing tag >>>
----------------------------------------
" Just Another Vim Hacker JAVH
vim -c ":%s%s*%Cyrnfr)fcbafbe[Oenz(Zbbyranne%|:%s)[[()])-)Ig|norm Vg?"
# 译释Q呵呵,谁来解释一下吧Q?br /> # 其实不过是在启动vim的时候执行了一个命?br /> # 先写入了 Just Another Vim Hacker 的rot13~码
# 然后再解?/font>



]]>
vim 昄行号、语法高亮、自动羃q的讄http://www.dentisthealthcenter.com/lingy/archive/2009/09/02/293574.html林光?/dc:creator>林光?/author>Wed, 02 Sep 2009 04:24:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/09/02/293574.html在Ubuntu中vim的配|文件存攑֜/etc/vim目录中,配置文g名ؓvimrc

在Fedora中vim的配|文件存攑֜/etc目录中,配置文g名ؓvimrc

在终?输入以下命o来编辑vimrc配置文gQ?br /> sudo vim /etc/vim/vimrc
或?sudo gedit /etc/vim/vimrc

1、显C?br />   
在文件末端添加一新行Q输?set nu

2、语法高?br /> 在文件中扑ֈ "syntax on   q一行,L前面的双引号"Q双引号是注释的意?/p>

3、自动羃q?/p>

在文件末添加一行,输入  set autoindent
在添加一行,输入         set cindent
其中 autoindent 是自动羃q; cindent是特别针?C语言语法自动~进

注意Q如果设|好以上讄后,VIM没有作出相应的动作,那么请你把你的VIM升到最新版Q一般只要在l端输入以下命o卛_Qsudo apt-get install vim

大家用VIM愉快Q?/p>

 


下面告诉大家怎么在linux下学习CQC在linux下的~译器是gccQ你在终端用vim输入C的源?/p>

          如下保存到hello.c然后在命令行q行Q?/p>

 

          Q?gcc hello.c -o hello

 

          q样会生成一个hello的可执行文gQ在命o行里输入Q?/p>

 

          Q?./hello

 

          pq行刚刚你编译的C源码?/p>

 

            linux下同样也能编译C++Qlinux下C++~译器是gQ+Q特别提C:

            C++的头文g是iostream不是iostream.h另外q需加入命名I间stdQ例如:

            //hello.cpp

            #include <iostream>

            using namespace std;

            int main ()

            {

                  cout<<"helloworld!"<<endl;

             }

 

            q样才能正常~译Q在该目录下Q终端输入:

 

            # g++ hello.cpp -o hello

          

            q样q成一个hello的可执行文gQ同?/hello命oq行?/p>

 

本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/Dreamcode/archive/2009/05/11/4166995.aspx



]]>
Java Class Loaderhttp://www.dentisthealthcenter.com/lingy/archive/2009/08/30/293221.html林光?/dc:creator>林光?/author>Sun, 30 Aug 2009 12:54:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/30/293221.htmlE序~制一般需l编辑、编译、连接、加载和q行几个步骤。在我们的应用中Q有一些公׃码是需要反复用,把q些代码~译?#8220;?#8221;文gQ在q接步骤中,q接器将从库文g取得所需的代码,复制到生成的可执行文件中。这U库UCؓ静态库Q其特点是可执行文g中包含了库代码的一份完整拷贝;~点是被多ơ用就会有多䆾冗余拯?/p>

Z克服q个~点可以采用动态连接库。这个时候连接器仅仅是在可执行文件中打上标志Q说明需要用哪些动态连接库Q当q行E序Ӟ加蝲器根据这些标志把所需的动态连接库加蝲到内存?/p>

另外在当前的~程环境中,一般都提供Ҏ让程序在q行的时候把某个特定的动态连接库加蝲q运行,也可以将其卸载(例如Win32的LoadLibrary()&FreeLibrary()和Posix的dlopen()&dlclose()Q。这个功能被q泛地用于在E序q行时刻更新某些功能模块或者是E序外观?/p>

What is ClassLoader?

与普通程序不同的是,JavaE序Qclass文gQƈ不是本地的可执行E序。当q行JavaE序Ӟ首先q行JVMQJava虚拟机)Q然后再把Java class加蝲到JVM里头q行Q负责加载Java class的这部分叫做Class Loader?/p>

JVM本n包含了一个ClassLoaderUCؓBootstrap ClassLoaderQ和JVM一PBootstrap ClassLoader是用本地代码实现的,它负责加载核心Java ClassQ即所有java.*开头的c)。另外JVMq会提供两个ClassLoaderQ它们都是用Java语言~写的,由Bootstrap ClassLoader加蝲Q其中Extension ClassLoader负责加蝲扩展的Java classQ例如所有javax.*开头的cd存放在JRE的ext目录下的c)QApplication ClassLoader负责加蝲应用E序自n的类?/p>

When to load the class?

什么时候JVM会用ClassLoader加蝲一个类呢?当你使用javaL行一个类QJVM使用Application ClassLoader加蝲q个c;然后如果cA引用了类BQ不是直接引用q是用Class.forName()引用QJVM׃扑ֈ加蝲cA的ClassLoaderQƈ用这个ClassLoader来加载类B?/p>

Why use your own ClassLoader?

gJVM自n的ClassLoader已经_了,Z么我们还需要创qClassLoader呢?

因ؓJVM自带的ClassLoader只是懂得从本地文件系l加载标准的java class文gQ如果编写你自己的ClassLoaderQ你可以做到Q?br /> 1Q在执行非置信代码之前,自动验证数字{֐
2Q动态地创徏W合用户特定需要的定制化构建类
3Q从特定的场所取得java classQ例如数据库?br /> 4) {等

事实上当使用Applet的时候,qC特定的ClassLoaderQ因旉要从|络上加载java classQƈ且要查相关的安全信息?/p>

目前的应用服务器大都使用了ClassLoader技术,即你不需要创qClassLoaderQ了解其原理也有助于更好地部|自q应用?nbsp;

ClassLoader Tree & Delegation Model

当你军_创徏你自qClassLoaderӞ需要承java.lang.ClassLoader或者它的子cR在实例化每个ClassLoader对象Ӟ需要指定一个父对象Q如果没有指定的话,pȝ自动指定ClassLoader.getSystemClassLoader()为父对象。如下图Q?/p>

在Java 1.2后,java class的加载采用所谓的委托模式QDelegation ModleQ,当调用一个ClassLoader.loadClass()加蝲一个类的时候,遵循以下的步骤Q?br /> 1Q检查这个类是否已经被加载进来了Q?br /> 2Q如果还没有加蝲Q调用父对象加蝲该类
3Q如果父对象无法加蝲Q调用本对象的findClass()取得q个cR?/p>

所以当创徏自己的Class LoaderӞ只需要重载findClass()q个Ҏ?/p>

Unloading? Reloading?

当一个java class被加载到JVM之后Q它有没有可能被卸蝲呢?我们知道Win32有FreeLibrary()函数QPosix有dlclose()函数可以被调用来卸蝲指定的动态连接库Q但是Javaq没有提供一个UnloadClass()的方法来卸蝲指定的类?/p>

在Java中,java class的卸载仅仅是一U对pȝ的优化,有助于减应用对内存的占用。既然是一U优化方法,那么完全是JVM自行军_如何实现Q对Java开发h员来说是完全透明的?/p>

在什么时候一个java class/interface会被卸蝲呢?Sun公司?a class or interface may be unloaded if and only if its class loader is unreachable. Classes loaded by the bootstrap loader may not be unloaded."

事实上我们关心的不是如何卸蝲cȝQ我们关心的是如何更新已l被加蝲了的cM而更新应用的功能。JSP则是一个非常典型的例子Q如果一个JSP文g被更改了Q应用服务器则需要把更改后的JSP重新~译Q然后加载新生成的类来响应后l的h?/p>

其实一个已l加载的cL无法被更新的Q如果你试图用同一个ClassLoader再次加蝲同一个类Q就会得到异常(java.lang.LinkageError: duplicate class definitionQ,我们只能够重新创Z个新的ClassLoader实例来再ơ加载新cR至于原来已l加载的c,开发h员不必去它Q因为它可能q有实例正在被用,只要相关的实例都被内存回收了Q那么JVM׃在适当的时候把不会再用的cd载?/p>

]]>
TOMCAT源码ȝ一http://www.dentisthealthcenter.com/lingy/archive/2009/08/30/293216.html林光?/dc:creator>林光?/author>Sun, 30 Aug 2009 12:05:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/30/293216.html首先不得不说q个corg.apache.tomcat.util.net.JIoEndpointQ它负责所有的TCPhq接Q实C一个服务器模式Q启用一个后台监听线E,负责接收到来的socketQ然后从U程池中取出响应的workerQ扔lworkerq行处理Q自ql监听。其ơworker是一个负责处理socket的一个线E,是它带着用户的请求开始进入Tomcat世界的,默认的workerd?00个,卻I最?00个线E。当处理完一个请求的时候,q个U程q不会销毁,而是q入waitdQ这个线E的对象也不会销毁,是进入了一个栈里面Q对应workstack那个数据l构。每当接收线E拿C个socket的时候,先从栈里面拿出一个已有的U程对象Q然后就利用该对象的assignҎQ将q个socketl它Qƈ调用notify重新唤醒q个worker的处理线E。以后我们做型服务器的时候,可以借鉴它的实现方式。正在研I多U程的朋友,q个cȝ对让你可以学的透彻Q?/p>

相对应的q有一个org.apache.tomcat.util.net.NioEndpointQ这个和前面那个功能差不多,但是用了NIO包里的APIQ有一个最大的区别是Q接收线E接收一个socket之后Q可能会这个socket先放入缓存池Q然后worker从池里面拿socketd理,比前面那个类看v来功能和性能都会提升很多Q不q代码行?K多,相当复杂Q设计不够精巧,有兴可以去研究下?/p>

org.apache.tomcat.util.buf.MessageBytesQ这是一个接q底层的字符串处理类Qؓ什么说是接q底层,是因为socket接收q来的都是字节类型,而java用的是char或者StringQ这之间的{换涉及到~码问题和性能问题Q所以凡是socket收进来的信息Q全部都用这个类表示Q只有当要输出字W串的时候,才会里面的字节q行转换Q实CUgq加载的懒模式,被Tomcat底层所使用的Requestc,是大量使用了这个类来存放数据。我们来小H视一下,Requestc:

  1. private MessageBytes methodMB = MessageBytes.newInstance();
  2.     private MessageBytes unparsedURIMB = MessageBytes.newInstance();
  3.     private MessageBytes uriMB = MessageBytes.newInstance();
  4.     private MessageBytes decodedUriMB = MessageBytes.newInstance();
  5.     private MessageBytes queryMB = MessageBytes.newInstance();
  6.     private MessageBytes protoMB = MessageBytes.newInstance();
  7.  
  8.     // remote address/host
  9.     private MessageBytes remoteAddrMB = MessageBytes.newInstance();
  10.     private MessageBytes localNameMB = MessageBytes.newInstance();
  11.     private MessageBytes remoteHostMB = MessageBytes.newInstance();
  12.     private MessageBytes localAddrMB = MessageBytes.newInstance();
  13.     
  14.     private MimeHeaders headers = new MimeHeaders();

或许大家会觉得,构造出q么多的c,性能会高到哪里去Q其实不是这LQ不停的构造和销毁对象的会损耗相当的性能Q但是一个对象被构造出来,可以重复利用Q那q当完了Q这个类是如此的设计,其中有一个回收资源的ҎQ叫recycle()Q这个方法可以清I里面的数组Q清I里面的对象Q而不会销毁自己本w,因ؓ使用它的对象Q只要调用recycleQ以后又可以重复使用了?/p>

MessageBytes其实内置?个重要的c,org.apache.tomcat.util.buf.ByteChunk和org.apache.tomcat.util.buf.CharChunkQ这2个类带我们回CC时代Qؓ什么这么说Q因为它直就是一个字W串处理c,一些眼熟的法全部映入眼帘Q比如字W{匚w法QindexOfQstartsWithQ判断字W{是否相等Q查扑֭W,{等Q比之JDK提供的性能更好Q功能更强大Q这句话说过了,呵呵Q?/p>

q有一个实用的值得学习的数据结构是Qorg.apache.tomcat.util.buf.AsciiQ如果知道表驱动的朋友们Q一定对q个cd熟悉了,判断大小写?判断是不是英文单词?判断是不是空白符Q判断是不是数字Q将字节cd转换为int、longcdQ大写转换Q等{。这些都是大学计机评的课后练习题



]]>
如何处理HTTP POST/GEThhttp://www.dentisthealthcenter.com/lingy/archive/2009/08/29/293078.html林光?/dc:creator>林光?/author>Sat, 29 Aug 2009 03:56:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/29/293078.html
    [全屏查看全文]
Servlet通过下面的方法来提供服务Q?
  • 实现serviceҎ?br />
  • 实现HttpServlet的doMethodҎQdoGet、doDelete、doOptions?doPost、doPut、doTraceQ?/li>
    通常QserviceҎ用来从客戯求(requestQ中提取信息Q访问扩展资源,q基于上面的信息提供响应QresponseQ?

    对于HTTP ServletsQ正提供响应的q程是首先填写响应(responseQ的头信息,然后从响应(responseQ中得到输出,最后向输出中写入内容信息。响应(responseQ头信息必须最先设|。下面将描述如何从请求(requestQ中获得信息和生HTTP响应QresponseQ?

    
  • 取得客户端请?
        一个HttpServletRequest对象提供到达HTTP 头部数据Q也允许你获取客L的数据。怎样获取q些数据取决于HTTP端请求方法。不用MHTTP方式Q你都可以用 getParameterValuesҎq回特定名称的参数倹{对于用 HTTP GET h的方式,q个getQueryStringҎ会q回一个可以用来分析的倹{?

        客户端请求(requestQ包含了从客L传递到Servlet的数据。所有的hQrequestQ都实现了ServletRequest接口。这个接口定义了一些方法访问下面的信息Q如?4-1所C?

    ?4-1  ServletRequest接口Ҏ
                c???q?                         ????
                参数Q用来在客户端和Servlet之间传送信?getAttribute(String name)
                getAttributeNames()
                getInputStream()
                getParameter(String name)
                getParameterMap()
                getParameterNames()
                getParameterValues(String name)
                对象值属性,用来在Servlet容器和Servlet
                之间Q或者协作的Servlet之间传递信?    removeAttribute(String name)
                setAttribute(String name, Object o)
                有关h使用的协议信息,
                客户端和服务器在h中的调用	   getContentLength()
                getContentType()
                getProtocol()
                getReader()
                getRealPath(String path)
                getRemoteAddr()
                getRemoteHost()
                getRequestDispatcher(String path)
                有关h使用的协议信息,
                客户端和服务器在h中的调用       getScheme()
                getServerName()
                getServerPort()
                isSecure()
                有关localization的信?       getCharacterEncoding()
                getLocale()
                getLocales()
                setCharacterEncoding(String env)


        下面的代码段C了如何用request中的Ҏ获得客户端信息?

    Enumeration params = request.getParameterNames();
                String paramName = null;
                String[] paramValues = null;
                while (params.hasMoreElements()) {
                paramName = (String) params.nextElement();
                paramValues = request.getParameterValues(paramName);
                System.out.println("\nParameter name is " + paramName);
                for (int i = 0; i < paramValues.length; i++) {
                System.out.println(", value " + i + " is " + paramValues[i].toString());
                }
                }


        HTTP Servlets使用HTTP request对象QHttpServletRequestQ,它包含了request URL、HTTP头信息、查询字W串Q等{。HTTP request URL 包括几个部分Q?br />     http://: ?

        一般情况下Q?

    requestURI = contextPath + servletPath + pathInfo
                Context pathQ通过getContextPathҎ获得?
                Servlet PathQ通过getServletPathҎ获得?
                PathInfoQ通过getPathInfoҎ获得?/ccid_code>


        如表14-2所C?

    ?4-2  路径的对?
                Request Path	            Path Elements
                /catalog/help/feedback.jsp	ContextPath: /catalog ServletPath:
                /help/feedback.jsp PathInfo: null


        
  • 提供HTTP响应
        响应QresponseQ包含了在服务器和客L之间传递的数据。所有的响应QresponseQ都实现了ServletResponse接口。这个接口定义了一些方法提供给开发h员用,如表14-3所C?

    ?4-3  ServletResponse接口Ҏ
                c???q?                          ????
                获得向客L发送数据的输出? 发送字W流QgetWriter()
                发送字节流QgetOutputStream()
                指示响应q回的内容类型(例如Qtext/htmlQ?
                已经注册的内容类型名UC存在IANA
                QInternet Assigned Numbers AuthorityQ?setContentType(java.lang.String type)
                指出是否是缓冲输出。默认情况下写入输出?
                内容被立卛_送到客户端。用缓冲后写入输出的内容先
                不发送到客户端,q样Servlet有更多的旉讄相应?
                状态码和头信息Q或者{Ud其他的Web资源	 flushBuffer()
                getBufferSize()
                isCommitted()
                reset()
                resetBuffer()
                setBufferSize(int size)
                setContentLength(int len)
                讄localization信息	            getCharacterEncoding()
                getLocale()
                setLocale(java.util.Locale loc)


        HTTP responsec(HttpServletResponseQ有一些代表HTTP头信息的域:
        
  • 状态码用来指出响应QresponseQ失败的原因?


        
  • Cookies在客L存储应用相关的信息,有时cookies用来l护和标识用Lsession?

        Servlet首先讄响应QresponseQ头信息Q包括响应(responseQ的内容cd和缓冲区大小Q然后在doGetҎ中从响应QresponseQ获得PrintWriter Q最后向输出中写入HTML代码Q调用close()Ҏ提交q次对客L的响应(responseQ。示范代码如下:

    public void doGet (HttpServletRequest request,
                HttpServletResponse response)
                throws ServletException, IOException
                {
                // 讄头信?
                response.setContentType("text/html");
                response.setBufferSize(8192);
                PrintWriter out = response.getWriter();
                // 向response中输?
                out.println("<html>" +
                "<head><title>+
                messages.getString("TitleBookDescription")
                +</title></head>");
                ...
                out.println("</body></html>");
                // 关闭输出?
                out.close();
                }


  • 林光?/a> 2009-08-29 11:56 发表评论
    ]]>
    TOMCAT源码分析(消息处理)http://www.dentisthealthcenter.com/lingy/archive/2009/08/26/292716.html林光?/dc:creator>林光?/author>Wed, 26 Aug 2009 12:53:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/26/292716.html我们知道了tomcat的整体框架了Q?也明白了里面都有些什么组Ӟ 以及各个lg是干什么用的了?/span>

    http://www.csdn.net/Develop/read_article.asp?id=27225

    我想Q接下来我们应该M解一?tomcat 是如何处理jsp和servleth的?/span>

    1.  我们以一个具体的例子Q来跟踪TOMCATQ?/span>看看它是如何?/span>Request一层一层地递交l下一个容器,q最后交l?/span>Wrapper来处理的?/span>

    ?/span>http://localhost:8080/web/login.jspZ?/span>

    Q以下例子,都是?/span>tomcat4 源码为参考)

    q篇心得主要分ؓ3个部分: 前期Q?中期Q?和末期?/span>

     前期Q讲解了在浏览器里面输入一个URLQ是怎么被tomcat抓住的?/span>

    中期Q讲解了被tomcat抓住后,又是怎么在各个容器里面穿梭, 最后到达最后的处理地点?/span>

    末期Q讲解到达最后的处理地点后,又是怎么具体处理的?/span>

    2?/span> 前期 Request的born.

        在这里我先简单讲一下requestq个东西?/span>

         我们先看着q个URLQ?/span>http://localhost:8080/web/login.jsp 它是动用?080端口来进行socket通讯的?/span>

         我们知道, 通过

           InputStream in = socket.getInputStream() ?/span>

           OutputStream out = socket.getOutputStream()

         可以实现消息的来来往往了?/span>

         但是如果把Streaml应用层看,昄操作h不方ѝ?

         所以,在tomcat 的Connector里面Q?socket被封装成了Request和Responseq两个对象?/span>

         我们可以单地把Request看成发到服务器来的数据Q把Response看成惛_出服务器的数据?/span>

         

         但是q样又有其他问题了啊Q?Requestq个对象是把socket装h了, 但是他提供的又东西太多了?/span>

         诸如Request.getAuthorization(), Request.getSocket()?nbsp;像Authorizationq种东西开发h员拿来基本上用不太着Q而像socketq种东西Q暴露给开发h员又有潜在的危险?而且啊, 在Servlet Specification里面标准的通信cLServletRequest和HttpServletRequestQ而非q个RequestcR?So, So, So. Tomcat必须得捣持捣持Request才行?最后tomcat选择了用捣持模式(应该叫适配器模式)来解册个问题。它把org.apache.catalina.Request 捣持成了 org.apache.coyote.tomcat4.CoyoteRequest?而CoyoteRequest又实CServletRequest和HttpServletRequest q两U接口?q样提供给开发h员需要且刚刚需要的Ҏ了?/span>

     

        ok, ?/span>我们?tomcat的顶层容?- StandardEngin 的invoke()Ҏq里讄一个断点, 然后讉K

        http://localhost:8080/web/login.jspQ?我们来看看在前期都会路过哪些地方Q?/span>

           1. run(): 536, java.lang.Thread, Thread.java

           CurrentThread

          2. run():666, org.apache.tomcat.util.threads.ThreadPool$ControlRunnable, ThreadPool.java

                   ThreadPool

           3. runIt():589, org.apache.tomcat.util.net.TcpWorkerThread, PoolTcpEndpoint.java

             ThreadWorker

    4.        processConnection():  549

    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler, Http11Protocol.java

                      http protocol parser

          5. Process(): 781, org.apache.coyote.http11.Http11Processor, Http11Processor.java

              http request processor

           6. service(): 193, org.apache.coyote.tomcat4.CoyoteAdapter,CoyoteAdapter.java

             adapter

           7. invoke(): 995, org.apache.catalina.core.ContainerBase, ContainerBase.java

       StandardEngin

        1. ȝE?/span>

        2. 启动U程?

        3. 调出U程池里面空闲的工作U程?/span>

        4. ?080端口传过来由httpd协议装的数据,解析成Request和Response对象?/span>

        5. 使用Http11Processor来处理request

        6. ?/span>Http11Processor里面Q?又会call CoyoteAdapter来进行适配处理Q把Request适配成实CServletRequest和HttpServletRequest接口?/span>CoyoteRequest.

    7. Cq里Q前期的L拔皮工作基本上搞定Q可以交l?/span>StandardEngin 做核心的处理工作了?/span>

    3. 中期?在各个容器间的穿梭?/span>

        Request在各个容器里面的I梭大致是这样一U方式:

        每个容器里面都有一个管道(piplineQ, 专门用来传送Request用的?/span>

        道里面又有好几个阀门(valveQ, 专门用来qoRequest用的?/span>

        在管道的低部通常都会放上一个默认的阀们?q个阀们至会做一件事情,是把Request交给子容器?/span>

        让我们来惌一下:

         当一个Requestq入一个容器后Q?它就在管道里面流动,波罗~ 波罗~ 波罗~ 地穿q各个阀门。在到最后一个阀门的时候,吧唧~ 那个该死的阀门就把它扔给了子容器?然后又开?波罗~ 波罗~ 波罗~ ... 吧唧~.... 波罗~ 波罗~ 波罗~ ....吧唧~....

        是通过q种方式Q?Request 走完了所有的容器。( 感觉有点像消化系l,最后一个地Ҏ点像那里~ Q?/span>

        OKQ?让我们具体看看都有些什么容器, 各个容器里面又都有些什么阀门,q些阀们都Ҏ们的Request做了些什么吧Q?/span>

    3.1 StandardEngin 的pipeline里面攄是:StandardEnginValve

    在这里,VALVE做了三g事:

    1.   验证传递过来的request是不?/span>httpservletRequest.

    2    验证传递过来的 request 是否携带?/span>host header信息.

    3    选择相应?/span>hostd理它。(一般我们都只有一个host:localhostQ也是127.0.0.1Q?/span>

    Cq个地方Q?/span>我们?/span>request已l完成了?/span>Enginq个部分的历史命,通向前途未卜的下一站: host了?/span>

    3.2 StandardHost 的pipline里面攄是: StandardHostValve

    1.   验证传递过来的request是不?/span>httpservletRequest.

    2.   ҎRequest来确定哪?/span>Context来处理?/span>

    Context其实是webappQ?/span>比如http://localhost:8080/web/login.jsp

    q里webContext|!

    3.   既然定了是哪个Context了,那么应该把那个Context?/span>classloader付给当前U程了?/span>

            Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());

       q样request只看得见指定的context下面?/span>classes啊, jar啊这些,而看不见tomcat本n的类Q?/span>什?/span>Engin啊, Valve啊?/span>不然q得了啊Q?/span>

    4. 既然requestCq里了,看来用户是准备访问webq个web app了,咋们得更C下这个用Lsession不是Q?Ok , qmanager更新一下用Lsession信息

    5. 交给具体的Context 容器ȝl处理Request.

    6. Context处理完毕了,?/span>classloaderq回来?/span>

    3.3 StandardContext 的pipline里面攄是: StandardContextValve

    1.   验证传递过来的request是不?/span>httpservletRequest.

    2.   如果request意图不轨Q想要访?/span>/meta-inf, /web-infq些目录下的东西Q呵呵,没有用D!

    3.   q个时候就会根?/span>Request到底?/span>ServletQ?/span>q是jspQ?/span>q是静态资源来军_到底用哪U?/span>Wrapper来处理这?/span>Reqeust了?/span>

    4.   一旦决定了到底用哪U?/span>WrapperQ?/span>OKQ交l那?/span>Wrapper处理?/span>

    4. 末期?不同的需求是怎么处理?

    StandardWrapper

    之前对Wrapper没有做过讲解Q其实它是这样一U东ѝ?/span>

    我们在处理Request的时候,可以分成3U?/span>

    处理静态的Q?org.apache.catalina.servlets.DefaultServlet  

    处理jsp的:org.apache.jasper.servlet.JspServlet

    处理servlet的:org.apache.catalina.servlets.InvokerServlet

    不同的requestqq?U不同的servletd理?/span>

    Wrapper是对它们的一U简单的装Q有了Wrapper后,我们可以轻村֜拦截每次的Request。也可以Ҏ地调用servlet的init()和destroy()ҎQ?便于理嘛!

    具体情况是这么滴Q?/span>

       如果request是找jsp文gQStandardWrapper里面׃装一个org.apache.jasper.servlet.JspServletd理它?/span>

       如果request是找 静态资?QStandardWrapper里面׃装一个org.apache.jasper.servlet.DefaultServlet d理它?/span>

       如果request是找servlet QStandardWrapper里面׃装一个org.apache.jasper.servlet.InvokerServlet d理它?/span>

    StandardWrapper同样也是容器Q既然是容器Q?那么里面一定留了一个管道给requestȝQ管道低部肯定也有一个阀??)Q用来做最后一道拦截工?

    在这最底部的阀门里Q其实就主要做了两g?

       一是启动过滤器Q让request在N个过滤器里面{一通,如果OKQ?那就PASS?否则p到其他地方去了?/span>

       二是servlet.service((HttpServletRequest) request,(HttpServletResponse) response); q个Ҏ.

         如果?JspServletQ?那么先把jsp文g~译成servlet_xxx, 再invoke servlet_xxx的servie()Ҏ?/span>

         如果?DefaultServletQ?q接找到静态资源,取出内容Q?发送出厅R?/span>

         如果?InvokerServletQ?p用那个具体的servlet的service()Ҏ?/span>

       ok! 完毕?/span>

    ?: StandardWrapper 里面的阀门是最后一道关口了?如果q个阀门欲意把request交给StandardWrapper 的子容器处理?对不P 在设计考虑的时候, Wrapperp考虑成最末的一个容器, 压根儿就不会lWrapperd子容器的ZQ?如果是要调用addChild(), 立马抛出IllegalArgumentExceptionQ?/span>

    参考:

         <http://jakarta.apache.org/tomcat/>
       <
    http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html>

     


    相关文章


    ]]>
    TOMCAT源码分析(启动框架http://www.dentisthealthcenter.com/lingy/archive/2009/08/26/292715.html林光?/dc:creator>林光?/author>Wed, 26 Aug 2009 12:49:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/26/292715.html
    TOMCAT源码分析(启动框架)     选择?ThomasHuang ?Blog
    关键?/font>   tomcat 源代?源码 source code architecture
    出处  

    TOMCAT源码分析(启动框架)
    前言Q?br />    本文是我阅读了TOMCAT源码后的一些心得?主要是讲解TOMCAT的系l框Ӟ 以及启动程。若有错漏之处,敬请批评指教Q?br /> Q?br />    毕竟TOMCAT的框架还是比较复杂的Q?单是从文字上理解Q?是不那么Ҏ掌握TOMCAT的框架的?所以得实践、实c再实践?下蝲一份TOMCAT的源码, 调试通过Q?然后单步跟踪其启动过E?如果有不明白的地方, 再来查阅本文Q?看是否能得到帮助?我相信这h果以及学习速度都会好很多!
      
    1. Tomcat的整体框架结?br />    Tomcat的基本框Ӟ 分ؓ4个层ơ?br />    Top Level Elements:
        Server
        Service  
       Connector
        HTTP
        AJP
       Container
       Engine
         Host
       Context
       Component 
        manager
       logger
       loader
       pipeline
       valve
             ...
       站在框架的顶层的是Server和Service
       Server:  其实是BackGroudE序Q?在Tomcat里面的Server的用处是启动和监听服务端事gQ诸如重启、关闭等命o?在tomcat的标准配|文Ӟserver.xml里面Q?我们可以看到“<Server port="8005" shutdown="SHUTDOWN" debug="0">”q里?SHUTDOWN"是server在监听服务端事g的时候所使用的命令字Q?br />    ServiceQ?在tomcat里面Q?service是指一c问题的解决Ҏ?nbsp; 通常我们会默认用tomcat提供的:Tomcat-Standalone 模式的service?在这U方式下的service既给我们提供解析jsp和servlet的服务, 同时也提供给我们解析静态文本的服务?br />   
       Connector: Tomcat都是在容器里面处理问题的Q?而容器又到哪里去取得输入信息呢?
    Connector是专干q个的?他会把从socket传递过来的数据Q?装成Request, 传递给容器来处理?br />    通常我们会用CUConnector,一U叫http connectoerQ?用来传递http需求的?另一U叫AJPQ?在我们整合apache与tomcat工作的时候, apache与tomcat之间是通过q个协议来互动的?Q说到apache与tomcat的整合工作, 通常我们的目的是Z让apache 获取静态资源, 而让tomcat来解析动态的jsp或者servlet。)
       Container: 当http connector把需求传递给的container: Engin的时候, 我们的视U就应该Ud到Containerq个层面来了?br />    在Containerq个层, 我们包含?U容器: Engin, Host, Context.
       Engin: 收到service传递过来的需求, 处理后, 结果返回给service( service 是通过 connector q个媒介来和Engin互动?).
       Host: Engin收到service传递过来的需求后Q不会自己处理, 而是交给合适的Host来处理?br /> Host在这里就是虚拟主机的意思, 通常我们都只会用一个主机,?#8220;localhost”本地机来处理?
       Context: Host接到了从Host传过来的需求后Q?也不会自己处理, 而是交给合适的Context来处理?
       比如Q?<http://127.0.0.1:8080/foo/index.jsp>
             <http://127.0.1:8080/bar/index.jsp>
       前者交lfooq个Context来处理, 后者交lbarq个Context来处理?br />    很明昑֐Q?context的意思其实就是一个web app的意思?br />    我们通常都会在server.xml里面做这L配置
       <Context path="/foo" docBase="D:/project/foo/web" />
       q个context容器Q就是用来干我们该干的事儿的地方的?br />   
       Compenent: 接下来, 我们l箋讲讲component是干什么用的?br />    我们得先理解一下容器和lg的关pR?br />    需求被传递到了容器里面, 在合适的时候, 会传递给下一个容器处理?br />    而容器里面又盛装着各种各样的组Ӟ 我们可以理解为提供各U各L增值服务?br />    manager: 当一个容器里面装了managerlg后,q个容器支持session理了, 事实上在tomcat里面的session理Q?是靠的在context里面装的manager component.
       logger: 当一个容器里面装了loggerlg后, q个容器里所发生的事情, p该组件记录下来啦Q?我们通常会在logs/ q个目录下看?catalina_log.time.txt 以及 localhost.time.txt 和localhost_examples_log.time.txt?q就是因为我们分别ؓQengin, host以及context(examples)q三个容器安装了loggerlgQ?q也是默认安装, 又叫做标?Q)
       loader: loaderq个lg通常只会l我们的context容器使用Q?loader是用来启动context以及理q个context的classloader用的?br />     pipline: pipeline是这样一个东西, 当一个容器决定了要把从上U传递过来的需求交l子容器的时候, 他就把这个需求放q容器的道(pipeline)里面厅R?而需求傻呼呼得在道里面动的时候, ׃被管道里面的各个阀门拦截下来?比如道里面放了两个阀门?W一个阀门叫?#8220;access_allow_vavle”Q?也就是说需求流q来的时候,它会看这个需求是哪个IPq来的, 如果q个IP已经在黑名单里面了, sure, 杀Q?W二个阀门叫?#8220;defaul_access_valve”它会做例行的查, 如果通过的话QOKQ?把需求传递给当前容器的子容器?是通过q种方式Q?需求就在各个容器里面传递,动Q?最后抵辄的地的了?br />     valve: 是上面所说的阀门啦?br />    Tomcat里面大概是q么些东西, 我们可以单地q么理解tomcat的框Ӟ它是一U自上而下Q?容器里又包含子容器的q样一U结构?br /> 2. Tomcat的启动流E?br />    q篇文章是讲tomcat怎么启动的,既然我们大体上了解了TOMCAT的框架结构了Q?那么我们可以望文生意地就猜到tomcat的启动, 会先启动父容器,然后逐个启动里面的子容器?启动每一个容器的时候, 都会启动安插在他w上的组件?当所有的lg启动完毕Q?所有的容器启动完毕的时候, tomcat本n也就启动完毕了?br />    理成章圎ͼ 我们同样可以猜到Q?tomcat的启动会分成两大部分Q?W一步是装配工作?W二步是启动工作?
       装配工作是为父容器装上子容器, 为各个容器安插进lg的工作?q个地方我们会用到digester模式Q?至于digester模式什么, 有什么用Q?怎么工作? 请参?<http://software.ccidnet.com/pub/article/c322_a31671_p2.html>
       启动工作是在装配工作之后Q?一旦装配成功了Q?我们只需要点燃最上面的一根导U, 整个tomcat׃被激zv来?q就好比我们要开一辆已l装配好了的汽R的时候一P我们只要把钥匙插q钥匙孔Q一拧,汽R的引擎就会发动v来,I׃开hQ?安全装置׃生效Q?如此一来,汽R整个发动v来了。(q个q程实和TOMCAT的启动过E不谋而和Q?让我们不得不怀?TOMCAT的设计者是在GE做JAVA开发的Q?br /> 2.1 一些有意思的名称Q?br />    Catalina
       Tomcat
       Bootstrap
       Engin
       Host
       Context
       他们的意思很有意思:
       Catalina: q程轰炸?br />    Tomcat: 熊猫轰炸?-- 轰炸机的一U(q让我想起了让国人引以ؓ豪的熊猫手机Q是不是英文可以叫做tomcat??? Q?又让我想起了另一则广告: 波导-手机中的战斗机、L?客机中的战斗?Q?br />    Bootstap: 引导
       Engin: 发动?br />    Host: LQ领?br />    Context: 内容Q?目标Q?上下?br />   
       ... 在许多许多年后, C人类已经灭绝?后现代生物发Cq些单词零落零落在一块?一个自以ؓ聪明的家伙把q些东西译出来了:
       在地勤h员的引导(bootstrap)下, 一架蘪炸架(catalina)腄跃vQ?q看是熊猫蘪炸机(tomcat)Q?q看q是熊猫轰炸机! 凭借着优秀的发动机技?engin)Q?q架熊猫轰炸机飞临了敌国的领土上I?host)Q?对准目标(context)投下了毁天灭地的核弹_波~ C生物p么隔屁了~
     
       lg所qͼ q又不得不让惛_GE是不是也参与了军事设备的生呢?
       反对帝国主义! 反对霸权主义! 和^万岁Q?自由万岁Q?br />   
    2.2  历史是那么惊h的相| tomcat的启动就是从org.apache.catalina.startup.Bootstrapq个cL然启动的Q?br />    在Bootstrap里做了两件事Q?br />    1. 指定?U类型classloader:
          commonLoader: common/classes、common/lib、common/endorsed
          catalinaLoader: server/classes、server/lib、commonLoader
          sharedLoaderQ?nbsp; shared/classes、shared/lib、commonLoader
       2. 引导Catalina的启动?br />       用Reflection技术调用org.apache.catalina.startup.Catalina的processҎQ?q传递参数过厅R?br />   
    2.3 Catalina.java
       Catalina完成了几个重要的dQ?br />    1. 使用Digester技术装配tomcat各个容器与组件?br />       1.1 装配工作的主要内Ҏ安装各个大g?比如server下有什么样的servcie?Host会容U_个context?Context都会使用到哪些组件等{?
          1.2 同时呢, 在装配工作这一步, q完成了mbeans的配|工作?在这里,我简单地但不十分_地描qC下mbean是什么,q什么用的?br />           我们自己生成的对象, 自己理Q?天经CQ?但是如果我们创徏了对象了Q?惌别h来管Q?怎么办呢Q?我想臛_得告诉别人我们都有什么, 以及通过什么方法可以找?nbsp; 吧! JMX技术给我们提供了一U手Dc?JMX里面主要?U东ѝMbean, agent, connector.
           MbeanQ?用来映射我们的对象。也许mbean是我们创徏的对象, 也许不是Q?但有了它Q?可以引用到我们的对象了?br />        Agent:  通过它, 可以找到mbean了?br />        Connector: q接Agent的方式?可以是http的, 也可以是rmi的,q可以直接通过socket?br />       发生在tomcat 装配q程中的事情:  GlobalResourcesLifecycleListener cȝ初始化会被触发:
             protected static Registry registry = MBeanUtils.createRegistry();  会运?br />          MBeanUtils.createRegistry()  会依?org/apache/catalina/mbeans/mbeans-descriptors.xmlq个配置文g创徏 mbeans. Ok, 外界有了条途径讉Ktomcat中的各个lg了。(有点像后门儿Q?br />    2. 为top level 的server 做初始化工作?实际上就是做通常会配|给service的两条connector.(http, ajp)
       3. 从serverq个容器开始启动, 点燃整个tomcat.
       4. 为server做一个hookE序Q?当server shutdown的时候, 关闭tomcat的各个容器用?br />    5. 监听8005端口Q?如果发?SHUTDOWN"Q默认培植下字符Ԍq来Q?关闭8005serverSocket?br /> 2.4 启动各个容器
       1. Server
          触发Server容器启动?before_start)Q?启动?start)Q?启动?after_start)3个事Ӟ q运行相应的事g处理器?br />       启动Server的子容器QServcie.
       2. Service
          启动Service的子容器QEngin
          启动Connector
       3. Engin
          CEnginq个层次Q以及以下别的容器Q?Tomcat׃用了比较一致的启动方式了?br />       首先Q?nbsp; q行各个容器自己Ҏ一些Q?br />       随后Q?nbsp; 触发启动前事?br />       立即Q?nbsp; 讄标签Q就表示该容器已l启?br />       接着Q?nbsp; 启动容器中的各个lgQ?loader, logger, manager{等
          再接着Q启动mappinglg。(?Q?br />       紧跟着Q启动子容器?br />       接下来,启动该容器的道(pipline)
          然后Q?nbsp; 触发启动中事?br />       最后,  触发启动后事件?br />  
          Engin大致会这么做Q?Host大致也会q么做, Context大致q是会这么做?那么很显然地Q?我们需要在q里使用C码复用的技术?tomcat在处理这个问题的时候, 漂亮C用了抽象cL处理?ContainerBase. 最后得这部分完成复杂功能的代码显得干净利落Q?q练爽快Q?实在是o得叹止, l细品来Q?直觉如n佳珍Q?另h齉K留香Q?留恋往q啊Q?br />      
          Engin的触发启动前事g里, 会激zȝ定在Engin上的唯一一个ListenerQEnginConfig?br />       q个EnginConfigcd本上没有做什么事情, 是把EnginConfig的调试别设|ؓ和Engin相当?另外是输出几行文本Q?表示Engin已经配置完毕Q?q没有做什么实质性的工作?br />       ?: mappinglg的用处是Q?当一个需求将要从父容器传递到子容器的时候, 而父容器又有多个子容器的话, 那么应该选择哪个子容器来处理需求呢Q?q个由mapping lg来定夺?br />    
       4. Host
           同Engin一P 也是调用ContainerBase里面的start()ҎQ?不过之前做了些自个儿的Q?是往Hostq个容器的通道QpiplineQ里面, 安装了一个叫?br />  “org.apache.catalina.valves.ErrorReportValve”的阀门?br />        q个阀门的用处是这LQ?nbsp; 需求在被Engin传递给Host后, 会l传递给Context做具体的处理?q里需求其实就是作为参C递的Request, Response?所以在context把需求处理完后, 通常会改动response?而这个org.apache.catalina.valves.ErrorReportValve的作用就是检察response是否包含错误Q?如果有就做相应的处理?br />    5. Context
           Cq里Q?q于轮Ctomcat启动中真正的重头戏,启动Context了?br />  StandardContext.start() q个启动Context容器的方法被StandardHost调用.
     5.1 webappResources 该context所指向的具体目?br />  5.2 安装defaultContex, DefaultContext 是默认Context?如果我们在一个Host下面安装了DefaultContextQ而且defaultContext里面又安装了一个数据库q接池资源的话?那么其他所有的在该Host下的Context, 都可以直接用这个数据库q接池, 而不用格外做配置了?br />   5.3 指定Loader. 通常用默认的org.apache.catalina.loader.WebappLoaderq个cR?nbsp;  Loader是用来指定q个context会用到哪些类啊, 哪些jar包啊q些什么的?br />  5.4 指定 Manager. 通常使用默认的org.apache.catalina.session. StandardManager ?Manager是用来管理session的?br />      其实session的管理也很好实现?以一U简单的session理Z?当需求传递过来的时候, 在Request对象里面有一个sessionId 属性?OKQ?得到q个sessionId后, 我们可以把它作为map的keyQ而value我们可以攄一个HashMap. HashMap里边儿, 再放我们x的东ѝ?br />  5.5 postWorkDirectory (). Tomcat下面有一个work目录?我们把时文仉扔在那儿厅R?q个步骤是在那里创Z个目录?一般说来会?CATALINA_HOME%/work/Standalone\localhost\ q个地方生成一个目录?br /> 5.6  Binding thread。到了这里, 应该发?class Loader 互换了?之前是看得见tomcat下面所有的class和lib. 接下来需要看得见当前context下的class?所以要讄contextClassLoader, 同时q要把旧的ClassLoader记录下来Q因Z后还要用的?br /> 5.7  启动 Loader. 指定q个Context具体要用哪些classesQ?用到哪些jar文g?如果reloadable讄成了true, ׃启动一个线E来监视classes的变化, 如果有变化就重新启动Context?br /> 5.8  启动logger
    5.9  触发安装在它w上的一个监听器?br />  lifecycle.fireLifecycleEvent(START_EVENT, null);
     作ؓ监听器之一QContextConfig会被启动. ContextConfig是用来配置web.xml的?比如q个Context有多ServletQ?又有多少FilterQ?是在这里给Context装上ȝ?br />  5.9.1 defaultConfig. 每个context都得配置 tomcat/conf/web.xml q个文g?br />  5.9.2 applicationConfig 配置自己?WEB-INF/web.xml 文g
    5.9.3 validateSecurityRoles 权限验证?通常我们在访?admin 或?manager的时候,需要用戯么是admin的要么是manager的, 才能讉K?而且我们q可以限刉些资源可以访问, 而哪些不能?都是在这里实现的?br /> 5.9.4 tldScan: 扫描一下, 需要用到哪些标{?tag lab)
    5.10 启动 manager
    5.11 postWelcomeFiles() 我们通常会用到的3个启动文件的名称Q?br /> index.html、index.htm、index.jsp p默认地绑在了q个context?br />  5.12 listenerStart 配置listener
     5.13 filterStart 配置 filter
     5.14 启动带有<load-on-startup>1</load-on-startup>的Servlet.
      序是从到大: 1,2,3… 最后是0
      默认情况下, 臛_会启动如?个的Servlet:
      org.apache.catalina.servlets.DefaultServlet  
          处理静态资源的Servlet. 什么图片啊Q?html啊, css啊, js啊都找他
      org.apache.catalina.servlets.InvokerServlet
          处理没有做Servlet Mapping的那些Servlet.
      org.apache.jasper.servlet.JspServlet
          处理JSP文g?
           5.15  标识context已经启动完毕?br />  C多少个步骤啊Q?Contextȝ是启动完毕喽?br />     OK! 走到了这里, 每个容器以及lg都启动完毕?Tomcatl于不辞辛劳Cؓ人民服务了!
    3. 参考文献:
        <http://jakarta.apache.org/tomcat/>
        <http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html>
       
    4. 后记
        q篇文章是讲解tomcat启动框架的,q有文章是讲解TOMCAT里面的消息处理流E的l节的?文章内容已经写好了, 现在正在整理阶段?怿很快可以做出来Q?大家共同研究共同q步?br />     q篇文章是独自分析TOMCAT源码所写的Q?所以一定有地方是带有个Z观色彩, 隑օ会有片面之处。若有不当之处敬h评指教,q样不仅可以使刚开始研ITOMCAT的兄弟们走弯\Q?我也可以学到东西?br />     email: sojan_java@yahoo.com.cn

    5. tomcat源码分析(消息处理)



    ]]>
    用Digester化XML文处理http://www.dentisthealthcenter.com/lingy/archive/2009/08/26/292713.html林光?/dc:creator>林光?/author>Wed, 26 Aug 2009 12:27:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/26/292713.html 

    Digester框架属于Jakarta CommonsQ它以规则和模式为基处理XML文。与SAX和DOM之类的标准API相比QDigester不涉及太多的l节问题Q非帔R合于对XML文q行单的处理?

    在Java和XML开发中Q一个常见的d是把XML文转换成对应的Java Bean对象的层ơ结构。h们经常用标准的SAX和DOM API来完成这个Q务。虽然这两种API都很强大和灵z,但对于某些简单的d来说Q它们显得操作层ơ太低,也就是说Q涉及了太多的细节问题。Jakarta Digester框架能够很好地满cd合的需要?

    Digester框架?

    Jakarta的Digester框架从Struts框架发展而来Q原先被用来处理struts-config.xml配置文gQ但很快Z认识到它有着更广泛的用途,把它转入了Jakarta Commons目。Jakarta Commons的目标是提供一?#8220;可重用Javalg的仓?#8221;。Digester最新的版本?.3Q于2002q??3日发布?

    Digester框架允许开发者指定一l动作,当解析器在XML文中发现某些特定的单模式时动作被执行。Digester框架带有10个预定义的规则(RuleQ,늛了unmarshalling XMLQ例如创建Bean或设|Bean属性)的大多数需求( marshalling的原意是?#8220;配制整齐Q编l列?#8221;Qmarshalling是在内存中ؓJava对象生成XML描述文的过E,而unmarshalling是指把XML形式的描q{换到可用Java代码操作的对象的q程Q我们称之ؓ“反配?#8221;Q,但必要时用户可以定义和实现自q规则?

    在本文的例子中,我们反配制下面q个XML文Q?

    <?xml version="1.0"?>
                <catalog library="somewhere">
                <book>
                <author>Author 1</author>
                <title>Title 1</title>
                </book>
                <book>
                <author>Author 2</author>
                <title>His One Book</title>
                </book>
                <magazine>
                <name>Mag Title 1</name>
                <article page="5">
                <headline>Some Headline</headline>
                </article>
                <article page="9">
                <headline>Another Headline</headline>
                </article>
                </magazine>
                <book>
                <author>Author 2</author>
                <title>His Other Book</title>
                </book>
                <magazine>
                <name>Mag Title 2</name>
                <article page="17">
                <headline>Second Headline</headline>
                </article>
                </magazine>
                </catalog>

    下面是Bean的代码。注意用Digester框架ӞBeancdd义成public?

    import java.util.Vector;
                public class Catalog {
                private Vector books;
                private Vector magazines;
                public Catalog() {
                books = new Vector();
                magazines = new Vector();
                }
                public void addBook( Book rhs ) {
                books.addElement( rhs );
                }
                public void addMagazine( Magazine rhs ) {
                magazines.addElement( rhs );
                }
                public String toString() {
                String newline = System.getProperty( "line.separator" );
                StringBuffer buf = new StringBuffer();
                buf.append( "--- Books ---" ).append( newline );
                for( int i=0; i<books.size(); i++ ){
                buf.append( books.elementAt(i) ).append( newline );
                }
                buf.append( "--- Magazines ---" ).append( newline );
                for( int i=0; i<magazines.size(); i++ ){
                buf.append( magazines.elementAt(i) ).append( newline );
                }
                return buf.toString();
                }
                }
                //===================================================
                public class Book {
                private String author;
                private String title;
                public Book() {}
                public void setAuthor( String rhs ) { author = rhs; }
                public void setTitle(  String rhs ) { title  = rhs; }
                public String toString() {
                return "Book: Author='" + author + "' Title='" + title + "'";
                }
                }
                //===================================================
                import java.util.Vector;
                public class Magazine {
                private String name;
                private Vector articles;
                public Magazine() {
                articles = new Vector();
                }
                public void setName( String rhs ) { name = rhs; }
                public void addArticle( Article a ) {
                articles.addElement( a );
                }
                public String toString() {
                StringBuffer buf = new StringBuffer( "Magazine: Name='" + name + "' ");
                for( int i=0; i<articles.size(); i++ ){
                buf.append( articles.elementAt(i).toString() );
                }
                return buf.toString();
                }
                }
                //===================================================
                public class Article {
                private String headline;
                private String page;
                public Article() {}
                public void setHeadline( String rhs ) { headline = rhs; }
                public void setPage(     String rhs ) { page     = rhs; }
                public String toString() {
                return "Article: Headline='" + headline + "' on page='" + page + "' ";
                }
                }

    1 2 下一?gt;>

    Digester框架以模式(PatternQ和规则QRuleQؓ基础处理输入的XML。模式必MXML元素匚wQ包括其名字和在文树内的位|。描q匹配模式的语法cM于XPath匚w模式Q例如:catalog模式匚w层?ccid_code><catalog>元素Qcatalog/book模式匚w直接嵌套?lt;catalog>元素内的<book>元素Q但不匹配文内其他位置?lt;book>元素Q?/ccid_code>?

    所有的模式都必L定其完整名称——从根元素开始的完整路径。唯一的例外是包含通配W(“*”Q的模式Q例?/name模式匚wXML文内Q何位|的<name>元素。但是根元素不必特别指出Q因为所有的路径都是从根元素开始的l对路径?

    当Digester发现一个指定的模式Q它执行关联的d。由此可见,Digester框架昄与SAX解析器有着密切的关p(实际上,DigestercdCorg.xml.sax.ContentHandlerQƈl护着解析栈)。所有在Digester中用的规则必须扩展org.apache.commons.digester.RuleQ后者本w提供了一些类gSAX的ContentHandler回调函数的方法。例如,当遇到匹配元素的开始标记和l束标记Ӟbegin()Ҏ和end()Ҏ分别被调用?

    一旦遇到匹配元素的内容Qbody()Ҏ被调用;最后被调用的方法是finish()Q这个方法在匚w元素的结束标记处理完毕之后被调用Q用来执行可能需要的事后清理d。然而,大多数时候我们不必关注这些方法,因ؓ框架提供的标准规则很可能已经提供了所有必需的功能?

    要反配制一个文,首先创徏一个org.apache.commons.digester.Digestercȝ实例Q如果必要的话,q行一些配|操作,指定必需的模式和规则Q最后向parse()Ҏ传递一个XML文g的引用。下面的DigesterDriverC了这一处理q程Q必d命o行上指定输入XML文的名Uͼ?

    import org.apache.commons.digester.*;
                import java.io.*;
                import java.util.*;
                public class DigesterDriver {
                public static void main( String[] args ) {
                try {
                Digester digester = new Digester();
                digester.setValidating( false );
                digester.addObjectCreate( "catalog", Catalog.class );
                digester.addObjectCreate( "catalog/book", Book.class );
                digester.addBeanPropertySetter( "catalog/book/author", "author" );
                digester.addBeanPropertySetter( "catalog/book/title", "title" );
                digester.addSetNext( "catalog/book", "addBook" );
                digester.addObjectCreate( "catalog/magazine", Magazine.class );
                digester.addBeanPropertySetter( "catalog/magazine/name", "name" );
                digester.addObjectCreate( "catalog/magazine/article", Article.class );
                digester.addSetProperties( "catalog/magazine/article", "page", "page" );
                digester.addBeanPropertySetter( "catalog/magazine/article/headline" );
                digester.addSetNext( "catalog/magazine/article", "addArticle" );
                digester.addSetNext( "catalog/magazine", "addMagazine" );
                File input = new File( args[0] );
                Catalog c = (Catalog)digester.parse( input );
                System.out.println( c.toString() );
                } catch( Exception exc ) {
                exc.printStackTrace();
                }
                }
                }

    在上面的代码中,我们首先创徏了Digestercȝ一个实例digesterQ然后指定它不要用DTD验证XML文的合法性——这是因为我们没有ؓXML文定义DTD。接下来Q我们指定了模式和关联的规则QObjectCreateRule创徏指定cȝ一个实例,q将它压入解析栈。SetPropertiesRule把Bean属性设|成当前XML元素的属性值——规则的W一个参数是XML属性的名称Q第二个参数是Bean属性的名称?

    SetPropertiesRule获取的是XML属性的|而BeanPropertySetterRule获取的是位于当前元素内的原始字符数据倹{用BeanPropertySetterRule时不必指定要讄的Bean属性名字,默认是当前XML元素的名U。在上面的例子中Q在匚wcatalog/magazine/article/headline模式的规则定义中使用的就是默认倹{最后,SetNextRule弹出解析栈顶部的对象Qƈ把该对象传递给它下面对象的指定名称的方法——通常用来把一个配|完毕的Bean插入父对象?

    注意Q我们可以ؓ同一个模式注册多个规则。如果注册了多个规则Q则q些规则按照它们被加入到Digester的次序执行,例如Q如果要处理catalog/magazine/article?article>元素Q我们首先创建合适的article BeanQ然后设|page属性,最后弹出完成后的article BeanQƈ把它插入magazine?

    调用LҎ

    我们不仅可以讄Bean的属性,而且q可以调用堆栈内对象的Q意方法。这通过CallMethodRule完成Q我们只需指定Ҏ名字Q如有必要,再说明调用的参数cd和数量。CallParamRule用来定义传递给被调用函数的参数|参数值可以从当前XML元素的命名的属性获取,也可以从当前元素包含的原始字W数据获取。例如,在前面实现DigesterDriver的例子中Q我们可以不用BeanPropertySetterRuleQ而是通过昑ּ调用属性的setҎ辑ֈ同样的目的:

    digester.addCallMethod( "catalog/book/author", "setAuthor", 1 );
                digester.addCallParam( "catalog/book/author", 0 );

    上面的第一行代码给Z要调用的ҎQ即setAuthor()Q,以及该调用需要的参数数量Q即1Q。第二行代码的意思是?author>元素包含的字W数据获取函数参数的|把它作ؓ参数数组的第一个传入(即烦引是0的数l元素)。如果我们指定了XML元素属性的名称Q例如digester.addCallParam( "catalog/book/author", 0, "author" );Q,则参数值将从当前元素的相应属性D取?

    q里必须注意的是Q?#8220;digester.addCallMethod( "pattern", "methodName", 0 );”q个语句不是指定了一个不带参数的Ҏ调用Q而是指定了带有一个参数的Ҏ调用Q它的值就是当前XML元素的字W数据!q样Q我们又有了另一U替代BeanPropertySetterRule的办法:

    digester.addCallMethod( "catalog/book/author", "setAuthor", 0 );

    如果要调用一个确实没有参数的ҎQ必采用如下Ş式:digester.addCallMethod( "pattern", "methodName" );?

    标准规则概要

    下面要说明所有标准规则?

    创徏

    ObjectCreateRuleQ利用指定类的默认构造函敎ͼ创徏该类的一个对象,q把对象压入栈。当元素处理l束Ӟ对象被弹出。被实例化的cd通过class对象或类的全U给出?

    FactoryCreateRuleQ利用指定的工厂cdZ个对象,把对象压入栈。对于没有提供默认构造函数的c,q一规则很有用。用于该规则的工厂类必须实现org.apache.commons.digester.ObjectCreationFactory接口?

    讄属?

    SetPropertiesRuleQ利用指定名U的XML元素属性|讄层Bean的一个或者多个指定名U的属性。XML元素的属性名U和Bean的属性名UCString[]数组形式传入该规则(通常用来处理

    之类的结构)?

    BeanPropertySetterRuleQ把层Bean的指定名U的属性设|成当前XML元素包含的字W数据。(通常用来处理<page>10</page>之类的结构)?

    SetPropertyRuleQ设|顶层Bean的一个属性。无论是Bean属性的名称Q还是赋予该属性的|都在当前XML元素中以属性的形式指定Q例如:<article key="page" value="10" />?

    理?子关p?

    SetNextRuleQ弹出栈的对象Q把它传递给紧接其下的另一个对象的指定名称的方法。通常用来把一个已l初始化的Bean插入到父对象?

    SetTopRuleQ把栈里面上数第二的对象传递给层的对象。当子对象提供了一个setParenetҎӞq一规则很有用?

    SetRootRuleQ调用栈底对象的一个方法,q把栈顶的对象作为参C入?

    调用LҎ

    CallMethodRuleQ调用顶层Bean的指定名U的Ҏ。被调用的方法可以有L多个参数Q参数的值通过后的CallParamRulel出?

    CallParamRuleQ表C方法调用的参数。参数的值或者取自指定名U的XML元素的属性,或者是当前元素包含的原始字W数据。这个规则要求用一个整数指定它在参数列表中的位|?

    通过XML指定规则

    在前面的内容中,我们用程序代码的方式指定模式和规则,q些模式和规则都是在~译的时候就已经定Q虽然从概念上来讲比较简单,但却不能说尽善尽:Digester框架的M目标是在q行时识别和处理各种数据l构Q但如果我们用编E的Ҏ指定模式和规则,则所有行为在~译时已l固定!如果Java源程序中包含了大量固定的字符Ԍ通常意味着E序在执行某些配|操作,q部分操作可以被Q或许是应该被)延迟到运行时q行?

    org.apache.commons.digester.xmlrules包解决了q个问题。这个包提供了一个DigesterLoaderc,它能够从XML文d模式/规则对,q回配置好的Digester对象。用来配|Digester对象的XML文必须遵从digester-rules.dtdQ这个DTD是xmlrules包的一部分?

    下面是本文例子的配|文件rules.xml。有几点必须说明?

    首先Q模式可以用两种方式指定Q或者?ccid_code><pattern>元素Q或者通过代表规则的XML元素的属性。这两种办法可以混合使用Q且<pattern>元素是可以嵌套的。其ơ,<alias>元素?lt;set-properties-rule>一起用,用来把XML属性映到Bean属性。最后,当前发行的Digester软g包而言Q我们不能在配置文g中指定BeanPropertySetterRuleQ正如前面所介绍的,我们用CallMethodRule来达到同L目标?

    <?xml version="1.0"?>
                <digester-rules>
                <object-create-rule pattern="catalog" classname="Catalog" />
                <set-properties-rule pattern="catalog" >
                <alias attr-name="library" prop-name="library" />
                </set-properties-rule>
                <pattern value="catalog/book">
                <object-create-rule classname="Book" />
                <call-method-rule pattern="author" methodname="setAuthor"
                paramcount="0" />
                <call-method-rule pattern="title" methodname="setTitle"
                paramcount="0" />
                <set-next-rule methodname="addBook" />
                </pattern>
                <pattern value="catalog/magazine">
                <object-create-rule classname="Magazine" />
                <call-method-rule pattern="name" methodname="setName" paramcount="0" />
                <pattern value="article">
                <object-create-rule classname="Article" />
                <set-properties-rule>
                <alias attr-name="page" prop-name="page" />
                </set-properties-rule>
                <call-method-rule pattern="headline" methodname="setHeadline"
                paramcount="0" />
                <set-next-rule methodname="addArticle" />
                </pattern>
                <set-next-rule methodname="addMagazine" />
                </pattern>
                </digester-rules>

    现在Q所有实际的操作都{Ud了Digester和DigesterLoaderc,XmlRulesDrivercd变得相当单。运行下面的XmlRulesDriverӞ在第一个命令行参数中指定目录文的名字Q在W二个参C指定rules.xmlQ注意,DigesterLoader不是从File或者org.xml.sax.InputSourcedrules.xml文gQ而是要求指定一个URLQ因此,下面代码中File引用被{换成了等LURLQ?

    import org.apache.commons.digester.*;
                import org.apache.commons.digester.xmlrules.*;
                import java.io.*;
                import java.util.*;
                public class XmlRulesDriver {
                public static void main( String[] args ) {
                try {
                File input = new File( args[0] );
                File rules = new File( args[1] );
                Digester digester = DigesterLoader.createDigester( rules.toURL() );
                Catalog catalog = (Catalog)digester.parse( input );
                System.out.println( catalog.toString() );
                } catch( Exception exc ) {
                exc.printStackTrace();
                }
                }
                }

    l束语:本文对Jakarta Commons Digester的介l就到这里结束。当Ӟq有许多内容q里未涉及。其中一个在q里忽略的主题是XML名称I间QDigester允许把规则定义成只能Ҏ一个名U空间内定义的元素v作用?

    另外Q我们简单地提及了通过扩展Rulecd发定制规则的问题。按照习惯,DigestercL供了push()、peek()和pop()ҎQ得开发者能够自由地直接操作解析栈?

    参考:

    Jakarta Commons Digester Homepage

    Jakarta Struts Homepage



    ]]>ThreadLocal与synchronized http://www.dentisthealthcenter.com/lingy/archive/2009/08/25/292559.html林光?/dc:creator>林光?/author>Tue, 25 Aug 2009 12:36:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/25/292559.html相关文章:  
    正确理解ThreadLocal
    ThreadLocal与synchronized

    推荐圈子: Pipboy
    更多相关推荐
    昨天上Java版块逛了一圈,一??千h览的帖子引起了偶滴注意 ThreadLocal与synchronized Q?以上的回复Q见大家对q个问题的兴?

    老实_从看到这个帖子的题目开始,p得帖子的作者估计是在概念上有所h?于是乎想写个咚咚Q同大家分n一下自q心得?

    帖子上,讨论的h很多Q高手不乏,各抒pQ但不知新手们看明白没有Q因此,q里偶以最z列表方式来说一说相关问题?

    1Q区别ThreadLocal ?synchronized

    ThreadLocal是一个线E隔?或者说是线E安?的变量存储的理实体Q注意:不是存储用的Q,它以JavacL式表玎ͼ
    synchronized是Java的一个保留字Q只是一个代码标识符Q它依靠JVM的锁机制来实C界区的函数、变量在CPUq行讉K中的原子性?
    两者的性质、表现及设计初衷不同Q因此没有可比较性?

    2.理解ThreadLocal中提到的变量副本
    事实上,我们向ThreadLocal中set的变量不是由ThreadLocal来存储的Q而是ThreadU程对象自n保存。当用户调用ThreadLocal对象的set(Object o)Ӟ该方法则通过Thread.currentThread()获取当前U程Q将变量存入Thread中的一个Map内,而Map的Key是当前的ThreadLocal实例。请看源码,q是最主要的两个函敎ͼ能看出ThreadLocal与Thread的调用关p:

    Java代码
    public void set(T value) {   
            Thread t = Thread.currentThread();   
            ThreadLocalMap map = getMap(t);   
            if (map != null)   
                map.set(this, value);   
            else  
                createMap(t, value);   
    }   
      
    ThreadLocalMap getMap(Thread t) {   
            return t.threadLocals;   
    }  
    public void set(T value) {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null)
                map.set(this, value);
            else
                createMap(t, value);
    }

    ThreadLocalMap getMap(Thread t) {
            return t.threadLocals;
    }

    Q有兴趣的朋友可以阅读Java的ThreadLocal源码Q因此,我们可以知道Q所谓的变量副本Q即是对Object ReferenceQ对象引用)的拷贝?

    3.理解Thread?ThreadLocal对变量的引用关系
    实际上Thread和ThreadLocal对变量引用关pd像是坐标pM的X轴和Y_是从两个l度上来l织对变量的引用的?

    首先说Thread?我们知道一个ThreadOne的执行会贯穿多个ҎMethodA、MethodB、MethodCq些Ҏ可能分布于不同的cd例。假设,q些Ҏ分别使用了ThreadLocalA、ThreadLocalB、ThreadLocalC来保存线E本地变量,那么q些变量都存于ThreadOne的Map中,q用各自的ThreadLocal实例作ؓkey?因此Q可以认为,借助ThreanLocal的setҎQ在X轴上QThread横向兌同一U程上下文中来自多个Method的变量引用副本?


     


    接着说ThreadLocal?一个MethodA中的X变量被多个U程ThreadOne、ThreadTwo、ThreadThree所讉K。假设MethodA使用ThreadLocal存储XQ通过setҎQ以ThreadLocal作ؓkey|不同线E来访时的不同的变量值引用保存于ThreadOne、ThreadTwo、ThreadThree的各自线E上下文中,保每个U程有自q一个变量倹{因此,可以认ؓQThreadLocal是以Method为Y_U向兌了处于同一Ҏ中的不同U程上的变量?


     

    希望能对大家有所帮助Q这样可以少走很多弯路哦?

    本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/yangairong1984/archive/2008/04/15/2294572.aspx



    ]]>
    理解ThreadLocal http://www.dentisthealthcenter.com/lingy/archive/2009/08/25/292558.html林光?/dc:creator>林光?/author>Tue, 25 Aug 2009 12:35:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/08/25/292558.htmlThreadLocal是什?/p>

    早在JDK 1.2的版本中提供java.lang.ThreadLocalQThreadLocal军_U程E序的ƈ发问题提供了一U新的思\。用这个工L可以很简z地~写Z的多线E程序?/p>

    ThreadLocal很容易让人望文生义,惛_然地认ؓ是一?#8220;本地U程”。其实,ThreadLocalq不是一个ThreadQ而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些?/p>

    当用ThreadLocall护变量ӞThreadLocal为每个用该变量的线E提供独立的变量副本Q所以每一个线E都可以独立地改变自q副本Q而不会媄响其它线E所对应的副本?/p>

    从线E的角度看,目标变量p是线E的本地变量Q这也是cd?#8220;Local”所要表辄意思?/p>

    U程局部变量ƈ不是Java的新发明Q很多语aQ如IBM IBM XL FORTRANQ在语法层面提供线E局部变量。在Java中没有提供在语言U支持,而是变相地通过ThreadLocal的类提供支持?/p>

    所以,在Java中编写线E局部变量的代码相对来说要笨拙一些,因此造成U程局部变量没有在Java开发者中得到很好的普及?/p>

    ThreadLocal的接口方?/p>

    ThreadLocalcL口很单,只有4个方法,我们先来了解一下:

    void set(Object value)
    讄当前U程的线E局部变量的倹{?/p>

    public Object get()
    该方法返回当前线E所对应的线E局部变量?/p>

    public void remove()
    当前线E局部变量的值删除,目的是ؓ了减内存的占用Q该Ҏ是JDK 5.0新增的方法。需要指出的是,当线E结束后Q对应该U程的局部变量将自动被垃圑֛Ӟ所以显式调用该Ҏ清除U程的局部变量ƈ不是必须的操作,但它可以加快内存回收的速度?/p>

    protected Object initialValue()
    q回该线E局部变量的初始|该方法是一个protected的方法,昄是ؓ了让子类覆盖而设计的。这个方法是一个gq调用方法,在线E第1ơ调用get()或set(Object)时才执行Qƈ且仅执行1ơ。ThreadLocal中的~省实现直接q回一个null?/p>

    值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型Q该cȝcd已经变ؓThreadLocal<T>。APIҎ也相应进行了调整Q新版本的APIҎ分别是void set(T value)、T get()以及T initialValue()?/p>

    ThreadLocal是如何做Cؓ每一个线E维护变量的副本的呢Q其实实现的思\很简单:在ThreadLocalcM有一个MapQ用于存储每一个线E的变量副本QMap中元素的键ؓU程对象Q而值对应线E的变量副本。我们自己就可以提供一个简单的实现版本Q?/p>

    代码清单1 SimpleThreadLocal

    public class SimpleThreadLocal {

    private Map valueMap = Collections.synchronizedMap(new HashMap());

    public void set(Object newValue) {

    valueMap.put(Thread.currentThread(), newValue);①键为线E对象,gؓ本线E的变量副本

    }

    public Object get() {

    Thread currentThread = Thread.currentThread();

    Object o = valueMap.get(currentThread);②返回本U程对应的变?/p>

    if (o == null && !valueMap.containsKey(currentThread)) {③如果在Map中不存在Q放到Map

    中保存v来?/p>

    o = initialValue();

    valueMap.put(currentThread, o);

    }

    return o;

    }

    public void remove() {

    valueMap.remove(Thread.currentThread());

    }

    public Object initialValue() {

    return null;

    }

    }

    虽然代码清单9?q个ThreadLocal实现版本昑־比较q稚Q但它和JDK所提供的ThreadLocalcd实现思\上是相近的?/p>

    一个TheadLocal实例

    下面Q我们通过一个具体的实例了解一下ThreadLocal的具体用方法?/p>

    代码清单2 SequenceNumber

    package com.baobaotao.basic;

    public class SequenceNumber {

    ①通过匿名内部c覆盖ThreadLocal的initialValue()ҎQ指定初始?/p>

    private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){

    public Integer initialValue(){

    return 0;

    }

    };

    ②获取下一个序列?/p>

    public int getNextNum(){

    seqNum.set(seqNum.get()+1);

    return seqNum.get();

    }

    public static void main(String[] args)

    {

    SequenceNumber sn = new SequenceNumber();

    ?3个线E共享snQ各自生序列号

    TestClient t1 = new TestClient(sn);

    TestClient t2 = new TestClient(sn);

    TestClient t3 = new TestClient(sn);

    t1.start();

    t2.start();

    t3.start();

    }

    private static class TestClient extends Thread

    {

    private SequenceNumber sn;

    public TestClient(SequenceNumber sn) {

    this.sn = sn;

    }

    public void run()

    {

    for (int i = 0; i < 3; i++) {④每个线E打?个序列?/p>

    System.out.println("thread["+Thread.currentThread().getName()+

    "] sn["+sn.getNextNum()+"]");

    }

    }

    }

    }

     
    通常我们通过匿名内部cȝ方式定义ThreadLocal的子c,提供初始的变量|如例子中①处所C。TestClientU程产生一l序列号Q在③处Q我们生?个TestClientQ它们共享同一个SequenceNumber实例。运行以上代码,在控制台上输Z下的l果Q?/p>

    thread[Thread-2] sn[1]

    thread[Thread-0] sn[1]

    thread[Thread-1] sn[1]

    thread[Thread-2] sn[2]

    thread[Thread-0] sn[2]

    thread[Thread-1] sn[2]

    thread[Thread-2] sn[3]

    thread[Thread-0] sn[3]

    thread[Thread-1] sn[3]

    考察输出的结果信息,我们发现每个U程所产生的序可焉׃n同一个SequenceNumber实例Q但它们q没有发生相互干扰的情况Q而是各自产生独立的序列号Q这是因为我们通过ThreadLocal为每一个线E提供了单独的副本?/p>

    Thread同步机制的比?/p>

    ThreadLocal和线E同步机制相比有什么优势呢QThreadLocal和线E同步机刉是ؓ了解军_U程中相同变量的讉K冲突问题?/p>

    在同步机制中Q通过对象的锁机制保证同一旉只有一个线E访问变量。这时该变量是多个线E共享的Q用同步机制要求程序慎密地分析什么时候对变量q行dQ什么时候需要锁定某个对象,什么时候释攑֯象锁{繁杂的问题Q程序设计和~写隑ֺ相对较大?/p>

    而ThreadLocal则从另一个角度来解决多线E的q发讉K。ThreadLocal会ؓ每一个线E提供一个独立的变量副本Q从而隔M多个U程Ҏ据的讉K冲突。因为每一个线E都拥有自己的变量副本,从而也没有必要对该变量进行同步了。ThreadLocal提供了线E安全的׃n对象Q在~写多线E代码时Q可以把不安全的变量装qThreadLocal?/p>

    ׃ThreadLocal中可以持有Q何类型的对象Q低版本JDK所提供的get()q回的是Object对象Q需要强制类型{换。但JDK 5.0通过泛型很好的解决了q个问题Q在一定程度地化ThreadLocal的用,代码清单 9 2׃用了JDK 5.0新的ThreadLocal<T>版本?/p>

    概括h_对于多线E资源共享的问题Q同步机刉用了“以时间换I间”的方式,而ThreadLocal采用?#8220;以空间换旉”的方式。前者仅提供一份变量,让不同的U程排队讉KQ而后者ؓ每一个线E都提供了一份变量,因此可以同时讉K而互不媄响?/p>

    Spring使用ThreadLocal解决U程安全问题

    我们知道在一般情况下Q只有无状态的Bean才可以在多线E环境下׃nQ在Spring中,l大部分Bean都可以声明ؓsingleton作用域。就是因为Spring对一些BeanQ如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder{)中非U程安全状态采用ThreadLocalq行处理Q让它们也成为线E安全的状态,因ؓ有状态的Bean可以在多线E中׃n了?/p>

    一般的Web应用划分为展现层、服务层和持久层三个层次Q在不同的层中编写对应的逻辑Q下层通过接口向上层开攑֊能调用。在一般情况下Q从接收h到返回响应所l过的所有程序调用都同属于一个线E,如图9?所C:

     

    ?同一U程贯通三?/p>

    q样你就可以Ҏ需要,一些非U程安全的变量以ThreadLocal存放Q在同一ơ请求响应的调用U程中,所有关联的对象引用到的都是同一个变量?/p>

    下面的实例能够体现SpringҎ状态Bean的改造思\Q?/p>

    代码清单3 TopicDaoQ非U程安全

    public class TopicDao {

    private Connection conn;①一个非U程安全的变?/p>

    public void addTopic(){

    Statement stat = conn.createStatement();②引用非U程安全变量

    }

    }

    ׃①处的conn是成员变量,因ؓaddTopic()Ҏ是非U程安全的,必须在用时创徏一个新TopicDao实例Q非singletonQ。下面用ThreadLocal对connq个非线E安全的“状?#8221;q行攚w:

    代码清单4 TopicDaoQ线E安?/p>

    import java.sql.Connection;

    import java.sql.Statement;

    public class TopicDao {

    ①用ThreadLocal保存Connection变量

    private static ThreadLocal<Connection> connThreadLocal = new ThreadLocal<Connection>();

    public static Connection getConnection(){

    ②如果connThreadLocal没有本线E对应的Connection创徏一个新的ConnectionQ?/p>

    q将其保存到U程本地变量中?/p>

    if (connThreadLocal.get() == null) {

    Connection conn = ConnectionManager.getConnection();

    connThreadLocal.set(conn);

    return conn;

    }else{

    return connThreadLocal.get();③直接返回线E本地变?/p>

    }

    }

    public void addTopic() {

    ④从ThreadLocal中获取线E对应的Connection

    Statement stat = getConnection().createStatement();

    }

    }

    不同的线E在使用TopicDaoӞ先判断connThreadLocal.get()是否是nullQ如果是nullQ则说明当前U程q没有对应的Connection对象Q这时创Z个Connection对象q添加到本地U程变量中;如果不ؓnullQ则说明当前的线E已l拥有了Connection对象Q直接用就可以了。这P׃证了不同的线E用线E相关的ConnectionQ而不会用其它线E的Connection。因此,q个TopicDao可以做到singleton׃n了?/p>

    当然Q这个例子本w很_糙Q将Connection的ThreadLocal直接攑֜DAO只能做到本DAO的多个方法共享Connection时不发生U程安全问题Q但无法和其它DAOq同一个ConnectionQ要做到同一事务多DAO׃n同一ConnectionQ必d一个共同的外部cM用ThreadLocal保存Connection?/p>

    ThreadLocal是解决线E安全问题一个很好的思\Q它通过为每个线E提供一个独立的变量副本解决了变量ƈ发访问的冲突问题。在很多情况下,ThreadLocal比直接用synchronized同步机制解决U程安全问题更简单,更方便,且结果程序拥有更高的q发性?/p>

     

    本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/qjyong/archive/2008/03/08/2158097.aspx



    ]]>
    ownerhttp://www.dentisthealthcenter.com/lingy/archive/2009/07/24/288258.html林光?/dc:creator>林光?/author>Fri, 24 Jul 2009 12:13:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/24/288258.htmlowner_4
    客户服务人员

    应该是owner_2客服支持人员

    3是制作h?br /> 4是服务h?br /> 31没看?/font>

    ]]>
    ilevelhttp://www.dentisthealthcenter.com/lingy/archive/2009/07/23/287998.html林光?/dc:creator>林光?/author>Thu, 23 Jul 2009 03:51:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/23/287998.html
     
    ilevel ?,2,3,4时分别是什么意思啊
    3--区域
    4--l管l?br /> 1--
    2--?
     
     
    3 区域 ?nbsp;大区
    1 全国 ?nbsp;׃八糟?nbsp;服务拍摄之类?/font>
    2是论七八p服务拍摄的下一U?/font>
     
    q个在那张表定义?我在ali_zeus_resourece表里找不?/font>
     
    在ali_zeus_access_area


    ]]>
    ilevelhttp://www.dentisthealthcenter.com/lingy/archive/2009/07/23/287997.html林光?/dc:creator>林光?/author>Thu, 23 Jul 2009 03:51:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/23/287997.html
     
    ilevel ?,2,3,4时分别是什么意思啊
    3--区域
    4--l管l?br /> 1--
    2--?
     
     
    3 区域 ?nbsp;大区
    1 全国 ?nbsp;׃八糟?nbsp;服务拍摄之类?/font>
    2是论七八p服务拍摄的下一U?/font>
     
    q个在那张表定义?我在ali_zeus_resourece表里找不?/font>
     
    在ali_zeus_access_area


    ]]>
    EXECUTE IMMEDIATE用法解 http://www.dentisthealthcenter.com/lingy/archive/2009/07/16/287019.html林光?/dc:creator>林光?/author>Thu, 16 Jul 2009 11:42:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/16/287019.html 它解析ƈ马上执行动态的SQL语句或非q行时创建的PL/SQL?动态创建和执行SQL语句性能前QEXECUTE IMMEDIATE的目标在于减企业费用ƈ获得较高的性能Q较之以前它相当Ҏ~码.管DBMS_SQL仍然可用Q但是推荐用EXECUTE IMMEDIATE,因ؓ它获的收益在包之上?


    -- 使用技?br />

    1. EXECUTE IMMEDIATE不会提交一个DML事务执行Q应该显式提?br /> 如果通过EXECUTE IMMEDIATE处理DML命oQ?br /> 那么在完成以前需要显式提交或者作为EXECUTE IMMEDIATE自己的一部分.
    如果通过EXECUTE IMMEDIATE处理DDL命o,它提交所有以前改变的数据


    2. 不支持返回多行的查询,q种交互用临时表来存储记录(参照例子如下)或者用REF cursors.


    3. 当执行SQL语句Ӟ不要用分P当执行PL/SQL块时Q在其尾部用分号.


    4. 在Oracle手册中,未详l覆盖这些功能?br /> 下面的例子展CZ所有用到Execute immediate的可能方?希望能给你带来方?


    5. 对于Forms开发?当在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功?


    EXECUTE IMMEDIATE -- 用法例子


    1. 在PL/SQLq行DDL语句


    begin
       execute immediate 'set role all';
    end;


    2. l动态语句传?USING 子句)


    declare
       l_depnam varchar2(20) := 'testing';
       l_loc     varchar2(10) := 'Dubai';
       begin
       execute immediate 'insert into dept values   (:1, :2, :3)'
         using 50, l_depnam, l_loc;
       commit;
    end;


    3. 从动态语句检索?INTO子句)


    declare
       l_cnt     varchar2(20);
    begin
       execute immediate 'select count(1) from emp'
         into l_cnt;
       dbms_output.put_line(l_cnt);
    end;


    4. 动态调用例E?例程中用到的l定变量参数必须指定参数cd.
    黓认为INcd,其它cd必须昑ּ指定


    declare
       l_routin    varchar2(100) := 'gen2161.get_rowcnt';
       l_tblnam    varchar2(20) := 'emp';
       l_cnt       number;
       l_status    varchar2(200);
    begin
       execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
         using in l_tblnam, out l_cnt, in out l_status;

       if l_status != 'OK' then
          dbms_output.put_line('error');
       end if;
    end;


    5. 返回g递到PL/SQL记录cd;同样也可?rowtype变量


    declare
       type empdtlrec is record (empno   number(4),
                                ename   varchar2(20),
                                deptno   number(2));
       empdtl empdtlrec;
    begin
       execute immediate 'select empno, ename, deptno ' ||
                        'from emp where empno = 7934'
         into empdtl;
    end;


    6. 传递ƈ索?INTO子句用在USING子句?br />

    declare
       l_dept     pls_integer := 20;
       l_nam      varchar2(20);
       l_loc      varchar2(20);
    begin
       execute immediate 'select dname, loc from dept where deptno = :1'
         into l_nam, l_loc
         using l_dept ;
    end;


    7. 多行查询选项.Ҏ选项用insert语句填充临时表,
    用时表q行q一步的处理,也可以用REF cursorsU正此缺?

    declare
       l_sal    pls_integer := 2000;
    begin
       execute immediate 'insert into temp(empno, ename) ' ||
                        '           select empno, ename from emp ' ||
                        '           where   sal > :1'
         using l_sal;
       commit;
    end;


            对于处理动态语?EXECUTE IMMEDIATE 比以前可能用到的更容易ƈ且更高效.
    当意图执行动态语句时Q适当地处理异常更加重?应该x于捕h有可能的异常.
    我是无聊的hQ所以做无聊的事情?/em>


    ]]>
    使用 TRUNCATE TABLE 删除所有行http://www.dentisthealthcenter.com/lingy/archive/2009/07/16/287018.html林光?/dc:creator>林光?/author>Thu, 16 Jul 2009 11:41:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/16/287018.html
    SQL Server 2008 联机丛书Q?009 q?5 月)
    使用 TRUNCATE TABLE 删除所有行

    若要删除表中的所有行Q则 TRUNCATE TABLE 语句是一U快速、有效的Ҏ。TRUNCATE TABLE 与不?WHERE 子句?DELETE 语句cM。但是,TRUNCATE TABLE 速度更快Qƈ且用更的pȝ资源和事务日志资源?/p>

    ?DELETE 语句相比QTRUNCATE TABLE h以下优点Q?/p>

    • 所用的事务日志I间较少?br /> DELETE 语句每次删除一行,q在事务日志中ؓ所删除的每行记录一个项。TRUNCATE TABLE 通过释放用于存储表数据的数据|删除数据Qƈ且在事务日志中只记录释放?br />
    • 使用的锁通常较少?br /> 当用行锁执?DELETE 语句Ӟ锁定表中各行以便删除。TRUNCATE TABLE 始终锁定表和,而不是锁定各行?br />
    • 如无例外Q在表中不会留有Mc?br /> 执行 DELETE 语句后,表仍会包含空c例如,必须臛_使用一个排?(LCK_M_X) 表锁Q才能释攑֠中的I。如果执行删除操作时没有使用表锁Q表Q堆Q中包含许多空c对于烦引,删除操作会留下一些空,管q些会通过后台清除q程q速释放?br />

    ?DELETE 语句相同Q?TRUNCATE TABLE 清空的表的定义与其烦引和其他兌对象一起保留在数据库中。如果表中包含标识列Q该列的计数器将重置列定义的U子倹{如果未定义U子Q则使用默认?1。若要保留标识计数器Q请使用 DELETE?/p>

    Microsoft SQL Server 引入一U功能,此功能可删除或截断超q?128 个区的表Q而无需同时保留需要删除的所有区的锁。有兌l信息,请参?a id="ctl00_MTContentSelector1_mainContentContainer_ctl04" onclick="javascript:Track('ctl00_MTContentSelector1_mainContentContainer_cpe28768_c|ctl00_MTContentSelector1_mainContentContainer_ctl04',this);" >删除q新生成大型对?/a>?/p>

    下面的示例删?JobCandidate 表中的所有数据。在 TRUNCATE TABLE 语句之前和之后?SELECT 语句来比较结果?/p>

    USE AdventureWorks;
    GO
    SELECT COUNT(*) AS BeforeTruncateCount
    FROM HumanResources.JobCandidate;
    GO
    TRUNCATE TABLE HumanResources.JobCandidate;
    GO
    SELECT COUNT(*) AS AfterTruncateCount
    FROM HumanResources.JobCandidate;
    GO
    


    ]]>
    一个简单的逻辑备䆾{略学习 http://www.dentisthealthcenter.com/lingy/archive/2009/07/10/286287.html林光?/dc:creator>林光?/author>Fri, 10 Jul 2009 08:58:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/10/286287.html一个简单的逻辑备䆾{略学习
    需求:
    每天19:00备䆾一ơ业务用?br /> 每个备䆾最多保??br /> 每个备䆾用日期作为备份文件的名称

    [root@localhost opt]# cat /home/autoBackup/ora_env
    export ORACLE_BASE=/opt/oracle
    export ORACLE_HOME=/opt/oracle/product/10.2.0
    export ORACLE_SID=STAPLES
    export ORACLE_TERM=xterm
    #export NLS_LANG="AMERICAN_AMERICA.ZHS16GBK"
    export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
    export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
    export PATH=$PATH:$ORACLE_HOME/bin

    export TNS_ADMIN=$ORACLE_HOME/network/admin
    export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME/jlib
    export JAVA_HOME=$ORACLE_HOME/jdk
    export ORA_NLS10=$ORACLE_HOME/nls/data
    export LC_CTYPE=en_US.UTF-8

    [root@localhost opt]# cat /opt/backup_exp.sh
    #!/bin/sh
    #CREATORQdaimin
    #functionQbackup database with expdp
    #usageQcrontab on linux
    #last modifyQtuolei 2007-08-29 create
    #set environment variable
    . /home/autoBackup/ora_env  #讄exp的环境变?br /> #开始备份,假定目录backupPath已经创徏Qƈ且backupPath=/opt/oracle/backup
    backupPath='/opt/oracle/backup/'
    FILE=`date +%Y%m%d`'.dmp'
    LOGFILE=`date +%Y%m%d`'.log'
    exp daimin/daimin@STAPLES file=$backupPath$FILE.dmp log=$backupPath$LOGFILE

    #删除以前q期的备?br /> find /opt/oracle/backup/* -name "*.dmp" -mtime +4 -exec rm {} \;

     

    [root@localhost etc]# crontab -e
    0 19 * * * /opt/backup_exp.sh > /opt/oracle/backup/logs/backup_exp.log 2>&1
    ~
    "crontab.XXXXmfkudb" 1L, 76C written
    crontab: installing new crontab
    [root@localhost etc]# crontab -l
    0 19 * * * /opt/backup_exp.sh > /opt/oracle/backup/logs/backup_exp.log 2>&1

    注意Q?br /> 1?opt/backup_exp.sh需要具有可执行权限Q才可以被root用户执行
    [root@localhost backup]# chmod +x /opt/backup_exp.sh
    否则会出?bin/sh: /opt/backup_exp.sh: Permission denied错误
    2、需要在脚本的第一行加#!/bin/sh
    否则会出?bin/sh: /opt/backup_exp.sh: cannot execute binary file错误
    3、注意在执行exp命o之前Q需要设|环境变量,所以在逻辑备䆾脚本中执行了. /home/autoBackup/ora_env 命o;


    参考网:
    http://blog.csdn.net/wzy0623/archive/2008/10/31/3193150.aspx
    http://www.linuxsir.org/main/?q=node/209


    本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/daimin1983/archive/2008/12/13/3511380.aspx



    ]]>
    Linuxpȝ利用Crontab命o实现定时重启http://www.dentisthealthcenter.com/lingy/archive/2009/07/10/286193.html林光?/dc:creator>林光?/author>Fri, 10 Jul 2009 03:01:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/10/286193.html  Crontab是一个很方便的在unix/linuxpȝ上定?循环)执行某个d的程?

      使用cron服务Q用 service crond status 查看 cron服务状态,如果没有启动?service crond start启动它,

      cron服务是一个定时执行的服务Q可以通过crontab 命od或者编辑需要定时执行的dQ?

      crontab -u //讑֮某个用户的cron服务Q一般root用户在执行这个命令的时候需要此参数

      crontab -l //列出某个用户cron服务的详l内?

      crontab -r //删除没个用户的cron服务

      crontab -e //~辑某个用户的cron服务

      比如说root查看自己的cron讄Qcrontab -u root -l

      再例如,root惛_除fred的cron讄Qcrontab -u fred -r

      在编辑cron服务Ӟ~辑的内Ҏ一些格式和U定Q输入:crontab -u root -e

      q入vi~辑模式Q编辑的内容一定要W合下面的格式:*/1 * * * * ls >> /tmp/ls.txt

      ~辑/etc/crontab文gQ在末尾加上一行: 30 5 * * * root init 6 q样将pȝ配置Z每天早上5?0自动重新启动?

      需要将crond讄为系l启动后自动启动的服务,可以?etc/rc.d/rc.local 中,在末֊?

      service crond start

      如果q需要在pȝ启动十加载其他服务,可以l箋加上其他服务的启动命令?

      比如Q?service mysqld start

      基本用法:

      1. crontab -l

      列出当前的crontabd

      2. crontab -d

      删除当前的crontabd

      3. crontab -e (solaris5.8上面?crontab -r)

      ~辑一个crontabd,ctrl_Dl束

      4. crontab filename

      以filename做ؓcrontab的Q务列表文件ƈ载入

      crontab file的格?

      crontab 文g中的行由 6 个字D늻成,不同字段间用I格?tab 键分隔。前 5 个字D|定命令要q行的时?

      分钟 (0-59)

      时 (0-23)

      日期 (1-31)

      月䆾 (1-12)

      星期?0-6Q其?0 代表星期?

      W?6 个字D|一个要在适当旉执行的字W串

      例子:

      #MIN HOUR DAY MONTH DAYOFWEEK COMMAND

      #每天早上6?0?

      10 6 * * * date

      #每两个小?

      0 */2 * * * date (solaris 5.8g不支持此U写?

      #晚上11点到早上8点之间每两个时Q早??

      0 23-7/2Q? * * * date

      #每个月的4号和每个C拜的礼拜一到礼拜三的早?1?

      0 11 4 * mon-wed date

      #1月䆾日早??

      0 4 1 jan * date

      补充Q在使用crontab的时候,要特别注意的是运行脚本中能够讉K到的环境变量和当前测试环境中的环境变量未必一_一个比较保险的做法是在q行的脚本程序中自行讄环境变量(export)

      (1)先徏一个文件crond.txt如下Q?每天早上5?6分重新启?

      36 5 * * * reboot

      (2)上传?opt目录

      (3)q行命o

      crontab /opt/crond.txt

      crontab -l

      让配|文件生效:如果让配|文件生效,q得重新启动cronQ切讎ͼ既然每个用户下的cron配置文g修改后。也要重新启动cron服务器?

      在Fedora 和Redhat中,我们应该用;

      [root@localhost ~]# /etc/init.d/crond restart

      如果让crond 在开机时q行Q应该改变其q行U别Q?

      [root@localhost ~]# chkconfig --levels 35 crond on

      service crond status 查看 cron服务状态,如果没有启动?service crond start启动它, cron服务是一个定时执行的服务Q可以通过crontab 命od或者编辑需要定时执行的d

    Crontab文g的每一行由六个?minutes、hours、day of month、month、day of week?command)l?成,域之间用I格或Tab分开Q其中:

    minutesQ?分钟域,值的范围??9

    hoursQ?时域,值的范围??3

    day of monthQ?日期Q值的范围??1

    monthQ?月䆾Q值的范围??2

    day of weekQ?星期Q值的范围??Q星期日gؓ0

    commandQ?所要运行的命o

    如果一个域?Q表明命令可以在该域所有可能的取D围内执行?

    如果一个域是由q字W隔开的两个数字,表明命o可以在两个数字之间的范围内执行(包括两个数字 本nQ?

    如果一个域是由逗号隔开的一pd值组成的Q表明命令可以在q些值组成的范围内执行?

    如果日期域和星期域都有|则这两个域都有效?

    ~写一个文Ӟ用以启动自动备䆾q程?

    cd /opt

    touch reboot.txt

    在reboot.txt中添加一下内?

    0 4 * * * reboot

    crontab /opt/reboot.txt

    用crontab -e~辑定时操作Q例如加入下行命令:

    用crontab Ql命o来查?

    注意:需要启动服?d在rc.local?

    重启crondd

    /etc/init.d/cron restart (ubuntu?

    W一U?在Fedora或Redhat {以RPM包管理的pȝ中;

    [root@localhost ~]# /etc/init.d/crond start

    [root@localhost ~]# /etc/init.d/crond stop

    [root@localhost ~]# /etc/init.d/crond restart

    /etc/rc.d/init.d/crond restart

    命o?

    crontab-操作每个用户的守护程序和该执行的旉表?

    部分参数说明

    crontab file [-u user]-用指定的文g替代目前的crontab?

    crontab-[-u user]-用标准输入替代目前的crontab.

    crontab-1[user]-列出用户目前的crontab.

    crontab-e[user]-~辑用户目前的crontab.

    crontab-d[user]-删除用户目前的crontab.

    crontab-c dir- 指定crontab的目录?

    crontab文g的格式:M H D m d cmd.

    M: 分钟Q?-59Q?

    HQ小Ӟ0-23Q?

    DQ天Q?-31Q?

    m: 月(1-12Q?

    d: 一星期内的天(0~6Q?为星期天Q?

    cmd要运行的E序Q程序被送入sh执行Q这个shell只有USER,HOME,SHELLq三个环境变量?

    下面是一个例子文Ӟ

    #MIN HOUR DAY MONTH DAYOFWEEK COMMAND
                #每天早上6?
                106* * * date
                #每两个小?
                0*/2* * * date
                #晚上11点到早上8点之间每两个时Q早上部?
                0 23-7/2Q?* * * date
                #每个月的4号和每个C拜的礼拜一到礼拜三的早?1?
                0 11 4* mon-wed date
                #1月䆾日早??
                0 4 1 jan* date
                范例
                lark:~>crontab-1 列出用户目前的crontab.
                #MIN HOUR DAY MONTH DAYOFWEEK COMMAND
                10 6* * * date
                0*/2* * * date
                0 23-7/2,8 * * * date
                lark:~>

    Q责ȝ辑:云子Q?



    ]]>
    Linux定时dpȝCron入门http://www.dentisthealthcenter.com/lingy/archive/2009/07/09/286135.html林光?/dc:creator>林光?/author>Thu, 09 Jul 2009 10:38:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/07/09/286135.htmlcron是一个linux下的定时执行工具Q可以在无需人工q预的情况下q行作业。由于Cron 是Linux的内|服务,但它不自动v来,可以用以下的Ҏ启动、关闭这个服务:

     

    /sbin/service crond start //启动服务

    /sbin/service crond stop //关闭服务

    /sbin/service crond restart //重启服务

    /sbin/service crond reload //重新载入配置

     

     

    你也可以这个服务在pȝ启动的时候自动启动:

     

    ?etc/rc.d/rc.localq个脚本的末֊上:

    /sbin/service crond start

     

    现在Cronq个服务已经在进E里面了Q我们就可以用这个服务了QCron服务提供以下几种接口供大家用:

     

    1.直接用crontab命o~辑

     

    cron服务提供crontab命o来设定cron服务的,以下是这个命令的一些参C说明Q?/p>

     

    crontab -u //讑֮某个用户的cron服务Q一般root用户在执行这个命令的时候需要此参数

     

    crontab -l //列出某个用户cron服务的详l内?/p>

     

    crontab -r //删除没个用户的cron服务

     

    crontab -e //~辑某个用户的cron服务

     

    比如说root查看自己的cron讄Qcrontab -u root -l

     

    再例如,root惛_除fred的cron讄Qcrontab -u fred -r

     

    在编辑cron服务Ӟ~辑的内Ҏ一些格式和U定Q输入:crontab -u root -e

     

    q入vi~辑模式Q编辑的内容一定要W合下面的格式:*/1 * * * * ls >> /tmp/ls.txt

     

    q个格式的前一部分是对旉的设定,后面一部分是要执行的命令,如果要执行的命o太多Q可以把q些命o写到一个脚本里面,然后在这里直接调用这个脚本就可以了,调用的时候记得写出命令的完整路径。时间的讑֮我们有一定的U定Q前面五?号代表五个数字,数字的取D围和含义如下Q?/p>

     

    分钟 Q?-59Q?/p>

     

    時 Q?-23Q?/p>

     

    日期 Q?-31Q?/p>

     

    月䆾 Q?-12Q?/p>

     

    星期 Q?-6Q?/0代表星期?/p>

     

    除了数字q有几个个特D的W号是"*"?/"?-"?,"Q?代表所有的取D围内的数字,"/"代表每的意?"*/5"表示?个单位,"-"代表从某个数字到某个数字,","分开几个L的数字。以下D几个例子说明问题Q?/p>

     

    每天早上6?/p>

     

    0 6 * * * echo "Good morning." >> /tmp/test.txt //注意单纯echoQ从屏幕上看不到M输出Q因为cron把Q何输出都email到root的信׃?/p>

     

    每两个小?/p>

     

    0 */2 * * * echo "Have a break now." >> /tmp/test.txt

     

    晚上11点到早上8点之间每两个时Q早上八?/p>

     

    0 23-7/2Q? * * * echo "Have a good dreamQ)" >> /tmp/test.txt

     

    每个月的4号和每个C拜的礼拜一到礼拜三的早?1?/p>

     

    0 11 4 * 1-3 command line

     

    1?日早??/p>

     

    0 4 1 1 * command line

     

    每次~辑完某个用Lcron讄后,cron自动?var/spool/cron下生成一个与此用户同名的文gQ此用户的cron信息都记录在q个文g中,q个文g是不可以直接~辑的,只可以用crontab -e 来编辑。cron启动后每q一份钟Mơ这个文Ӟ查是否要执行里面的命令。因此此文g修改后不需要重新启动cron服务?/p>

     

    2.~辑/etc/crontab 文g配置cron

     

    cron服务每分钟不仅要M?var/spool/cron内的所有文Ӟq需要读一?etc/crontab,因此我们配置q个文g也能q用 cron服务做一些事情。用crontab配置是针Ҏ个用LQ而编?etc/crontab是针对系l的d。此文g的文件格式是Q?/p>

     

    SHELL=/bin/bash

    PATH=/sbin:/bin:/usr/sbin:/usr/bin

    MAILTO=root //如果出现错误Q或者有数据输出Q数据作为邮件发l这个帐?/p>

    HOME=/ //使用者运行的路径,q里是根目录

    # run-parts

    01 * * * * root run-parts /etc/cron.hourly //每小时执?etc/cron.hourly内的脚本

    02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本

    22 4 * * 0 root run-parts /etc/cron.weekly //每星期执?etc/cron.weekly内的脚本

    42 4 1 * * root run-parts /etc/cron.monthly //每月L?etc/cron.monthly内的脚本

     

    大家注意"run-parts"q个参数了,如果Lq个参数的话Q后面就可以写要q行的某个脚本名Q而不是文件夹名了



    ]]>
    over partition by与group by 的区?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284658.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Mon, 29 Jun 2009 11:04:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284658.html</guid><description><![CDATA[<div id="message10586007" class="t_msgfont">各位好!<br /> over partition by ?group by 都是与统计类函数用,q两个有什么区别呢Q?br /> 目前我只知道一个这L区别Q?br /> 比如有一张表saraly:CREATE TABLE SALARY AS SELECT 'A' NAME,10 DEPT,1000 SALARY FROM DUAL UNION ALL SELECT 'B',10,2000 FROM DUAL UNION ALL SELECT 'C' ,20,1500 FROM DUAL UNION ALL SELECT 'D',20,3000 FROM DUAL UNION ALL<br /> SELECT 'E',10,1000 FROM DUAL;<br /> NAME DEPT SALARY<br /> A         10     1000<br /> B         10     2000<br /> C         20     1500<br /> D         20     3000<br /> E         10     1000   <br /> 用over partition by 我就可以查询到每位员工本来的具体信息和它所在部门的d资:<br /> select name,dept,salary,sum(salary) over (partition by dept) total_salary from salary;  <br /> name       dept         salary      tatal_salary<br /> A        10        1000        4000<br /> B        10        2000        4000<br /> E        10        1000        4000<br /> C        20        1500        4500<br /> D        20        3000        4500<br /> <br /> 用goup by 没办法做到q点Q只能查询到每个部门的d资:<br /> select dept,sum(salary) total_salary from salary group by dept<br /> dept        total_salary<br /> 10        4000<br /> 20        4500<br /> 另外over partion by q可以做到查询每位员工占部门d资的癑ֈ比:<br /> select name,dept,salary,salary*100/sum(salary) over (partition by dept) percent from salary;<br /> <br /> name       dept         salary     percent<br /> A        10        1000        25<br /> B        10        2000        50<br /> E        10        1000        25<br /> C        20        1500        33.3333333333333<br /> D        20        3000        66.6666666666667<br /> 用group by 也没办法做到q个.不知道我的理解正不正,请各位朋友指点,特别是over partition by 与group by 的更多区别请各位一起分享,谢谢Q?br /> <br /> 20        4500<br /> <br /> </div> <img src ="http://www.dentisthealthcenter.com/lingy/aggbug/284658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2009-06-29 19:04 <a href="http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle中的NULLQ八Q?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284559.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Mon, 29 Jun 2009 02:59:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284559.html</guid><description><![CDATA[<p style="text-indent: 21pt"><span style="font-family: 宋体">最q在论坛上经常看刎ͼ很多人提出和<span lang="EN-US">NULL有关的问题。NULL其实是数据库中特有的cdQOracle中很多容易出现的错误都是和NULL有关的?/span></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">打算单的ȝ一?span lang="EN-US">NULL的相关知识?/span></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">q一描qC下在<span lang="EN-US">SQL和PLSQL中一些处理NULL的一些问题?/span></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULLQ一Q:<a >http://yangtingkun.itpub.net/post/468/244434</a></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULLQ二Q:<a >http://yangtingkun.itpub.net/post/468/245107</a></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULLQ三Q:<a >http://yangtingkun.itpub.net/post/468/245259</a></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULLQ四Q:<a >http://yangtingkun.itpub.net/post/468/245697</a></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULLQ五Q:<a >http://yangtingkun.itpub.net/post/468/247492</a></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULLQ六Q:<a >http://yangtingkun.itpub.net/post/468/251496</a></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">Oracle中的NULLQ七Q:<a >http://yangtingkun.itpub.net/post/468/258467</a></span></p> <p style="text-indent: 21pt"></p> <br /> <span style="display: none">8\![ Q!x;]$Yf0</span> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">NULL的最大的特点是两个NULL是不相等的。如果用{号来判断两个NULL是否相等得到的结果一定是NULL。从唯一U束的特点也可以看到Q对于徏立了唯一U束的列QOracle允许插入多个NULL|q时因ؓOracle不认些NULL是相{的?/span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> CREATE TABLE T (ID NUMBER, CONSTRAINT UN_T UNIQUE(ID));</font></span></p> <p><span style="font-size: 10.5pt"><font face="宋体">表已创徏?/font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> INSERT INTO T VALUES (1);</font></span></p> <p><span style="font-size: 10.5pt"><font face="宋体">已创?span lang="EN-US"> 1 行?/span></font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> INSERT INTO T VALUES (1);<br /> <span style="display: none">| Pw6I)A#P,x_0</span>INSERT INTO T VALUES (1)<br /> <span style="display: none">+h:w|3~ N0</span>*<br /> <span style="display: none">LCB-P#b{$C0</span>ERROR 位于W?1 ?<br /> <span style="display: none">f9i vJ Y%T0</span>ORA-00001: q反唯一U束条g (YANGTK.UN_T)</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><br /> <span style="display: none">&rSq _0P7QvYN0</span><font face="宋体">SQL> INSERT INTO T VALUES (NULL);</font></span></p> <p><span style="font-size: 10.5pt"><font face="宋体">已创?span lang="EN-US"> 1 行?/span></font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> INSERT INTO T VALUES (NULL);</font></span></p> <p><span style="font-size: 10.5pt"><font face="宋体">已创?span lang="EN-US"> 1 行?/span></font></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">但是有的时候,<span lang="EN-US">Oracle会认为NULL是相同的Q比如在GROUP BY和DISTINCT操作中。这个时候,Oracle会认为所有的NULL都是一cȝ?/span></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">q有一U情况,是?span lang="EN-US">DECODE函数中。如果表辑ּ为DECODE(COL, NULL, 0, 1)Q那么如果COL的gؓNULLQOracle会认U情况与W二个参数的NULL值相匚wQ会q回0。不q这里只是给人感觉NULL值是相等的,Oracle在实现DECODE函数的时候,仍然是通过IS NULL的方式进行的判断?/span></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">对于大多数的常用函数来说Q如果输入ؓ<span lang="EN-US">NULLQ则输出也是NULL。NVL、NVL2、DECODE和||操作是个例外。他们在输入参数为NULL的时候,l果可能不是NULL。不q归l其原因是因为,q些函数都有多个参数Q当多个参数不全为NULLӞl果可能不是NULLQ如果输入参数均为NULLQ那么得到的输出l果也是NULL?/span></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体" lang="EN-US">NULLq有一个特点,是一般聚集函C会处理NULL倹{不是MAX、MIN、AVGq是SUMQ这些聚集函数都不会处理NULL。注意这里说的不会处理NULLQ是指聚集函C直接忽略NULLD录的存在。除非是聚集函数处理的列中包含的全部记录都是NULLQ这U情况下Q上面这些聚集函Cq回NULL倹{?/span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> DELETE T WHERE ID = 1;</font></span></p> <p><span style="font-size: 10.5pt"><font face="宋体">已删?span lang="EN-US"> 1 行?/span></font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> SELECT NVL(TO_CHAR(ID), 'NULL') FROM T;</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">NVL(TO_CHAR(ID),'NULL')<span style="display: none">ITPUB个hI间 Z,I Pa;o~)t/Tm7L</span><br /> ----------------------------------------<br /> <span style="display: none">L B d-f-A/o*c0</span>NULL<span style="display: none">ITPUB个hI间(C"}5Q5A#L#t</span><br /> NULL</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> SELECT MAX(ID) FROM T;</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">MAX(ID)<br /> <span style="display: none">!C Cs"Ys5|'`0</span>----------</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><br /> <span style="display: none">G_S.c d5mk)O#c0</span><font face="宋体">SQL> SELECT AVG(ID) FROM T;</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">AVG(ID)<span style="display: none">ITPUB个hI间*O.Ylk0OU(Oy4Dq$vQr</span><br /> ----------</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><br /> <span style="display: none">RFf+Lf{] y0</span><font face="宋体">SQL> INSERT INTO T VALUES (1);</font></span></p> <p><span style="font-size: 10.5pt"><font face="宋体">已创?span lang="EN-US"> 1 行?/span></font></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">聚集函数中比较特D的?span lang="EN-US">COUNTQ第一个特D点是COUNT不会q回NULL|即表中没有记录Q或者COUNT(COL)中,COL列的记录全ؓNULLQCOUNT也会q回0D不是NULL。第二个Ҏ点就是COUNT(*)或COUNT(帔R)的Ş式。这UŞ式得COUNT可以计算包含NULL记录在内的记录L?/span></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> SELECT COUNT(*), COUNT(1), COUNT('A'), COUNT(ID), COUNT(NULL) FROM T;</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">COUNT(*) COUNT(1) COUNT('A') COUNT(ID) COUNT(NULL)<span style="display: none">ITPUB个hI间-NNOH2z</span><br /> ---------- ---------- ---------- ---------- -----------<br /> <span style="display: none">;s t:O8t3o.y0t0</span> 3 3 3 1 0</font></span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">最后简单说一?span lang="EN-US">AVGQAVG(COL){h于SUM(COL)/COUNT(COL)Q不{h于SUM(COL)/COUNT(*)Q?/span></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">SQL> SELECT AVG(ID), SUM(ID)/COUNT(ID), SUM(ID)/COUNT(*) FROM T;</font></span></p> <p><span style="font-size: 10.5pt" lang="EN-US"><font face="宋体">AVG(ID) SUM(ID)/COUNT(ID) SUM(ID)/COUNT(*)<br /> <span style="display: none">6~{9O*mL9C7c)p0</span>---------- ----------------- ----------------<br /> <span style="display: none">6@:[S'L&k\&V9{VR0</span> 1 1 .333333333</font></span></p> <p style="text-indent: 21pt"></p> <p style="text-indent: 21pt"></p> <br /> <img src ="http://www.dentisthealthcenter.com/lingy/aggbug/284559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2009-06-29 10:59 <a href="http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>能否按照DECODE条g来COUNTQ?Q?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284556.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Mon, 29 Jun 2009 02:57:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284556.html</guid><description><![CDATA[<p>表A   <br />       DW               WP             BJ   <br />       Q-Q-Q-Q-Q-Q-Q-Q-   <br />       A                 M1             Y   <br />       B                 M2             N   <br />       C                 M3             Y   <br />       D                 M1             Y   <br />     <br />   我向l计BJ?Y‘的DW有多个和总DW多少个?Q?  <br />     我用COUNT(DW),COUNT(DECODE(A.BJ,'Y',DW,0))   <br />   q样不行啊?Q?  <br />   SQL应该怎么写啊Q?Q不要用兼套语句Q这样太|嗦?<span>问题ҎQ?0、回复次敎ͼ3</span><a >Top</a> </p> <div class="tagad"><iframe src="/Include/Board.htm?Tags=" frameborder="0" scrolling="no"></iframe></div> <h3><strong><a class="anchor" name="r_34342834">1 ?/a>Visual_Studio_NetQ打鼠英雄)<input class="user5" title="五用户 该版得分于{于5000分,大于2000? type="button" /></strong><span>回复?2006-04-22 20:08:49 得分 <em>15</em></span></h3> <p>SELECT   COUNT(DW),SUM(DECODE(BJ,'Y',1,0))   FROM   A<a >Top</a></p> <h3><strong><a class="anchor" name="r_34342852">2 ?/a>chliang315Q)<input class="user3" title="三用户 该版得分于{于1000分,大于500? type="button" /></strong><span>回复?2006-04-22 20:11:32 得分 <em>35</em></span></h3> <p>可以?  <br />   COUNT(DW),COUNT(DECODE(A.BJ,'Y',DW,null))<a >Top</a></p> <h3><strong><a class="anchor" name="r_34342979">3 ?/a>bbcboyQ烦猪哥哥)<input class="user1" title="一U用?该版得分于{于100? type="button" /></strong><span>回复?2006-04-22 20:30:58 得分 0 </span></h3> <p>两位都是好h啊!Q?  <br />   非常感谢Q!   <br />   </p> <img src ="http://www.dentisthealthcenter.com/lingy/aggbug/284556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2009-06-29 10:57 <a href="http://www.dentisthealthcenter.com/lingy/archive/2009/06/29/284556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ant+cactus+tomcat5.5容器内单元测?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2009/06/22/283575.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Mon, 22 Jun 2009 07:06:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2009/06/22/283575.html</guid><description><![CDATA[ 一、下载ƈ解压~cactus<br />   下蝲地址为http://Java.chinaitlab.com/tools/45970.Html 。将cactus的lib目录下的cactus-ant-1.7.1.jar复制到ant的lib目录?br />   二、配|cactus<br />   cactus的配|很单,新徏一个cactus.properties文gQƈ把它攑֜ant脚本中的cactusd的classpath下,文g中包括如下内?br />   cactus.sysproperties=cactus.contextURL<br highlighted="1" />   #cactus-sample-servlet-cactified是你的试应用所在\径,8080?zmkey style="border-bottom: #ff6c00 2px dotted; float: none; cursor: pointer; font-weight: bold; margin-right: 3px; cssfloat: none" class="zoomino-searchword" offset="52" path="body > div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(4)" anchorType="previous" jQuery1245654007453="6">端口?img style="border-bottom: medium none; border-left: medium none; padding-bottom: 0px; margin: 0px; padding-left: 0px; width: 12px; padding-right: 0px; display: inline; background-position: -18px -23px; float: none; height: 14px; border-top: medium none; border-right: medium none; padding-top: 0px; cssfloat: none" class="zoominoBgImage" src="http://static.zoomino.cn/static-ox/images/blank.gif" width="1" height="1" alt="" /></zmkey><br />   cactus.contextURL = http://localhost:8080/cactus-sample-servlet-cactified<br />   cactus.servletReDirectorName = ServletRedirector<br />   cactus.jspRedirectorName = JspRedirector<br />   cactus.filterRedirectorName = FilterRedirector <br />   具体的做法结合ant脚本再进一步解释?br />   三、运行ant脚本<br />    ant脚本主要执行以下d<br />   1、设定classpath<br />   <path id="project.classpath"><br />    <fileset dir="${lib.dir}"><br />    <include name="*.jar"/><br />    </fileset><br />    <!-- cactus.properties文g需要放在lib.dir所对应的\径中 --><br />    <pathelement location="${lib.dir}"/><br />    <pathelement location="${tomcat.home}/common/lib/jsp-api.jar"/><br />    <pathelement location="${tomcat.home}/common/lib/servlet-api.jar"/><br />    </path><br />   2、定义相关Q?br />   <taskdef resource="cactus.tasks" classpathref="project.classpath"/><br />    <taskdef name="runservertests" classname="org.apache.cactus.integration.ant.RunServerTestsTask"><br />    <classpath><br />    <path refid="project.classpath"/><br />    </classpath><br />    </taskdef><br />   3、编译应用的cL件和试的类文g<br />   4、打包整个应用ؓwar文g<br />   需要注重的是,不仅要打包应用类Q测试类也要打包<br />   <target name="war" depends="compile.java"<br />    description="Generate the runtime war"><br />    <war warfile="${target.dir}/${project.name}.war"<br />    webXML="${src.webapp.dir}/WEB-INF/web.xml"><br />    <fileset dir="${src.webapp.dir}"><br />    <exclude name="cactus-report.xsl"/><br />    <exclude name="WEB-INF/cactus-web.xml"/><br />    <exclude name="WEB-INF/web.xml"/><br />    </fileset><br />    <classes dir="${target.classes.java.dir}"/><br />    <!-- 别忘了打包测试类 --><br />    <classes dir="${target.classes.test.dir}"/><br />    <!-- 别忘了打包各U相关的jar文g --><br />    < lib dir="project.classpath"/><br />    </war><br />    </target><br />   5、在应用的web.xml文g中添加测试所需的各U映?br />   cactus提供了两个task来完成这个工作,CactifyWar和WebXmlMerge?br />   CactifyWar的功能是自动在已l打包的应用的web.xml文g中添加所需的映。WebXmlMerge是提供合q两个web.xml文g的功能?br />   <target name="test.prepare"<br />    depends="war, compile.cactus, test.prepare.logging"><br />    <!-- Cactify the web-app archive --><br />    <cactifywar srcfile="${target.dir}/${project.name}.war"<br />    destfile="${tomcat.home}/webapps/${project.name}-cactified.war"<br />    ><br />    <classes dir="${target.classes.java.dir}"/><br />    <classes dir="${target.classes.test.dir}"/><br />    <lib dir="project.classpath"/><br />    </cactifywar><br />   </target><br />   6、运行测?br />   cactus提供了cactus和RunServerTests两个task来运行测试?br highlighted="1" />   "cactus" task是通过复制容器服务器的最文件ƈq行来运行测试,因此需要制定容器服务器的类型,启动速度E快点,另外配置比较方便Q但是无法测试象tomcat<zmkey style="border-bottom: #ff6c00 2px dotted; float: none; cursor: pointer; font-weight: bold; margin-right: 3px; cssfloat: none" class="zoomino-searchword" offset="84" path="body > div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(64)" anchorType="previous" jQuery1245654007453="7">q接?img style="border-bottom: medium none; border-left: medium none; padding-bottom: 0px; margin: 0px; padding-left: 0px; width: 12px; padding-right: 0px; display: inline; background-position: -18px -23px; float: none; height: 14px; border-top: medium none; border-right: medium none; padding-top: 0px; cssfloat: none" class="zoominoBgImage" src="http://static.zoomino.cn/static-ox/images/blank.gif" width="1" height="1" alt="" /></zmkey>{资源。另外对tomcat5.5的支持也不好?br />   "RunServerTests"是通过直接启动容器服务hq行试Q因此速度E慢Q且配置较麻烦,但能试各种资源?br />   <target name="test" depends="test.prepare"<br />    description="Run tests on Tomcat "><br />    <!-- Start the servlet engine, wait for it to be started, run the<br />    unit tests, stop the servlet engine, wait for it to be stopped.<br />    The servlet engine is stopped if the tests fail for any reason --><br />    <!-- 8080是服务器的端口号Q?{project.name}-cactified是项目的路径Q和上一步的cactifywar 的destfile相对?--><br />    <runservertests<br />    testURL="http://localhost:8080/${project.name}-cactified/ServletRedirector?Cactus_Service=RUN_TEST"<br />    startTarget="_StartTomcat"<br />    stopTarget="_StopTomcat"<br />    testTarget="_Test"/><br />    </target><br />   <!-- _Test是一个普通的junitd --><br />    <target name="_Test"><br />    <junit printsummary="yes" fork="yes"><br />    <classpath><br />    <path refid="project.classpath"/><br />    <pathelement location="${target.classes.java.dir}"/><br />    <pathelement location="${target.classes.test.dir}"/><br />    </classpath><br />    <formatter type="brief" usefile="false"/><br />    <formatter type="xml"/><br />    <batchtest><br />    <fileset dir="${src.test.dir}"><br />    <!-- Due to some Cactus synchronization bug, the 'unit' tests need<br />    to run before the 'sample' tests --><br />    <include name="**/Test*.java"/><br />    <exclude name="**/Test*All.java"/><br />    </fileset><br />    </batchtest><br />    </junit><br />    </target><br />   文章来源: baike.duba.net <img src ="http://www.dentisthealthcenter.com/lingy/aggbug/283575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2009-06-22 15:06 <a href="http://www.dentisthealthcenter.com/lingy/archive/2009/06/22/283575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>lservlet写单元测试的ȝhttp://www.dentisthealthcenter.com/lingy/archive/2009/06/22/283551.html林光?/dc:creator>林光?/author>Mon, 22 Jun 2009 05:39:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/06/22/283551.html lservlet写单元测试的ȝ收藏
    servlet的测试一般来说需要容器的支持Q不是像通常的javacȝjunit试一L单,
     
    下面通过对HelloWorld代码的测试阐qC几种servlet试Ҏ?br />  
    被测试的HelloWorldcȝ代码如下Q?br />  
    /**
     * 被测试的servlet
     */

    import java.io.IOException;
     
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.cactus.WebRequest;
    import org.apache.cactus.server.HttpServletRequestWrapper;
     
    public class HelloWorld extends HttpServlet{
     
     public void saveToSession(HttpServletRequest request) {

             request.getSession().setAttribute("testAttribute",request.getParameter("testparam"));

     }
     
     public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException{

             String username=request.getParameter("username");

             response.getWriter().write(username+":Hello World!");
           
     }
     
     public boolean authenticate(){
            
            return true;
     
     }

    }
     
    以HelloWorldZQ我ȝ了Servlet的多U测试方法如下:
     
    一.使用HttpUnit试
     
    import com.meterware.httpunit.GetMethodWebRequest;
    import com.meterware.httpunit.WebRequest;
    import com.meterware.httpunit.WebResponse;
    import com.meterware.servletunit.InvocationContext;
    import com.meterware.servletunit.ServletRunner;
    import com.meterware.servletunit.ServletUnitClient;
    import junit.framework.Assert;
    import junit.framework.TestCase;
     
    public class HttpUnitTestHelloWorld extends TestCase {
     
     protected void setUp() throws Exception {
      super.setUp();
     }
     
     protected void tearDown() throws Exception {
      super.tearDown();
     }
     
     public void testHelloWorld() {
     
      try {

       // 创徏Servlet的运行环?/p>

       ServletRunner sr = new ServletRunner();

       // 向环境中注册Servlet

       sr.registerServlet("HelloWorld", HelloWorld.class.getName());
     
       // 创徏讉KServlet的客L

       ServletUnitClient sc = sr.newClient();

       // 发送请?/p>

       WebRequest request = new GetMethodWebRequest("http://localhost/HelloWorld");
       request.setParameter("username", "testuser");

       InvocationContext ic = sc.newInvocation(request);

       HelloWorld is = (HelloWorld) ic.getServlet();
     
       // 试servlet的某个方?/p>

       Assert.assertTrue(is.authenticate());

       // 获得模拟服务器的信息

       WebResponse response = sc.getResponse(request);

       // 断言

       Assert.assertTrue(response.getText().equals("testuser:Hello World!"));

      } catch (Exception e) {

       e.printStackTrace();

      }

     }
     
    }
     
    上述例子其实是junit的一个测试例子,在其中用了httpunit模拟的servlet环境,使用上述Ҏ试
     
    servlet可以q容器Q容易把该测试写入ant或maven脚本Q让试q行?br />  
    httpunit|址Qhttp://httpunit.sourceforge.net/
     
    使用该种Ҏ试的弱点就是:如果要用request(response)的setCharercterEncodingҎӞ试会出C些问?
     
    而且httpunit在测试servlet行ؓӞ采用的是完全模拟览器,有时试比较隑ֆ?br />  
    ?使用cactus试
     
    /**
     * cactus试servlet的例?br />  * 必须要有tomcat的支?br />  *
     */
     
    import junit.framework.Test;
    import junit.framework.TestSuite;
    import org.apache.cactus.ServletTestCase;
    import org.apache.cactus.WebRequest;
    import org.apache.cactus.WebResponse;
    public class CactusHelloWorld extends ServletTestCase{
     
         HelloWorld servlet;
         public CactusHelloWorld(String theName) {
             super(theName);
         }
     
         protected void setUp() throws Exception {
             super.setUp();
             servlet = new HelloWorld();
         }
     
         protected void tearDown() throws Exception {
             super.tearDown();
         }
     
         /**
          * 试Ҏ试参数在此讄
          *
          * @param webrequest
          */
     
         public void beginSaveToSessionOK(WebRequest request) {
             request.addParameter("testparam", "it works!");
         }
        
         /**
          * 试Ҏ试参数在此讄
          *
          * @param webrequest
          */
     
         public void beginDoGet(WebRequest request) {
             request.addParameter("username", "testuser");
         }
     
         /**
          * 调用servlet的测试方?br />       * 
          */

         public void testSaveToSessionOK() {
             servlet.saveToSession(request);
             assertEquals("it works!", session.getAttribute("testAttribute"));
         }
     
         public void testDoGet() {
             try {
                 servlet.doGet(request, response);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     
         /**
          * 此方法可以判断测试方法的输出Q会传递测试方法的reponselend***,q且格式化ؓcactus
          * 的WebResponse或者可以跟httpunit集成Q格式化为httpunit的response
          *
          * @param response
          */

         public void endDoGet(WebResponse response) {
             String content;        
             content = response.getText();
             assertEquals("testuser:Hello World!", content);
         }
    }
     
    cactus具备丰富灉|的测试功能,如要试doGetҎQ分为beginDoGet(模拟试参数讄)、DoGet(执行试)、endDoGet(状态结果验?
     
    相比httpunit来说Q写试更ؓҎQ测试servlet更ؓ专业,程更ؓ清晰Q但是cactus需要容器支持,使得试不可以自动进行,但是
     
    如果使用一个嵌入式的容器,试可以自动了?br />  
    cactus是一个servlet和jsp的测试框?http://jakarta.apache.org/cactus/getting_started.html
     
    ?使用Jetty作ؓ嵌入式容器测试servlet.
     
    /**
     * 一个关于嵌入式jetty试的例子,jetty作ؓstubs的一个例?br />  *
     */
    package com.easyjf.testexample;
     
    import org.mortbay.jetty.Connector;
    import org.mortbay.jetty.Server;
    import org.mortbay.jetty.bio.SocketConnector;
    import org.mortbay.jetty.servlet.ServletHandler;
     
    import com.meterware.httpunit.WebClient;
    import com.meterware.httpunit.WebConversation;
    import com.meterware.httpunit.WebResponse;
     
    import junit.framework.Assert;
    import junit.framework.TestCase;
     
    public class JettySampleTest extends TestCase {
     
     Server server;
     protected void setUp() throws Exception {
          //通过代码讄q启动一个服务器Q该服务器是servlet的测试容?br />       super.setUp();
          server = new Server();
          Connector connector=new SocketConnector();
          connector.setPort(80);
          server.setConnectors(new Connector[]{connector});
          ServletHandler handler=new ServletHandler();
          server.setHandler(handler);
          handler.addServletWithMapping("HelloWorld", "/");
          server.start();
     }
     
     protected void tearDown() throws Exception {
      super.tearDown();
      server.stop();
     }
     
     public void testHellWorld() {
      try {
       WebConversation wc = new WebConversation();
       WebResponse web = wc.getResponse("http://127.0.0.1/HelloWorld");
       String result=web.getText();
       Assert.assertEquals(result,"it works!");
      } catch (Exception e) {
       e.printStackTrace();
      }
     }
    }
     
    可以发现Qjetty可以充当一个servlet的容器,方便的是,jetty支持嵌入式服务,卛_以通过代码来启动,
     
    所以要写自动测试的例子很方便,可以l合httpunit或者cactusq行servlet试?br />  
    jetty主页Qhttp://docs.codehaus.org/display/JETTY/Embedding+Jetty


    ?使用mock对象Q此处用easymock
     
    import java.io.PrintWriter;
    import java.io.Writer;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    import junit.framework.Assert;
    import junit.framework.TestCase;
    import static org.easymock.EasyMock.*;
    public class MockTestServlet extends TestCase {
     
        public void testService() throws Exception {

            System.out.println("service");

            HttpServletRequest request = createMock(HttpServletRequest.class);

            HttpServletResponse response = createMock(HttpServletResponse.class);

            //Creating the ServletConfig mock here

            ServletConfig servletConfig = createMock(ServletConfig.class);

            //Creating the ServletContext mock here

            ServletContext servletContext = createMock(ServletContext.class);
           
            //Create the target object 
         
            HelloWorld4 instance = new HelloWorld();

            //初始化servlet,一般由容器承担Q一般调用servletConfig作ؓ参数初始化,此处模拟容器行ؓ

            instance.init(servletConfig);
     
            //在某些方法被调用时设|期望的q回|如下q样׃会去实际调用servletConfig的getServletContextҎQ而是直接q回
     
            //servletContext,׃servletConfig是mock出来的,所以可以完全控制?/p>

            expect(servletConfig.getServletContext()).andReturn(servletContext).anyTimes();

            expect(request.getParameter("username")).andReturn("testuser");

            PrintWriter pw=new PrintWriter(System.out,true);

            expect(response.getWriter()).andReturn(pw).anyTimes();
           
            //以上均是录制Q下面ؓ重放Q该U机制ؓeasymock试机制Q要理解Leasymock试的一些资?br />         replay(request);
            replay(response);
            replay(servletConfig);
            replay(servletContext);
     
            instance.doGet(request, response);

            pw.flush();
           
     
            //验证l果是否预期Q如果预期,则会在pw上写出testuser.
            verify(request);
            verify(response);
            verify(servletConfig);
            verify(servletContext);
       }
    }
     
    mock试注重行ؓQmock对象其实都是模拟的对象,Ҏ一般直接给Z个返回|没有具体的对象逻辑Qmock对象
     
    是用来帮助测试要试的类的。比如要试servlet的内部行为,又不惌容器{环境,可以采用mock试?br />  
    easymock是mock试的一个框Ӟhttp://www.easymock.org/
     
    发表?@ 2007q?2?0?22:13:00|评论(2)

    C? 设计模式之创建模?| 旧一? 服务定位器模?service locator)wldandanpig 发表?007q??4?10:09:40  IP:举报
    请问g
    public String saveInfo()
    {
    String reqInfo = request.getParameter("reqInfo");
    String sessInfo = (String)request.getSession().getAttribute("sessInfo");

    request.setAttribute("reqInfo" , "response:"+reqInfo);
    request.getSession().setAttribute("sessInfo", "response:"+reqInfo);

    return "SUCCESS";
    }
    q个Ҏ怎么试啊cz_hyf 发表?007q??4?17:20:23  IP:举报
    如果用httpunit的话

    public void testHelloWorld() {

    try {

    // 创徏Servlet的运行环?/p>

    ServletRunner sr = new ServletRunner();

    // 向环境中注册Servlet

    sr.registerServlet("HelloWorld", HelloWorld.class.getName());

    // 创徏讉KServlet的客L

    ServletUnitClient sc = sr.newClient();

    // 发送请?/p>

    WebRequest request = new GetMethodWebRequest("http://localhost/HelloWorld");
    request.setParameter("reqInfo", "......");

    InvocationContext ic = sc.newInvocation(request);

    HelloWorld is = (HelloWorld) ic.getServlet();

    // 试servlet的某个方?/p>

    Assert.assertEquals(is.saveInfo,"SUCCESS");

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    如果q不攑ֿQ不妨把request和request.session中的值取出来看看是否是你放进ȝ


    本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/cz_hyf/archive/2007/02/10/1507211.aspx



    ]]>
    oracle trunc()函数的用?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2009/06/19/283162.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Fri, 19 Jun 2009 01:39:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2009/06/19/283162.html</guid><description><![CDATA[<span class="bold"><span class="smalltxt">TRUNC()函數分兩E?img src="http://blog.csdn.net/Emoticons/tongue_smile.gif" alt="" /><br /> <br /> </span></span>1.TRUNC(for dates)<br />         TRUNC函数为指定元素而截ȝ日期倹{?br />         其具体的语法格式如下Q?br />         TRUNCQdate[,fmt]Q?br />         其中Q?br />         date        一个日期?br />         fmt                日期格式Q该日期由指定的元素格式所截去。忽略它则由最q的日期截去<br />         下面是该函数的用情况:<br />         TRUNCQTO_DATE(’24-Nov-1999 08:00 pm’,’dd-mon-yyyy hh:mi am’)Q?br />                 =’24-Nov-1999 12:00:00 am’<br />         TRUNCQTO_DATE(’24-Nov-1999 08:37 pm’,’dd-mon-yyyy hh:mi am’,’hh’)Q?nbsp;       =’24-Nov-1999 08:00:00 am’<br /> <br /> 2.TRUNC(for number)<br />         TRUNC函数q回处理后的数|其工作机制与ROUND函数极ؓcMQ只是该函数不对指定数前或后的部分做相应舍入选择处理Q而统l截厅R?br />         其具体的语法格式如下<br />         TRUNCQnumber[,decimals]Q?br />         其中Q?br />         number        待做截取处理的数?br />         decimals        指明需保留数点后面的位数。可选项Q忽略它则截L有的数部分<br />         下面是该函数的用情况:<br />         TRUNCQ?9.985Q?Q?89.98<br />         TRUNCQ?9.985Q?89<br />         TRUNCQ?9.985Q?1Q?80<br />         注意Q第二个参数可以敎ͼ表示为小数点左边指定位数后面的部分截去,卛_?记?<br /> <img src ="http://www.dentisthealthcenter.com/lingy/aggbug/283162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2009-06-19 09:39 <a href="http://www.dentisthealthcenter.com/lingy/archive/2009/06/19/283162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>oracle merge into 的用法详?实例 http://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283070.html林光?/dc:creator>林光?/author>Thu, 18 Jun 2009 08:10:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283070.htmloracle merge into 的用法详?实例
    oracle merge into 的用法详?实例

    作用Qmerge into 解决用B表跟新A表数据,如果A表中没有Q则把B表的数据插入A表;

    语法Q?/p>

    MERGE INTO [your table-name] [rename your table here]

    USING ( [write your query here] )[rename your query-sql and using just like a table]

    ON ([conditional expression here] AND [...]...)

    WHEN MATHED THEN [here you can execute some update sql or something else ]

    WHEN NOT MATHED THEN [execute something else here ! ]

    -------------------------------------实例-----------------------------------------------------------------

    merge into tfa_alarm_act_nms a
    using (select FP0,FP1,FP2,FP3,REDEFINE_SEVERITY
    from tfa_alarm_status) b
    on (a.fp0=b.fp0 and a.fp1=b.fp1 and a.fp2=b.fp2 and a.fp3=b.fp3)
    when matched then update set a.redefine_severity=b.redefine_severity
    when not matched then insert (a.fp0,a.fp1,a.fp2,a.fp3,a.org_severity,a.redefine_severity,a.event_time
    ,a.int_id)
    values (b.fp0,b.fp1,b.fp2,b.fp3,b.REDEFINE_SEVERITY,b.redefine_severity,sysdate,7777778);

    作用Q利用表 tfa_alarm_status跟新?font color="#0000ff">tfa_alarm_act_nms 的b.redefine_severityQ?/font>条g?font color="#0000ff">a.fp0=b.fp0 and a.fp1=b.fp1 and a.fp2=b.fp2 and a.fp3=b.fp3Q?/font>如果tfa_alarm_act_nms表中没有该条件的数据插入?/font>

    如果你的数据量很大,此sql效率非常高?/p>



    ]]>
    解析Q怎样使用Oracle的DECODE()函数 http://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283067.html林光?/dc:creator>林光?/author>Thu, 18 Jun 2009 08:08:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283067.html 

    DECODE()函数Q它输入数g函数中的参数列表相比较,Ҏ输入D回一个对应倹{函数的参数列表是由若干数值及其对应结果值组成的若干序偶形式。当Ӟ如果未能与Q何一个实参序偶匹配成功,则函C有默认的q回倹{?

    区别于SQL的其它函敎ͼDECODE函数q能识别和操作空倹{?

    语法QDECODE(control_value,value1,result1[,value2,result2…][,default_result]);

    control _value试图处理的数倹{DECODE函数该数g后面的一pd的偶序相比较Q以军_q回倹{?

    value1是一l成序偶的数倹{如果输入数g之匹配成功,则相应的l果被q回。对应一个空的返回|可以使用关键字NULL于之对应

    result1 是一l成序偶的结果倹{?

    default_result 未能与Q何一个值匹配时Q函数返回的默认倹{?

    例如Q?

    selectdecode( x , 1 , ‘x is 1 ’, 2 , ‘x is 2 ’, ‘others’) from dual

    当x{于1Ӟ则返?#8216;x is 1’?

    当x{于2Ӟ则返?#8216;x is 2’?

    否则Q返回others’?

    需要,比较2个值的时候,可以配合SIGN()函数一起用?

    SELECT DECODE( SIGN(5 -6), 1 'Is Positive', -1, 'Is Nagative', 'Is Zero')

    同样Q也可以用CASE实现Q?

    SELECT CASE SIGN(5 - 6)
                WHEN  1  THEN  'Is Positive'
                WHEN -1 THEN  'Is Nagative'
                ELSE 'Is Zero' END
                FROM DUAL

    此外Q还可以在Order by中用Decode?

    例如Q表table_subjectQ有subject_name列。要求按照:语、数、外的顺序进行排序。这Ӟ可以非常轻杄使用Decode完成要求了?

    select * from table_subject order by decode(subject_name, '语文', 1, '数学', 2, , '外语',3)Q责ȝ辑:卢兆林)



    ]]>
    怎样从一个过E返回一个结果集http://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283045.html林光?/dc:creator>林光?/author>Thu, 18 Jun 2009 06:22:00 GMThttp://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283045.htmlcreate or replace procedure p_stu_lst(result out sys_refcursor) is
    BEGIN
       OPEN RESULT FOR SELECT * FROM test;
    end p_stu_lst;
    SQL> select * from test;

    NAME       KM                 CJ
    ---------- ---------- ----------
    张三       语文               80
    张三       数学               86
    张三       p               75
    李四       语文               78
    李四       数学               85
    李四       p               78
    李四       物理               90

    已选择7行?br />
    SQL> exec p_stu_lst(:aaa);

    PL/SQL q程已成功完成?br />
    SQL> print aaa

    NAME       KM                 CJ
    ---------- ---------- ----------
    张三       语文               80
    张三       数学               86
    张三       p               75
    李四       语文               78
    李四       数学               85
    李四       p               78
    李四       物理               90

    已选择7行?/div>

    ]]>
    Oracle PL/SQL游标的学?/title><link>http://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283042.html</link><dc:creator>林光?/dc:creator><author>林光?/author><pubDate>Thu, 18 Jun 2009 06:11:00 GMT</pubDate><guid>http://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283042.html</guid><description><![CDATA[<div class="adgg"><a target="_blank">被过滤广?/a></div> <strong>一 游标是什?/strong> <br /> <br /> 游标字面理解是游动的光标?<br /> <br /> 用数据库语言来描qͼ游标是映在l果集中一行数据上的位|实体,有了游标Q用户就可以讉Kl果集中的Q意一行数据了Q将游标攄到某行后Q即可对该行数据q行操作Q例如提取当前行的数据等?<br /> <br /> <strong>?游标的分c?/strong> <br /> <br /> 昑ּ游标和隐式游?<br /> <br /> 昑ּ游标的用需?步: <br /> <br /> 1. 声明游标 <br /> <br /> <ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"> <pre><ccid_code>CURSOR mycur(vartype number) is select emp_no,emp_zc from cus_emp_basic where com_no = vartype;</ccid_code></pre> </td> </tr> </tbody> </table> </ccid_nobr><br /> <br /> 2. 打开游标 <br /> <br /> open mycur(000627) <br /> <br /> 注:000627是参?<br /> <br /> 3. d数据 <br /> <br /> fetch mycur into varno, varprice; <br /> <br /> 4. 关闭游标 <br /> <br /> close mycur; <br /> <br /> <strong>?游标的属?/strong> <br /> <br /> oracle 游标?个属性:%ISOPENQ?FOUNDQ?NOTFOUNDQ?ROWCOUNT?<br /> <br /> %ISOPEN判断游标是否被打开Q如果打开%ISOPEN{于true,否则{于falseQ?<br /> <br /> %FOUND %NOTFOUND判断游标所在的行是否有效,如果有效Q则%FOUNDD{于trueQ否则等于falseQ?<br /> <br /> %ROWCOUNTq回当前位置为止游标d的记录行数?<br /> <br /> <strong>?CZ</strong> <br /> <br /> <ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"> <pre><ccid_code>set serveroutput on; declare varno varchar2(20); varprice varchar2(20); CURSOR mycur(vartype number) is select emp_no,emp_zc from cus_emp_basic where com_no = vartype; begin if mycur%isopen = false then open mycur(000627); end if; fetch mycur into varno,varprice; while mycur%found loop dbms_output.put_line(varno||','||varprice); if mycur%rowcount=2 then exit; end if; fetch mycur into varno,varprice; end loop; close mycur; end;</ccid_code></pre> </td> </tr> </tbody> </table> </ccid_nobr><br /> <br /> PL/SQL记录的结构和C语言中的l构体类|是由一l数据项构成的逻辑单元?<br /> <br /> PL/SQL记录q不保存在数据库中,它与变量一P保存在内存空间中Q在使用记录时候,要首先定义记录结构,然后声明记录变量。可以把PL/SQL记录看作是一个用戯定义的数据类型?<br /> <br /> <ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"> <pre><ccid_code>set serveroutput on; declare type person is record ( empno cus_emp_basic.emp_no%type, empzc cus_emp_basic.emp_zc%type); person1 person; cursor mycur(vartype number)is select emp_no,emp_zc from cus_emp_basic where com_no=vartype; begin if mycur%isopen = false then open mycur(000627); end if; loop fetch mycur into person1; exit when mycur%notfound; dbms_output.put_line('雇员~号:'||person1.empno||',地址:'||person1.empzc); end loop; close mycur; end;</ccid_code></pre> </td> </tr> </tbody> </table> </ccid_nobr><br /> <br /> 典型游标for 循环 <br /> <br /> 游标for循环C显C游标的一U快捷用方式,它用for循环依次dl果集中的行数据Q当form循环开始时Q游标自动打开Q不需要openQ,每@环一ơ系l自动读取游标当前行的数据(不需要fetch)Q当退出for循环Ӟ游标被自动关闭(不需要用closeQ。用游标for循环的时候不能用open语句Qfetch语句和close语句Q否则会产生错误?<br /> <br /> <ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"> <pre><ccid_code>set serveroutput on; declare cursor mycur(vartype number)is select emp_no,emp_zc from cus_emp_basic where com_no=vartype; begin for person in mycur(000627) loop dbms_output.put_line('雇员~号:'||person.emp_no||',地址:'||person.emp_zc); end loop; end;</ccid_code></pre> </td> </tr> </tbody> </table> </ccid_nobr><br /> <img src ="http://www.dentisthealthcenter.com/lingy/aggbug/283042.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.dentisthealthcenter.com/lingy/" target="_blank">林光?/a> 2009-06-18 14:11 <a href="http://www.dentisthealthcenter.com/lingy/archive/2009/06/18/283042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <a href="http://www.dentisthealthcenter.com/">久久一级片</a> <div style="position:fixed;left:-9000px;top:-9000px;"><video id="395jp"><font id="395jp"><font id="395jp"><video id="395jp"></video></font></font></video><meter id="395jp"><video id="395jp"></video></meter><nobr id="395jp"></nobr><dl id="395jp"><i id="395jp"></i></dl><nobr id="395jp"><nobr id="395jp"></nobr></nobr><dl id="395jp"></dl><delect id="395jp"><font id="395jp"></font></delect><meter id="395jp"><font id="395jp"></font></meter><noframes id="395jp"></noframes><i id="395jp"><i id="395jp"></i></i><meter id="395jp"></meter><i id="395jp"></i><noframes id="395jp"><noframes id="395jp"></noframes></noframes><noframes id="395jp"><noframes id="395jp"><video id="395jp"><video id="395jp"></video></video></noframes></noframes><font id="395jp"></font><video id="395jp"><noframes id="395jp"></noframes></video><dl id="395jp"></dl><font id="395jp"><meter id="395jp"></meter></font><video id="395jp"><dl id="395jp"></dl></video><font id="395jp"><meter id="395jp"></meter></font><delect id="395jp"></delect><nobr id="395jp"><nobr id="395jp"></nobr></nobr><i id="395jp"><i id="395jp"><dl id="395jp"><i id="395jp"></i></dl></i></i><nobr id="395jp"><noframes id="395jp"></noframes></nobr><delect id="395jp"><font id="395jp"><font id="395jp"><meter id="395jp"></meter></font></font></delect><meter id="395jp"><nobr id="395jp"></nobr></meter><meter id="395jp"><nobr id="395jp"><nobr id="395jp"><nobr id="395jp"></nobr></nobr></nobr></meter><delect id="395jp"><delect id="395jp"></delect></delect><delect id="395jp"><delect id="395jp"><meter id="395jp"><nobr id="395jp"></nobr></meter></delect></delect><i id="395jp"></i><nobr id="395jp"><meter id="395jp"><nobr id="395jp"><nobr id="395jp"></nobr></nobr></meter></nobr><dl id="395jp"><i id="395jp"></i></dl><nobr id="395jp"><video id="395jp"></video></nobr><video id="395jp"><nobr id="395jp"><dl id="395jp"><video id="395jp"></video></dl></nobr></video><i id="395jp"><i id="395jp"></i></i><dl id="395jp"></dl><font id="395jp"><font id="395jp"></font></font><dl id="395jp"></dl><font id="395jp"></font><i id="395jp"><meter id="395jp"><meter id="395jp"><font id="395jp"></font></meter></meter></i><meter id="395jp"></meter><meter id="395jp"><video id="395jp"><video id="395jp"><dl id="395jp"></dl></video></video></meter><delect id="395jp"></delect><meter id="395jp"><nobr id="395jp"><nobr id="395jp"><nobr id="395jp"></nobr></nobr></nobr></meter><noframes id="395jp"></noframes><dl id="395jp"></dl><font id="395jp"><font id="395jp"></font></font><font id="395jp"><meter id="395jp"></meter></font><noframes id="395jp"></noframes><delect id="395jp"><delect id="395jp"></delect></delect> <video id="395jp"></video><i id="395jp"><dl id="395jp"><font id="395jp"><i id="395jp"></i></font></dl></i><dl id="395jp"><video id="395jp"><noframes id="395jp"><video id="395jp"></video></noframes></video></dl><font id="395jp"></font><noframes id="395jp"><i id="395jp"><font id="395jp"><delect id="395jp"></delect></font></i></noframes><delect id="395jp"><nobr id="395jp"></nobr></delect><dl id="395jp"><dl id="395jp"></dl></dl><meter id="395jp"><nobr id="395jp"><video id="395jp"><noframes id="395jp"></noframes></video></nobr></meter><dl id="395jp"><i id="395jp"><font id="395jp"><noframes id="395jp"></noframes></font></i></dl><i id="395jp"><video id="395jp"><nobr id="395jp"><nobr id="395jp"></nobr></nobr></video></i><noframes id="395jp"><nobr id="395jp"></nobr></noframes><font id="395jp"></font><i id="395jp"><i id="395jp"></i></i><delect id="395jp"></delect><nobr id="395jp"><noframes id="395jp"></noframes></nobr><i id="395jp"><i id="395jp"></i></i><i id="395jp"><font id="395jp"><meter id="395jp"><meter id="395jp"></meter></meter></font></i><font id="395jp"><font id="395jp"></font></font><delect id="395jp"><i id="395jp"><font id="395jp"><meter id="395jp"></meter></font></i></delect><noframes id="395jp"><noframes id="395jp"><noframes id="395jp"><dl id="395jp"></dl></noframes></noframes></noframes><noframes id="395jp"><video id="395jp"></video></noframes><noframes id="395jp"><noframes id="395jp"></noframes></noframes><noframes id="395jp"><dl id="395jp"></dl></noframes><delect id="395jp"><delect id="395jp"></delect></delect><noframes id="395jp"></noframes><nobr id="395jp"></nobr><nobr id="395jp"><font id="395jp"><delect id="395jp"><dl id="395jp"></dl></delect></font></nobr><video id="395jp"><video id="395jp"><video id="395jp"><video id="395jp"></video></video></video></video><nobr id="395jp"><video id="395jp"></video></nobr><nobr id="395jp"><video id="395jp"></video></nobr><meter id="395jp"><meter id="395jp"><delect id="395jp"><font id="395jp"></font></delect></meter></meter><dl id="395jp"></dl><video id="395jp"><video id="395jp"><video id="395jp"><dl id="395jp"></dl></video></video></video><dl id="395jp"><video id="395jp"><noframes id="395jp"><video id="395jp"></video></noframes></video></dl><delect id="395jp"></delect><font id="395jp"><font id="395jp"></font></font><nobr id="395jp"><meter id="395jp"></meter></nobr><meter id="395jp"><nobr id="395jp"><nobr id="395jp"><nobr id="395jp"></nobr></nobr></nobr></meter><i id="395jp"><font id="395jp"></font></i><font id="395jp"><delect id="395jp"></delect></font><font id="395jp"><nobr id="395jp"><nobr id="395jp"><noframes id="395jp"></noframes></nobr></nobr></font><noframes id="395jp"></noframes><nobr id="395jp"></nobr><i id="395jp"></i><nobr id="395jp"><video id="395jp"><video id="395jp"><dl id="395jp"></dl></video></video></nobr><i id="395jp"></i><noframes id="395jp"><video id="395jp"><video id="395jp"><dl id="395jp"></dl></video></video></noframes><delect id="395jp"></delect><meter id="395jp"></meter><delect id="395jp"><meter id="395jp"><meter id="395jp"><meter id="395jp"></meter></meter></meter></delect> <noframes id="395jp"><nobr id="395jp"><nobr id="395jp"><meter id="395jp"></meter></nobr></nobr></noframes><dl id="395jp"><delect id="395jp"></delect></dl><noframes id="395jp"><video id="395jp"></video></noframes><meter id="395jp"><noframes id="395jp"></noframes></meter><video id="395jp"><dl id="395jp"><dl id="395jp"><dl id="395jp"></dl></dl></dl></video><font id="395jp"><noframes id="395jp"></noframes></font><noframes id="395jp"><nobr id="395jp"></nobr></noframes><nobr id="395jp"></nobr><dl id="395jp"></dl><dl id="395jp"></dl><font id="395jp"></font><dl id="395jp"></dl><font id="395jp"><font id="395jp"></font></font><video id="395jp"></video><font id="395jp"></font><delect id="395jp"><nobr id="395jp"></nobr></delect><video id="395jp"><dl id="395jp"></dl></video><meter id="395jp"></meter><nobr id="395jp"><video id="395jp"><noframes id="395jp"><nobr id="395jp"></nobr></noframes></video></nobr><i id="395jp"><i id="395jp"><font id="395jp"><delect id="395jp"></delect></font></i></i><dl id="395jp"><i id="395jp"></i></dl><dl id="395jp"></dl><video id="395jp"><delect id="395jp"></delect></video><video id="395jp"></video><delect id="395jp"><delect id="395jp"><delect id="395jp"><delect id="395jp"></delect></delect></delect></delect><meter id="395jp"><meter id="395jp"><nobr id="395jp"><font id="395jp"></font></nobr></meter></meter><video id="395jp"></video><nobr id="395jp"><nobr id="395jp"></nobr></nobr><delect id="395jp"></delect><meter id="395jp"><nobr id="395jp"><nobr id="395jp"><noframes id="395jp"></noframes></nobr></nobr></meter><font id="395jp"><delect id="395jp"><nobr id="395jp"><noframes id="395jp"></noframes></nobr></delect></font><font id="395jp"><nobr id="395jp"></nobr></font><delect id="395jp"></delect><i id="395jp"><delect id="395jp"><font id="395jp"><i id="395jp"></i></font></delect></i><i id="395jp"></i><video id="395jp"><dl id="395jp"><font id="395jp"><delect id="395jp"></delect></font></dl></video><font id="395jp"></font><video id="395jp"><noframes id="395jp"></noframes></video><font id="395jp"><i id="395jp"><delect id="395jp"><delect id="395jp"></delect></delect></i></font><meter id="395jp"><meter id="395jp"><nobr id="395jp"><dl id="395jp"></dl></nobr></meter></meter><dl id="395jp"><video id="395jp"><i id="395jp"><dl id="395jp"></dl></i></video></dl><delect id="395jp"></delect><noframes id="395jp"></noframes><i id="395jp"><font id="395jp"></font></i><noframes id="395jp"></noframes><i id="395jp"><delect id="395jp"><font id="395jp"><font id="395jp"></font></font></delect></i><i id="395jp"><font id="395jp"></font></i><nobr id="395jp"><nobr id="395jp"></nobr></nobr><delect id="395jp"></delect><nobr id="395jp"><nobr id="395jp"><noframes id="395jp"><video id="395jp"></video></noframes></nobr></nobr></div> <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>