??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区二区三区91,精品亚洲成AV人在线观看,久久精品国产亚洲av品善http://m.tkk7.com/raozhh/category/5989.htmlzh-cnThu, 01 Mar 2007 02:37:41 GMTThu, 01 Mar 2007 02:37:41 GMT60Linux 基本理知识http://m.tkk7.com/raozhh/articles/45760.html饶志?/dc:creator>饶志?/author>Fri, 12 May 2006 00:58:00 GMThttp://m.tkk7.com/raozhh/articles/45760.htmlhttp://m.tkk7.com/raozhh/comments/45760.htmlhttp://m.tkk7.com/raozhh/articles/45760.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/45760.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/45760.html
作者:?逸(sery@163.comQ?br /><|管员世?gt; 2005q?1?br />通过W一招的实践Q我们已l可以顺利的安装好linux操作pȝQ这仅仅是工作的一部分,现在最q不及待的事情就是用这个系l。打开安装好linux操作pȝ计算机的甉|Q让机器正常引导Q待pȝ引导完毕Q我们的W一个操?--d开始了Q在q一步,能执行的d是输入用户名root和初始安装时讑֮的密码,一旦输入无误,便可取得操作整个计算机的所有权限,开始了挑战Linux的艰难之旅?br />
用户账号密码
为安全v见,需要定期更改超U用户root的密码。这个操作十分简单,在shell提示W?后输?passwd回RQ然后两ơ输入新密码卛_。退出rootdQ然后再ơ登录,验密码修Ҏ否正。然而不q的事情q是偶尔会发生,刚才更改的密码记不清楚了Qroot用户d不了Q急h啦,Nq要重装linux操作pȝQ如果你q想试一遍安装操作,本是无可厚非的,但这q不是一个好LQ特别是在硬盘上存储很多重要数据的情形下。请参照下面的操作来解决q个问题Q?br />1?    手动重启pȝQ按计算机复位键或先关闭计算机在开启?br />2?    当引pȝ到达“引导加载程序(选择Ʋ启动的操作pȝQ”GRUBӞredhat 9在安装的时候,我们默认安装的引导程序是 GRUBQ,按键盘字母“e”键Q如果硬盘上安装多个操作pȝ的话Q还需要用头选中linux 启动条目。将看到如下几行文本Qؓ节省幅Q多余的文本省略了)
root (hd0,4)
kernel /boot/vmlinuz-2.4.20-8 ro root=LABLE/ hdc=ide-scsi  
initrd /boot/initrd-2.4.20-8.img
3?    ?“kernel /boot/vmlinuz-2.4.20-8 ro root=LABLE/ hdc=ide-scsi?Ҏ “kernel /boot/vmlinuz-2.4.28 single root=LABLE/ hdc=ide-scsi”后按回车键Q返回编辑屏q?br />4?    按“b”键使用上面更改后的选项引导计算机,q样计算机就q入单用h式(q行U别1Q而不用输入用户名和密码登录?br />5?    输入命opasswd回RQ两ơ输入新口oQ然后小心保存。关于口令设|的有很多,可以Ҏ自己的情况设|复杂口令?br />6?    再次重启计算机,q时便可利使用新密码进入系l了?br />q个操作对于理员来Ԍ是十分有用的Q但是如果这个服务器q行的是关键应用Q那么应当把它锁在机柜里Q因Z是公司聘用的非管理员也能够替你执行这个操作,很危险的?br />
用户账号
有句名言叫“linux是|络”,q就意味着linuxpȝ不是pȝ理员一个h把玩的,有太多的理由让更多的人来使用q个资源。刚安装完的linuxpȝQ只有一个用户rootQ没有Q何责任让其他仅需使用一部分功能的h来共享root账号和密码。既然如此,l要用计机资源的h开设̎号吧?br />1?    开设̎P在命令提C符输入 #useradd sery 可以成功的d账号seryQ用命o#passwd sery 来给账号sery 讄密码。通过q种方式d的̎Lȝ录将?home/sery, sery用户的环境变?bash_profile在目?/home/sery中。也可以指定用户的主目录Q例如我们要安装数据库Y件sybase ASEQ需要指定它的主目录?opt/sybaseQ通过输入命o#useradd –d /opt/sybase sybse 可以了Q这样sybase用户的环境变量\径也变成 /opt/sybase/.bash_profile。可以把一些用h加到一个组了,以满特定的功能。上面开讄两个账号Q默认生两个组sery和sybase?br />2?    更改账号Q某天,公司的sery职了,由新来的tieny接替他的工作Q可以用命o#usermod –l tieny –m –d /home/tieny sery来实现。当然还应当把口令也改一下?br />3?    删除账号Qsery׃工作不力Q被老板开除了Q那么作为系l管理员应当把他的̎号删除,先删除̎?userdel sery,然后q要删除sery用户的主目录/home/sery?br />需要注意的是,上述的̎h作,只有具备理员权限的用户Q比如rootQ才可以q行的,普通用户仅仅能更改自己的密码而已?br />
文本~辑器vi
要用Unix/linux来完成工作,你没有办法来回避使用文本~辑器这个工兗在unix/linux的世界里Qvi是赫赫有名的Qibm的AIX、SUN的Solaris、SCO UNIX、RedHat Linux{等Q没有一个不用vi q个~辑工具的。因此,作ؓunix/linuxpȝ理员,必须熟练掌握q个基本技能?br />vi文本~辑器打开以后Q有两种模式Q命令模式和输入Q或者编辑)模式。在使用q程中,q两U模式是需要来回相互切换的Q初学者对此往往感到qhQ下面D一个例子来说明一下:
我们在此要把计算机的L名改成sery,那么qvi~辑器修攚w|文?etc/hosts文g。输入命?#vi /etc/hosts 回RQ立刻进入vi的命令模式。在q种模式下,可以q行查找、保存文件等操作Q按字母“i”键切换到编辑模?--屏幕底部昄“Insert”,然后光标定位Q输入相关的字符Q输入完毕ƈ查无误后Q按“Esc”键切换到命令模式,接着输入“:”加wq回R把刚才的输入保存在文g/etc/hosts里。整个过Eȝ一下流E就是:vi filename 打开文g---切换到编辑模式(“i”)----输入文本----切换到命令模式(“Esc?Q“:”)----保存文gQwqQ?br />[root@sybase root]# vi /etc/hosts

# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1           localhost.localdomain localhost //按i切换~辑模式

202.108.93.200       sery //q行是加上去?br />//按Esc键回到命令模式,再输入“:?br />Qwq                 //保存文g退?br />
有时Q文件修改后不想保存它,则在命o模式下输入?q!?如果只是打开文g而没有做M修改Q在命o模式下输入?q”就可以了。有一个技巧还是需要掌握的Q那是在文件中查找字符。编辑一个小的文Ӟ字符C多)用光标定位就可以完成修改Q但是如果要~辑的一个文件较大,例如修改Apache的配|文ӞҎ实际应用Q我们仅需?etc/httpd/conf/httpd.conf做少怿改就可以了,假如用光标定位的Ҏ来做q个事情Q恐怕是一件很Ҏ的事Q这Ӟ查找定位q个功能派上用Z。查找是在命令模式下q行的,q一点要记牢。在apache的配|文仉Q我们要修改Ҏ档的位置Q首先?vi /etc/httpd/conf/httpd.conf打开文gq入命o模式Q然后输入“?DocumentRoot”很快就可定位输入点Q接着按“i”切换到~辑模式Q按要求修改文本Q而后切换到命令模式保存退出。查找方式也是很灉|的,Ҏ当前光标所在的位置Q既可以向后查找Q有可以向前查找Q不q向前查扑ּ始字W是?”而不是?”。vi的功能特别多Q在此无法一一列DQ不q笔者介l的Ҏ已经以对付日常的工作,随着旉的推U,你同样会逐步掌握更多?vi 使用技能。随着linux版本不断的升U,vi也越来越便于使用Q例如在linux桌面环境下,可以用鼠标选定文本Q然后用复制功能来化操作?br />
配置|络参数
如果linux服务器不q入|络Q除了供理员测试而外Q再没有别的实际意义Q因此把linux服务器连入网l就是必ȝ了。在W一招安装linuxӞ我们已经把网l的一些参数手动输入了Q但是有时还得在实际应用中更Ҏ些参数。网l参C要包括:IP地址、子|掩码、默认网兛_指定dns服务器。IP地址、子|掩码、默认网关由文g/etc/sysconfig/network-scripts/ifcfg-eth0来指定。用~辑?vi 打开/etc/sysconfig/network-scripts/ifcfg-eth0Q修改对应的|我本Z惯把默认|关加在q个文g里,卛_q个文g里插入一行“GATEWAY=X.X.X.X”。默认网x个非帔R要的讄Q如果设|错误,linux服务器就只能讉K同一|段的主不能与其他|段的计机互访管其他的网l参数设|完全无误。我曾有意无意的犯过q个错误Q结果每ơ都是一栯人沮丧。在讲授|络的课E里Q默认网兌定义成一个三层设备,讲得通俗一点就是\由器Q它的作用是q接不同|段/子网的通信Q它记录与它某一端口直连的同一|段的机器mac与ip地址对应|UCؓARPQ。\由器/|关不会自动获得同一|段L的mac-ip|只有通过手动指定默认|关把主机的mac-ip值通告l网兟뀂指定dns服务器地址可以让linux服务器以域名的方式访问互联网上的其他机器。指定域名服务器地址q程很简单,只需用vi~辑文g/etc/resolve.conf,输入 nameserver 202.106.0.20 保存退出。需要特别注意的是,不要把指定dns服务器与讑֮本linux服务器ؓdns服务器搞混了Q这是两个完全不同的东西Q前者ؓ客户端,后者ؓ服务器端?br />q有一U特D情况,在只有一个网l设备的条g下,我们需要设|几个IP地址Q比如基于IP地址的虚拟主机。这U操作称备别名。eth0的第一个别名是/etc/sysconfig/network-scripts/ifcfg-eth0:1,用编辑器vi参照/etc/sysconfig/network-scripts/ifcfg-eth0的格式输入网l参数即可?br />在系l提C符下,用命?ifconfig eth0 200.200.200.200 255.255.255.248 up也可指定或修改网l设备的|络参数。但是这U修Ҏ式是动态进行的Q系l重启以后就无效了。以命o#route add default gw X.X.X.X d的默认网关也是同L效果?br />修改|络参数后,要修改立即生效Q不需要重启计机Q重新启动网l服务就可以了。在RedHat linux 9以后的版本,只要输入命o#service network restart卛_Q然后用命o#ifconfig –a来检验修改的l果?br />修改|络参数需要管理员权限才能q行?br />
文gpȝ和原始设?br />在这里介l文件系l和原始讑֤Q?raw deviceQ的目的主要是ؓ来安装大型数据库oracle或sybase奠定一些基Q因些数据库可以使用文gpȝ或原始设备作为逻辑存储区域?br />文gpȝ是一U存储数据的ҎQ采用分层目录结构来存储文gQ由一个根目录和许多子目录、文件组成(IBM AIX 5Lpȝ理技术定义)。Redhat linux 9主要包括以下一些目录:
1?bin:linux通用命o?br />2?dev:pȝ讑֤文g?br />3?etc:理配置文g?br />4?home:各用L目录?br />5?mnt:挂接讑֤的位|?br />6?root:根用Lȝ录?br />7?sbin:pȝ理命o和守护进E?br />8?tmp:临时文g目录?br />9?var:应用E序使用的数据目录,如系l日志文件目录、匿名ftp目录{?br />10?usr:手动安装E序的目录?br />对于文gpȝ的目录及其目录下的文Ӟ我们可以直接q行讉KQ例如在/tmp下创建目?tmp/test?br />原始讑֤指不是由基础操作pȝ可以理的磁盘,q句话不太好理解。给linux服务器添加一个硬盘,创徏分区Q但是不能直接用基本命o对这个分行操作,比如直接在上面创建目录,只有通过挂接才可以进行磁盘I/O操作。例子的命oQ?mount /dev/sdb1 /mnt/dsk2, cd /mnt/dsk2Q在q个目录下就可以创徏文g{基本操作了。Sybase{数据库可以直接指定原始讑֤为存储空_其目的是使数据的修改立即写入盘?br />
q行U别
RedHat linux ?-6{几U运行别。与solaris和AIX的运行别的定义差异较大。按照前面安装linux的设定,pȝ启动后进入的q行U别?。要切换到别的运行环境只需输入#init <runlevel> 。下面列出各个运行别的功能Q?br />1?    q行U别0Q关机操作?br />2?    q行U别1Q单用户l护模式。这U模式只能是用户root,上文我们更改遗忘?root 密码是在这U模式下q行的。另外,有时文gpȝ损坏时进行修复,也要在这U模式下q行。运行?相当与MS windows 2000的安全模式?br />3?    q行U别2Q多用户模式。所有配|文件系l被挂装Q但NFS资源不可用。运行?与MS windows 2000的带|络的安全模式有些类伹{?br />4?    q行U别3Q这是linux服务器的正常模式Q系l资源完全可用?br />5?    q行U别4Q用戯定义?br />6?    q行U别5Q多用户带网l服务加囑Ş界面Qinit 3加图形)。这相当于MS windows的正常模式。如果没有安装xwindow׃能启用这个别,用命?startx也可从运行?切换到运行??br />7?    q行U别6Q重新启动计机?br />在一般情况下Q我们需要linux服务器工作在q行U别3下,偶尔Z操作方便会?q个U别。Linuxq有另外一些运行别,但不多用。熟l掌握上q几个运行别对于系l维护是很有帮助的?br />
q程操作linux服务?br />linux服务器基本配|完成后Q需要把它撤L试台Q也许要把它攑֜隔自己办公室很远的idc机房Q或者由于同事无法忍受机器巨大的噪音而必L它放在某个隔ȝ房间的机柜里。我们更愿意坐在自己的办公桌前,用桌面系l或W记本来q程控制和操作放在在某个地方的linux服务器,然后惬意的喝一杯咖啡?br />telnet曾作为最主要的远E管理工P׃其存在安全隐患而逐渐失宠Q从RedHat linux 7.1开始,默认情况?telnet 服务是不启用的。安全shell包(sshQ由于它提供Ҏ据的加密传输Q具备较高的安全Ҏ,因此来多的系l管理员正在在用ssh来管理远E的 linux服务器?br />要用ssh服务Q应当保证openssh-server软g包被安装Q一般情况下Qssh服务器被配置成自动启动,?linux服务器端Q不必对ssh做Q何设|,只需保证它被安装和启动就可以了。RedHat linux 允许root用户q程dQ而RedFlag linux则在默认情况下不允许root 用户q程d。可通过修改文g /etc/sshd/sshd_configQ“PermitRootLogin no”表CZ允许root用户q程dQ“PermitRootLogin yes”表C允许root用户q程登陆。我本h习惯使用rootq程d?br />1?    从linuxq接Q输入命?ssh <q程linux服务器的ip地址或域?gt;Q回车后输入 root密码可以得到root的shell环境Q与直接操作linux服务器一栗?br />2?    从windowsq接Q有多款用来q接linux服务器的q程理工具Q比较有名的有SecureCRT、NetTerm、XManager、Putty{。SecureCRT是个不错的工P它不仅支持ssh,q支持文件上传功能。Windows下配|SecureCRT是比较容易的Q在此不做介l?br />下图是SecureCRT使用sshdlinux服务器的事例Q?
 
当作好上q的准备后,真正的远E操?控制可以开始了?br />

                                   


]]>
Ajax原理详细说明(转自ibm开发者网? http://m.tkk7.com/raozhh/articles/42361.html饶志?/dc:creator>饶志?/author>Fri, 21 Apr 2006 08:53:00 GMThttp://m.tkk7.com/raozhh/articles/42361.htmlhttp://m.tkk7.com/raozhh/comments/42361.htmlhttp://m.tkk7.com/raozhh/articles/42361.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/42361.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/42361.html阅读全文

]]>
Portlet开发基知识 http://m.tkk7.com/raozhh/articles/40636.html饶志?/dc:creator>饶志?/author>Wed, 12 Apr 2006 06:07:00 GMThttp://m.tkk7.com/raozhh/articles/40636.htmlhttp://m.tkk7.com/raozhh/comments/40636.htmlhttp://m.tkk7.com/raozhh/articles/40636.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/40636.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/40636.html  Portlet开发基知识

1.portlet.xml文gQ放|在WEB_INF/portlet.xml下面。典型的例子Q?/p>

<portlet>
<description>Description goes here</description>
<portlet-name>first</portlet-name>
<portlet-class>com.malani.examples.portlets.jsr168.FirstPortlet
</portlet-class>
<portlet-info>
<title>First</title>
</portlet-info>
</portlet>

portlet-class是实现的类。可以和web.xml对照比较一下?/font>

2.实现的PortletcR和传统的servlet一Pportal容器来管理protlet的生命周期。它必须实现javax.portlet.Portlet接口。但是jsr168标准提供了一个方便类QGenericPortlet你可以直?br />l承它就ok了?/font>

1)生命周期Q同servlet一样Portlet必须有自q命周期。这定义在javax.portlet.Portlet接口中。它的方法是Qinit(),render(),processAction(),destroy().但创建portlet实例的时候调用init()Ҏ。它完成一些需要花Ҏ늚资源的动作。但实例被销毁的时候,容器调用destroyҎ来释放这些资源?/font>

Portlet规范清晰的区分了renderh和actionh的区别。renderRequest()会调用该portlet上的render()ҎQactionRequst()会调用processAction()Ҏ.要注意的是一ơ用户完整的h是Qportal面上的所有的protlet?render()调用Q该hprotlet?font color="#000000">processAction()调用。具体看图:

3.Portlet模式

VIEW模式是你必须实现的,EDITQHELP模式是可选的。你可以通过修改doEdit()和doHelp()
Ҏ来实现这些模式。另外还需要在portlet.xml配置模式Q?/p>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>edit</portlet-mode>
<portlet-mode>help</portlet-mode>
</supports>

修改本文件但没有实现该模式容器会抛出 javax.portlet.PortletException异常.

实现window状态,注意JSR 168q没有对q个q行规定Q但webLogic 完成了:

<portlet>
<portlet-name>state</portlet-name>
<supports>
<mime-type>text/html</mime-type>
<excluded-window-state>minimized</excluded-window-state>
<excluded-window-state>maximized</excluded-window-state>
</supports>
</portlet>

包含JSP文gQ?/font>

上面的例子中我们在doViewҎ中通过Ҏ得到Writer实例Q这样可以输出HTML片断。但是,
我们q不推荐您这样做。我们推荐您使用JSP来达到视图-java的分Rؓ了包含一个特定的jsp
首先你必d到PortletContext.在PortletContext中,通过调用getRequestDispatcher()Ҏ
得到PorletRequestDispatcherQ通过它的includer()Ҏ来包含JSp例如Q?br />// execute the necessary logic here...
PortletRequestDispatcher aDispatcher =
getPortletContext().getRequestDispatcher(
"/IncludePortlet/includeView.jsp"
);
aDispatcher.include(aRequest, aResponse);

处理动作

在标准的web应用E序?提交表单Q或者一个动作url常见的。JSR168规范中定义了portlet taglib
来帮助我们完成这些工作:

<form action="<portlet:actionURL/>" method="post">
...
</form>

提交的话会自动调用该portlet?font color="#000000">processAction(ActionRequest aRequest, ActionResponse aResponse)ҎQ这p你传l方式一样了reqeust的getParameter()或者是getAttribute()?br />得到传来的参数?/font>

processAction()Ҏ讄response对象中的倹{不要用ActionRequest或ActionResponse对象的setAttribute()Ҏ。g会从processAction()传递到render()ҎQ而且在JSP中是不可用的。相反要使用ActionResponse对象的setRenderParameter()Ҏ。这些render参数对所有后lrenderh可用Q这一点与典型的Web应用E序h属性很不相同。典型的Web applicationh属性只对于一个请求可用。另一斚wQrenderh参数对于许多后箋renderh可用。render参数保持可用直到D动作的重新执行显式地修改或删除?br />

所呈现的参数是怎样昄在JSP上的呢?应用来自portlet标签库的defineObjects标签来定义portlet对象。该标签使renderRequest、renderResponse和portletConfig portlet对象在页面中可用。参数通过调用renderRequest对象的getParameter()Ҏ来显C。请参考与所包含的源代码CZ中的favoriteColorView.jsp?br />
  portlet FavoriteColor也展CZ其他概念。第一个是如何在processAction()Ҏ中用~程的方法改变portlet模式。调用ActionResponse对象的setPortletMode()Ҏ来修改portlet模式。第二个概念是如何用一个HTML链接来修改portlet模式。该链接使用来自portlet标签库的renderURL标签生成。根据希望的portlet模式指定portletMode属性的倹{请参考源代码CZ中的FavoriteColorPortletcdfavoriteColorView.jsp面?/p>



]]>
接触 solaris : 安装 oraclehttp://m.tkk7.com/raozhh/articles/39168.html饶志?/dc:creator>饶志?/author>Tue, 04 Apr 2006 06:53:00 GMThttp://m.tkk7.com/raozhh/articles/39168.htmlhttp://m.tkk7.com/raozhh/comments/39168.htmlhttp://m.tkk7.com/raozhh/articles/39168.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/39168.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/39168.html 接触 solaris : 安装 oracle 作者:佚名  来源Q本站收集  发布时_2005-11-14 18:40:47  发布人:admin

减小字体 增大字体

接触 solaris : 安装 oracle


Install oracle815 in Solaris 7

1.建立 ORACLE 用户?DBA l,初始化安装目?
=================================================
groupadd dba
useradd -g dba oracle
passwd oracle
mkdir /oracle
chown -R oracle.dba /oracle

2.为安?ORACLE 讄pȝ变量
=================================================
vi /etc/system
(add in the end)=>
set shmsys:shminfo_shmmax=4294967295
set shmsys:shminfo_shmmin=1
set shmsys:shminfo_shmmni=100
set shmsys:shminfo_shmseg=10
set semsys:seminfo_semmni=100
set semsys:seminfo_semmsl=100
set semsys:seminfo_semmns=2000
set semsys:seminfo_semopm=100
set semsys:seminfo_semvmx=32767
Q请Ҏ实际情况做调_

vi /etc/services
(add in the end)=>
orasrv 1525/tcp oracle
listener 1521/tcp
Q请Ҏ实际情况做调_

vi /etc/oracle/.profile(.cshrc)
(add or modify)=>
set path=( /oracle/bin /usr/sbin /usr/bin /usr/openwin/bin /oracle /etc /usr/ccs/bin . )
setenv ORACLE_HOME /oracle
setenv ORACLE_SID oracle8
#setenv DISPLAY 10.1.1.110:0.0
setenv NLS_LANG AMERICAN_AMERICA.ZHS16CGB231280
#setenv NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
Q请Ҏ实际情况做调_


说明Q加#为可选的参数Q?10.1.1.110是用PC行EXTRAXd服务器所配置的?

#sync;sync;reboot Sun OS重启Qɾpȝ参数生效

3.Install
=================================================
1 、插入ORACLE 安装光盘
#/etc/init.d/volmgt stop
#/etc/init.d/volmgt start
%volcheck
%df -k 查有无cdrom的设?

2?%cd /cdrom/cdrom0 %./runInstaller 出现 ORACLE Universal Installer的安装窗?按Next键l?

(q程安装则在 KEA!X Server {远E模拟桌面环境下在命令窗口中q行 ./runInstaller 出现 ORACLE Universal Installer的安装窗?按Next键l?

3、Destination框输入将要安装oracle的目录这里我输入/oracleQ接着出现弹出H口要求用rootq行/tmp/orainstRoot.sh (它创建oraInventory的安装目? 接着选择要安装的产品ORACLE8I 8.1.5

4、选typical或custom安装Q注意屏q上端Language按钮Q选Chinese语言?

5、接着出现要安装ORACLE产品的全部信息,如果有不对的地方可以按Perious按钮q回修改。如果确认无误,按NextQORACLE开始安装?

(如果选择了要建数据库Q会要求你输入数据库的存攑֜址Q这里我输入/oracle/data,那么数据库的真正存放地址?/oracle/data/oradata/dbdir)

6、安装成?00%后又回到开始的选项菜单?oracle/orainst/install.log 安装日志文g最后提COK

7、弹出Setup PrivilegesH口,要求用rootq行 #/oracle/root.sh
Are these setting correct (y/n):?y Enter the full pathname of the local bin directory (y/n): ?bin (此shell E序?var/oracle路径下生成一个文件oratab ,q做pȝ?


4.创徏数据库时应该注意的问?
=================================================
心库徏好后不能修改的参敎ͼ

Character sets : ZHS16GDK
db_block_size : 2048

建库p|错误 01034 :

先取消徏库过E?
查oracle安装目录下的 .profile(.cshrc) 讄及其他系l设|?
Q必要的时?reboot 服务器)?oracle/dbs/dbassist 重新建库

建库p|后重建时说库已经存在Q?

rm -r /oracle/admin/
rm -r /oracle//


5.建库后的微调
=================================================
#vi /var/opt/oracle/oratab 最后一行改 app1:/oracle:Y
#vi /var/opt/oracle/listener.ora ?host= (host_name) oraclehome= (/oracle)
例子: listener=(address_list=
(address=(protocol=tcp)
(port=1521)
(host=joe)))
sid_list_listener=(sid_list=
(sid_desc=(sid_name=oracle8)
(oracle_home=/oracle)))
trace_level+listener=admin
startup_wait_time_listener=0
connect_timeout_listener=5

#vi /var/opt/oracle/tnsnames.ora 一些连接字W串Q分布式通讯时有?


6.安装试
=================================================
#su - oracle %env 看环境变量改变了没有

%svrmgrl 唤醒SVRMGR状?
SVRMGR>connect internal
q接打开数据?SVRMGR>shutdown immediate 先关?instances, 数据?
SVRMGR>startup 再打开数据库,当看?instances startup, database mount, database open的时候,oracle安装成功
SVRMGR>exit

%lsnrctl start 启动listener 如果出错查环境变量是否设好,及lsnrctl文g的内容和执行属性?


7。配|自启动/关闭
=================================================
~写 SH 文g
vi /etc/oracle

#!/bin/sh
OPT_=$1

case "$OPT_" in
start)
/bin/echo "$0 : (start)"
#
# Your service startup command goes here.
#
su - oracle -c "/oracle/bin/dbstart"
su - oracle -c "/oracle/bin/lsnrctl start"
# su - root -c "/www/tomcat/bin/startup.sh"
# su - root -c "/www/apache/bin/apachectl start"

# NOTE: Must exit with zero unless error is severe.
exit 0
;;
stop)
/bin/echo "$0 : (stop)"
#
# Your service shutdown command goes here.
#
su - oracle -c "/oracle/bin/lsnrctl stop"
su - oracle -c "/oracle/bin/dbshut"
# su - root -c "/www/tomcat/bin/shutdown.sh"
# su - root -c "/www/apache/bin/apachectl stop"

# NOTE: Must exit with zero unless error is severe.
exit 0
;;
*) /bin/echo ''
/bin/echo "Usage: $0 [start|stop]"
/bin/echo " Invalid argument ==> \"${OPT_}\""
/bin/echo ''
exit 0
;;
esac

讄执行ơ序
ln -s /etc/init.d/oracle /etc/rc2.d/S99oracle
ln -s /etc/init.d/oracle /etc/rc0.d/K01oracle


8.自启?关闭 试
=================================================
reboot ?ps -ef | grep oracle



]]>
常用正则表达?/title><link>http://m.tkk7.com/raozhh/articles/38505.html</link><dc:creator>饶志?/dc:creator><author>饶志?/author><pubDate>Fri, 31 Mar 2006 08:37:00 GMT</pubDate><guid>http://m.tkk7.com/raozhh/articles/38505.html</guid><wfw:comment>http://m.tkk7.com/raozhh/comments/38505.html</wfw:comment><comments>http://m.tkk7.com/raozhh/articles/38505.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/raozhh/comments/commentRss/38505.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/raozhh/services/trackbacks/38505.html</trackback:ping><description><![CDATA[ <h2 class="post-title">常用正则表达?/h2> <div id="exxqykw" class="post-body">  正则表达式用于字W串处理、表单验证等场合Q实用高效。现一些常用的表达式收集于此,以备不时之需?br /><br />匚w中文字符的正则表辑ּQ?[\u4e00-\u9fa5]<br />评注Q匹配中文还真是个头疼的事,有了q个表达式就好办?br /><br />匚w双字节字W?包括汉字在内)Q[^\x00-\xff]<br />评注Q可以用来计字W串的长度(一个双字节字符长度?QASCII字符?Q?br /><br />匚wI白行的正则表达式:\n\s*\r<br />评注Q可以用来删除空白行<br /><br />匚wHTML标记的正则表辑ּQ?lt;(\S*?)[^>]*>.*?|<.*? /><br />评注Q网上流传的版本太糟p,上面q个也仅仅能匚w部分Q对于复杂的嵌套标记依旧无能为力<br /><br />匚w首尾I白字符的正则表辑ּQ^\s*|\s*$<br />评注Q可以用来删除行首行I白字符(包括I格、制表符、换늬{等)Q非常有用的表达?br /><br />匚wEmail地址的正则表辑ּQ\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*<br />评注Q表单验证时很实?br /><br />匚w|址URL的正则表辑ּQ[a-zA-z]+://[^\s]*<br />评注Q网上流传的版本功能很有限,上面q个基本可以满需?br /><br />匚w帐号是否合法(字母开_允许5-16字节Q允许字母数字下划线)Q^[a-zA-Z][a-zA-Z0-9_]{4,15}$<br />评注Q表单验证时很实?br /><br />匚wGUIDQ由数字Q字母,下划U,中划U组?br />/^[a-zA-Z0-9_\-]*$/<br /><br />匚w国内电话LQ\d{3}-\d{8}|\d{4}-\d{7}<br />评注Q匹配Ş式如 0511-4405222 ?021-87888822<br /><br />匚w腾讯QQP[1-9][0-9]{4,}<br />评注Q腾讯QQ号从10000开?br /><br />匚w中国邮政~码Q[1-9]\d{5}(?!\d)<br />评注Q中国邮政编码ؓ6位数?br /><br />匚ww䆾证:\d{15}|\d{18}<br />评注Q中国的w䆾证ؓ15位或18?br /><br />匚wip地址Q\d+\.\d+\.\d+\.\d+<br />评注Q提取ip地址时有?br /><br />匚w特定数字Q?br />^[1-9]\d*$    //匚w正整?br />^-[1-9]\d*$   //匚w负整?br />^-?[1-9]\d*$   //匚w整数<br />^[1-9]\d*|0$  //匚w非负整数Q正整数 + 0Q?br />^-[1-9]\d*|0$   //匚w非正整数Q负整数 + 0Q?br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匚w正QҎ<br />^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匚w负QҎ<br />^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匚w点?br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匚w非负点敎ͼ正QҎ + 0Q?br />^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匚w非正点敎ͼ负QҎ + 0Q?br />评注Q处理大量数据时有用Q具体应用时注意修正<br /><br />匚w特定字符Ԍ<br />^[A-Za-z]+$  //匚w?6个英文字母组成的字符?br />^[A-Z]+$  //匚w?6个英文字母的大写l成的字W串<br />^[a-z]+$  //匚w?6个英文字母的写l成的字W串<br />^[A-Za-z0-9]+$  //匚w由数字和26个英文字母组成的字符?br />^\w+$  //匚w由数字?6个英文字母或者下划线l成的字W串<br />评注Q最基本也是最常用的一些表辑ּ<br /><br />原蝲地址Qhttp://lifesinger.3322.org/myblog/?p=185</div> <img src ="http://m.tkk7.com/raozhh/aggbug/38505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/raozhh/" target="_blank">饶志?/a> 2006-03-31 16:37 <a href="http://m.tkk7.com/raozhh/articles/38505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式之?/title><link>http://m.tkk7.com/raozhh/articles/38501.html</link><dc:creator>饶志?/dc:creator><author>饶志?/author><pubDate>Fri, 31 Mar 2006 08:27:00 GMT</pubDate><guid>http://m.tkk7.com/raozhh/articles/38501.html</guid><wfw:comment>http://m.tkk7.com/raozhh/comments/38501.html</wfw:comment><comments>http://m.tkk7.com/raozhh/articles/38501.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/raozhh/comments/commentRss/38501.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/raozhh/services/trackbacks/38501.html</trackback:ping><description><![CDATA[ <center> <h1>正则表达式之?/h1> </center> <center> <p>原著QSteve Mansour <br />sman@scruznet.com <br /><font size="-1">Revised: June 5, 1999<br />(copied by jm /at/ jmason.org from http://www.scruz.net/%7esman/regexp.htm, after the original disappeared! ) </font></p> <p>译QNeo Lee<br />neo.lee@gmail.com<br /><font size="-1">2004q?0?6?/font></p> </center> <hr /> <p> <a >英文版原?/a> </p> <p>译者按Q原文因为年代久q,文中很多链接早已q期Q主要是关于vi、sed{工L介绍和手册)Q本译文中已此c链接删除,如需查这些链接可以查看上面链接的原文。除此之外基本照原文直译Q括号中有“译者按”的部分是译者补充的说明。如有内Ҏ面的问题L接和Steve Mansor联系Q当Ӟ如果你只写中文,也可以和我联pR?/p> <hr /> <h1>??/h1> <p> <b> <a >什么是正则表达?/a> </b> <br /> <b> <a >范例</a> </b> <br />   <a >?/a><br />   <a >中Q神奇的咒语Q?/a><br />   <a >困难Q不可思议的象形文字)</a><br /><b><a >不同工具中的正则表达?/a></b></p> <p> </p> <hr width="100%" /> <h1> <a name="WhatAreRegularExpressions"> </a>什么是正则表达?/h1>一个正则表辑ּQ就是用某种模式d配一cdW串的一个公式。很多h因ؓ它们看上L较古怪而且复杂所以不敢去使用——很不幸Q这文章也不能够改变这一点,不过Q经q一点点l习之后我就开始觉得这些复杂的表达式其实写hq是相当单的Q而且Q一旦你弄懂它们Q你p把数时辛苦而且易错的文本处理工作压~在几分钟(甚至几秒钟)内完成。正则表辑ּ被各U文本编辑Y件、类库(例如Rogue Wave的tools.h++Q、脚本工P像awk/grep/sedQ广泛的支持Q而且像Microsoft的Visual C++q种交互式IDE也开始支持它了? <p>我们在如下的章节中利用一些例子来解释正则表达式的用法Q绝大部分的例子是基?b><tt>vi</tt></b>中的文本替换命o?b><tt>grep</tt></b>文g搜烦命o来书写的Q不q它们都是比较典型的例子Q其中的概念可以在sed、awk、perl和其他支持正则表辑ּ的编E语a中用。你可以看看<a >不同工具中的正则表达?/a>q一节,其中有一些在别的工具中用正则表辑ּ的例子。还有一个关于vi中文本替换命令(sQ的<a >单说?/a>附在文后供参考?/p><h2>正则表达式基</h2>正则表达式由一些普通字W和一?i>元字W(metacharactersQ?/i>l成。普通字W包括大写的字母和数字Q而元字符则具有特D的含义Q我们下面会l予解释? <p>在最单的情况下,一个正则表辑ּ看上d是一个普通的查找丌Ӏ例如,正则表达?testing"中没有包含Q何元字符Q,它可以匹?testing"?123testing"{字W串Q但是不能匹?Testing"?/p><p>要想真正的用好正则表辑ּQ正的理解元字W是最重要的事情。下表列Z所有的元字W和对它们的一个简短的描述? </p><p></p><table cellspacing="2" cellpadding="2"><tbody><tr valign="baseline"><th align="left"><b><i>元字W?/i></b></th><td> </td><th align="left"><b><i>描述</i></b></th></tr><tr><td><hr width="100%" /></td><td></td><td><hr width="100%" /></td></tr><tr><td valign="top" align="middle"><center><b><tt><font face="Courier New"><font size="+1">.</font></font></tt></b></center></td><td></td><td>匚wM单个字符。例如正则表辑ּ<b><tt>r.t</tt></b>匚wq些字符Ԍ<i>rat</i>?i>rut</i>?i>r t</i>Q但是不匚w<i>root</i>。?/td></tr><tr><td valign="top"><center><b><tt><font face="Courier New"><font size="+1">$</font></font></tt></b></center></td><td></td><td>匚w行结束符。例如正则表辑ּ<b><tt>weasel$</tt></b> 能够匚w字符?<i>He's a weasel</i>"的末,但是不能匚w字符?<i>They are a bunch of weasels.</i>"。?/td></tr><tr><td valign="top"><center><b><font size="+1">^</font></b></center></td><td></td><td>匚w一行的开始。例如正则表辑ּ<b><tt>^When in</tt></b>能够匚w字符?<i>When in the course of human events</i>"的开始,但是不能匚w"<i>What and When in the"?/i></td></tr><tr><td valign="top"><center><b><tt><font face="Courier New"><font size="+1">*</font></font></tt></b></center></td><td></td><td>匚w0或多个正好在它之前的那个字符。例如正则表辑ּ<b><tt></tt></b><b><tt>.*</tt></b>意味着能够匚wL数量的Q何字W?/td></tr><tr><td valign="top"><center><b><tt><font face="Courier New"><font size="+1">\</font></font></tt></b></center></td><td></td><td>q是引用府,用来这里列出的q些元字W当作普通的字符来进行匹配。例如正则表辑ּ<b><tt>\$</tt></b>被用来匹配美元符P而不是行,cM的,正则表达?tt><strong>\.</strong></tt>用来匚w点字W,而不是Q何字W的通配W?/td></tr><tr><td valign="top"><center><b><tt><font face="Courier New"><font size="+1">[ ] </font></font></tt></b><br /><b><tt><font face="Courier New"><font size="+1">[c</font><font size="-1">1</font><font size="+1">-c</font><font size="-1">2</font><font size="+1">]</font></font></tt></b><br /><b><tt><font face="Courier New"><font size="+1">[^c</font><font size="-1">1</font><font size="+1">-c</font><font size="-1">2</font><font size="+1">]</font></font></tt></b></center></td><td></td><td>匚w括号中的M一个字W。例如正则表辑ּ<b><tt>r[aou]t</tt></b>匚w<i>rat</i>?i>rot</i>?i>rut</i>Q但是不匚w<i>ret</i>。可以在括号中用连字符-来指定字W的区间Q例如正则表辑ּ<b><tt>[0-9]</tt></b>可以匚wM数字字符Q还可以制定多个区间Q例如正则表辑ּ<b><tt>[A-Za-z]</tt></b>可以匚wM大小写字母。另一个重要的用法是“排除”,要想匚w<i>除了</i>指定区间之外的字W——也是所谓的补集——在左边的括号和W一个字W之间用^字符Q例如正则表辑ּ<b><tt>[^269A-Z]</tt></b> 匹配除???和所有大写字母之外的M字符?/td></tr><tr><td valign="top"><center><b><tt><font face="Courier New"><font size="+1">\< \></font></font></tt></b></center></td><td></td><td>匚w词(<em>word</em>Q的开始(\<Q和l束Q\>Q。例如正则表辑ּ<b><tt><font face="Courier New">\<the</font></tt></b>能够匚w字符?<i>for the wise</i>"中的"the"Q但是不能匹配字W串"<i>otherwise</i>"中的"the"?strong>注意</strong>Q这个元字符不是所有的软g都支持的?/td></tr><tr><td valign="top"><center><b><tt><font face="Courier New"><font size="+1">\( \)</font></font></tt></b></center></td><td></td><td>?\( ?\) 之间的表辑ּ定义为“组”(<em>group</em>Q,q且匹配这个表辑ּ的字W保存到一个时区域(一个正则表辑ּ中最多可以保?个)Q它们可以用 <b><tt>\1</tt></b> ?b><tt>\9</tt></b> 的符h引用?/td></tr><tr><td valign="baseline"><center><b><tt><font face="Courier New"><font size="+1">|</font></font></tt></b></center></td><td></td><td>两个匹配条件进行逻辑“或”(<em>Or</em>Q运。例如正则表辑ּ<b><tt><font face="Courier New">(him|her)</font></tt></b> 匚w"<i>it belongs to him</i>"?<i>it belongs to her</i>"Q但是不能匹?<i>it belongs to them.</i>"?strong>注意</strong>Q这个元字符不是所有的软g都支持的?/td></tr><tr valign="baseline"><td><center><b><tt><font face="Courier New"><font size="+1">+</font></font></tt></b></center></td><td></td><td>匚w1或多个正好在它之前的那个字符。例如正则表辑ּ<b><tt></tt></b><b><tt></tt></b><b><tt>9+</tt></b>匚w9?9?99{?strong>注意</strong>Q这个元字符不是所有的软g都支持的?/td></tr><tr valign="baseline"><td><center><b><tt><font size="+1">?</font></tt></b></center></td><td></td><td>匚w0?个正好在它之前的那个字符?strong>注意</strong>Q这个元字符不是所有的软g都支持的?/td></tr><tr valign="baseline"><td><center><b><font size="+1"><tt><font face="Courier New">\{</font></tt><i>i</i><tt><font face="Courier New">\}</font></tt></font></b><br /><b><font size="+1"><tt><font face="Courier New">\{</font></tt><i>i</i><tt><font face="Courier New">,</font></tt><i>j</i><tt><font face="Courier New">\}</font></tt></font></b></center></td><td></td><td valign="baseline">匚w指定数目的字W,q些字符是在它之前的表达式定义的。例如正则表辑ּ<b><tt><font face="Courier New">A[0-9]\{3\}</font></tt></b> 能够匚w字符"A"后面跟着正好3个数字字W的Ԍ例如A123、A348{,但是不匹配A1234。而正则表辑ּ<b><tt><font face="Courier New">[0-9]\{4,6\}</font></tt></b> 匚wq箋的Q?个?个或?个数字字W?strong>注意</strong>Q这个元字符不是所有的软g都支持的?/td></tr></tbody></table><p></p><hr width="100%" /><p>最单的元字W是点,它能够匹配Q何单个字W(注意<strong>?/strong>包括新行W)。假定有个文件test.txt包含以下几行内容Q?/p><ul><tt>he is a rat</tt><br /><tt>he is in a rut</tt><br /><tt>the food is Rotten</tt><br /><tt>I like root beer</tt></ul>我们可以使用grep命o来测试我们的正则表达式,grep命o使用正则表达式去试匚w指定文g的每一行,q将臛_有一处匹配表辑ּ的所有行昄出来。命? <ul><tt>grep r.t test.txt</tt></ul>在test.txt文g中的每一行中搜烦正则表达?b><tt>r.t</tt></b>Qƈ打印输出匚w的行。正则表辑ּ<b><tt>r.t</tt></b>匚w一?b><tt>r</tt></b>接着M一个字W再接着一?b><tt>t</tt></b>。所以它匹配文件中?b><tt>rat</tt></b>?b><tt>rut</tt></b>Q而不能匹?b><tt>Rotten</tt></b>中的<b><tt>Rot</tt></b>Q因为正则表辑ּ是大写敏感的。要惛_时匹配大写和写字母Q应该用字W区间元字符Q方括号Q。正则表辑ּ<b><tt>[Rr]</tt></b>能够同时匚w<b><tt>R</tt></b>?b><tt>r</tt></b>。所以,要想匚w一个大写或者小写的<b><tt>r</tt></b>接着M一个字W再接着一?b><tt>t</tt></b>p使用q个表达式:<b><tt>[Rr].t</tt></b>? <p>要想匚w行首的字W要使用抑扬字符Q?em>^</em>Q——又是也被叫做插入符。例如,x到text.txt中行?he"打头的行Q你可能会先用简单表辑ּ<b><tt>he</tt></b>Q但是这会匹配第三行?b><tt>the</tt></b>Q所以要使用正则表达?b><tt>^he</tt></b>Q它只匹配在行首出现?b><tt>h</tt></b>?</p><p>有时候指定“除了×××都匚w”会比较Ҏ辑ֈ目的Q当抑扬字符Q?em>^</em>Q出现在Ҏ号中是,它表C“排除”,例如要匹?b><tt>he</tt></b> Q但是排除前面是<b><tt>t</tt></b> or <b><tt>s</tt></b>的情性(也就?b><tt>the</tt></b>?b><tt>s</tt></b><b><tt>he</tt></b>Q,可以使用Q?b><tt>[^st]he</tt></b>?</p><p>可以使用Ҏh指定多个字符区间。例如正则表辑ּ<b><tt>[A-Za-z]</tt></b>匚wM字母Q包括大写和写的;正则表达?b><tt>[A-Za-z][A-Za-z]*</tt></b> 匚w一个字母后面接着0或者多个字母(大写或者小写)。当然我们也可以用元字符<b><tt>+</tt></b>做到同样的事情,也就是:<b><tt>[A-Za-z]+</tt></b> Q和<b><tt>[A-Za-z][A-Za-z]*</tt></b>完全{h。但是要注意元字W?b><tt>+</tt></b> q不是所有支持正则表辑ּ的程序都支持的。关于这一点可以参考后面的<a >正则表达式语法支持情?/a>?/p><p>要指定特定数量的匚wQ要使用大括P注意必须使用反斜杠来转义Q。想匚w所?b><tt>100</tt></b>?b><tt>1000</tt></b>的实例而排?b><tt>10</tt></b>?b><tt>10000</tt></b>Q可以用:<b><tt>10\{2,3\}</tt></b>Q这个正则表辑ּ匚w数字1后面跟着2或??的模式。在q个元字W的使用中一个有用的变化是忽略第二个数字Q例如正则表辑ּ<b><tt>0\{3,\}</tt></b> 匹配至?个连l的0?/p><h2><a name="SimpleCommands"></a>单的例子</h2><p>q里有一些有代表性的、比较简单的例子? </p><p></p><table cellspacing="2" cellpadding="2"><tbody><tr><td><b><i>vi 命o</i></b></td><td><b><i>作用</i></b></td></tr><tr><td><hr width="100%" /></td><td><hr width="100%" /></td></tr><tr><td><b><tt><font face="Courier New"><font size="+1">:%s/ */ /g</font></font></tt></b></td><td>把一个或者多个空格替换ؓ一个空根{?/td></tr><tr><td><b><tt><font face="Courier New"><font size="+1">:%s/ *$//</font></font></tt></b></td><td>L行尾的所有空根{?/td></tr><tr><td><b><tt><font face="Courier New"><font size="+1">:%s/^/ /</font></font></tt></b></td><td>在每一行头上加入一个空根{?/td></tr><tr><td><b><tt><font face="Courier New"><font size="+1">:%s/^[0-9][0-9]* //</font></font></tt></b></td><td>L行首的所有数字字W?/td></tr><tr><td><b><tt><font face="Courier New"><font size="+1">:%s/b[aeio]g/bug/g</font></font></tt></b></td><td>所有的<i>bag</i>?i>beg</i>?i>big</i>?i>bog</i>改ؓ<i>bug</i>。?/td></tr><tr><td><b><tt><font face="Courier New"><font size="+1">:%s/t\([aou]\)g/h\1t/g</font></font></tt></b></td><td>所?i>tag</i>?i>tog</i>?i>tug</i>分别改ؓ<i>hat</i>?i>hot</i>?i>hug</i>Q注意用group的用法和使用\1引用前面被匹配的字符Q?/td></tr><tr><td></td><td></td></tr></tbody></table><h2><a name="MediumDifficultyExamples"></a>中的例子(奇的咒语)</h2><h3>?</h3><p>所有方法foo(<i>a,b,c</i>)的实例改为foo(<i>b,a,c</i>)。这里a、b和c可以是Q何提供给Ҏfoo()的参数。也是说我们要实现q样的{换: </p><p></p><table cellspacing="4" cellpadding="0"><tbody><tr><td><b>之前</b></td><td> </td><td><b>之后</b></td></tr><tr><td><tt>foo(10,7,2)</tt></td><td></td><td><tt>foo(7,10,2)</tt></td></tr><tr><td><tt>foo(x+13,y-2,10)</tt></td><td></td><td><tt>foo(y-2,x+13,10)</tt></td></tr><tr><td><tt>foo( bar(8), x+y+z, 5)</tt></td><td></td><td><tt>foo( x+y+z, bar(8), 5)</tt></td></tr></tbody></table><p>下面q条替换命o能够实现q一法Q?/p><ul><b><tt><font face="Courier New">:%s/foo(\([^,]*\),\([^,]*\),\([^)]*\))/foo(\2,\1,\3)/g</font></tt></b></ul><p>现在让我们把它打散来加以分析。写个表辑ּ的基本思\是找出foo()和它的括号中的三个参数的位置。第一个参数是用这个表辑ּ来识别的Q:<b><tt><font face="Courier New">\([^,]*\)</font></tt></b>Q我们可以从里向外来分析它:  </p><p></p><table><tbody><tr><td><b><tt><font face="Courier New">[^,]</font></tt></b></td><td> </td><td>除了逗号之外的Q何字W?/td></tr><tr><td><b><tt><font face="Courier New">[^,]*</font></tt></b></td><td></td><td>0或者多个非逗号字符</td></tr><tr><td><b><tt><font face="Courier New">\([^,]*\)</font></tt></b></td><td></td><td>这些非逗号字符标记?b><tt>\1</tt></b>Q这样可以在之后的替换模式表辑ּ中引用它</td></tr><tr valign="baseline"><td><b><tt><font face="Courier New">\([^,]*\),</font></tt></b></td><td></td><td>我们必须扑ֈ0或者多个非逗号字符后面跟着一个逗号Qƈ且非逗号字符那部分要标记出来以备后用?/td></tr></tbody></table><p>现在正是指出一个用正则表辑ּ常见错误的最x机。ؓ什么我们要使用<b><tt><font face="Courier New">[^,]*</font></tt></b>q样的一个表辑ּQ而不是更加简单直接的写法Q例如:<b><tt><font face="Courier New">.*</font></tt></b>Q来匚wW一个参数呢Q设x们用模?b><tt><font face="Courier New">.*</font></tt></b>来匹配字W串"10,7,2"Q它应该匚w"10,"q是"10,7,"Qؓ了解册个两义性(ambiguityQ,正则表达式规定一律按照最长的串来Q在上面的例子中是"10,7,"Q显然这样就扑և了两个参数而不是我们期望的一个。所以,我们要?b><tt><font face="Courier New">[^,]*</font></tt></b>来强制取出第一个逗号之前的部分?/p><p>q个表达式我们已l分析到了:<b><tt><font face="Courier New">foo(\([^,]*\)</font></tt></b>Q这一D可以简单的译为“当你找?b><tt>foo(</tt></b>把其后直到W一个逗号之前的部分标Cؓ<b><tt><font face="Courier New">\1</font></tt></b>”。然后我们用同L办法标记W二个参Cؓ<b><tt><font face="Courier New">\2</font></tt></b>。对W三个参数的标记Ҏ也是一P只是我们要搜索所有的字符直到x受我们ƈ没有必要L索第三个参数Q因为我们不需要调整它的位|,但是q样的模式能够保证我们只L换那些有三个参数的foo()Ҏ调用Q在foo()是一个重载(overoadingQ方法时q种明确的模式往往是比较保险的。然后,在替换部分,我们扑ֈfoo()的对应实例,然后利用标记好的部分q行替换Q是的第一和第二个参数交换位置?/p><h3>?</h3>假设有一个CSVQcomma separated valueQ文Ӟ里面有一些我们需要的信息Q但是格式却有问题,目前数据的列序是:姓名Q公司名Q州名羃写,邮政~码Q现在我们希望讲q些数据重新l织Q以便在我们的某个Y件中使用Q需要的格式为:姓名Q州名羃?邮政~码Q公司名。也是_我们要调整列序Q还要合q两个列来构成一个新列。另外,我们的Y件不能接受逗号前后面有MI格Q包括空格和制表W)所以我们还必须要去掉逗号前后的所有空根{? <p>q里有几行我们现在的数据Q?/p><ul><tt>Bill Jones,     HI-TEK Corporation ,  CA, 95011</tt><br /><tt><font face="Courier New">Sharon Lee Smith,  Design Works Incorporated,  CA, 95012</font></tt><br /><tt><font face="Courier New">B. Amos   ,  Hill Street Cafe,  CA, 95013</font></tt><br /><tt><font face="Courier New">Alexander Weatherworth,  The Crafts Store,  CA, 95014</font></tt><br /><tt><font face="Courier New">...</font></tt></ul>我们希望把它变成q个样子Q? <ul><tt>Bill Jones,CA 95011,HI-TEK Corporation</tt><br /><tt><font face="Courier New">Sharon Lee Smith,CA 95012,Design Works Incorporated</font></tt><br /><tt><font face="Courier New">B. Amos,CA 95013,Hill Street Cafe</font></tt><br /><tt><font face="Courier New">Alexander Weatherworth,CA 95014,The Crafts Store</font></tt><br /><tt><font face="Courier New">...</font></tt></ul>我们用两个正则表达式来解决q个问题。第一个移动列和合q列Q第二个用来LI格? <p>下面是W一个替换命令:</p><ul><b><tt><font face="Courier New">:%s/\([^,]*\),\([^,]*\),\([^,]*\),\(.*\)/\1,\3 \4,\2/</font></tt></b></ul>q里的方法跟?基本一PW一个列Q姓名)用这个表辑ּ来匹配:<b><tt><font face="Courier New">\([^,]*\)</font></tt></b>Q即W一个逗号之前的所有字W,而姓名内容被?b><tt><font face="Courier New">\1</font></tt></b>标记下来。公司名和州名羃写字D는同样的方法标Cؓ<b><tt><font face="Courier New">\2</font></tt></b>?b><tt><font face="Courier New">\3</font></tt></b>Q而最后一个字D는<b><tt><font face="Courier New">\(.*\)</font></tt></b>来匹配("匚w所有字W直到行?Q。替换部分则引用上面标记的那些内Ҏq行构造? <p>下面q个替换命o则用来去除空|</p><ul><b><tt><font face="Courier New">:%s/[ \t]*,[ \t]*/,/g</font></tt></b></ul>我们q是分解来看Q?b><tt><font face="Courier New">[ \t]</font></tt></b>匚wI格/制表W,<b><tt><font face="Courier New">[ \t]*</font></tt></b> 匚w0或多个空?制表W,<b><tt>[ \t]*</tt></b>,匚w0或多个空?制表W后面再加一个逗号Q最后,<b><tt><font face="Courier New">[ \t]*,[ \t]*</font></tt></b>匚w0或多个空?制表W接着一个逗号再接着0或多个空?制表W。在替换部分Q我们简单的我们扑ֈ的所有东西替换成一个逗号。这里我们用了l尾的可选的<b><tt>g</tt></b>参数Q这表示在每行中Ҏ有匹配的串执行替换(而不是缺省的只替换第一个匹配串Q? <h3>?</h3>假设有一个多字符的片断重复出玎ͼ例如Q? <blockquote><tt>Billy tried really hard</tt><br /><tt>Sally tried really really hard</tt><br /><tt>Timmy tried really really really hard</tt><br /><tt>Johnny tried really really really really hard</tt></blockquote>而你x"really"?really really"Q以及Q意数量连l出现的"really"字符串换成一个简单的"very"Qsimple is good!Q,那么以下命oQ? <blockquote><b><tt>:%s/\(really \)\(really \)*/very /</tt></b></blockquote>׃把上q的文本变成Q? <blockquote><tt>Billy tried very hard</tt><br /><tt>Sally tried very hard</tt><br /><tt>Timmy tried very hard</tt><br /><tt>Johnny tried very hard</tt></blockquote>表达?b><tt>\(really \)*</tt></b>匚w0或多个连l的"really "Q注意结有个空|Q?b><tt>\(really \)\(really \)*</tt></b> 匚w1个或多个q箋?really "实例? <h2><a name="HardExamples"></a>困难的例子(不可思议的象形文字)</h2><i>Coming soon</i>. <p></p><hr /><h1><a name="Regular_Expressions_In_Various_Tools"></a>不同工具中的正则表达?/h1>OKQ你已经准备使用REQregular expressionsQ正则表辑ּQ,但是你ƈ准备使用vi。所以,在这里我们给Z些在其他工具中用RE的例子。另外,我还会ȝ一下你在不同程序之间用RE可能发现的区别? <p>当然Q你也可以在Visual C++~辑器中使用RE。选择Edit->ReplaceQ然后选择"Regular expression"选择框,Find What输入框对应上面介l的vi命o<b><tt>:%s/pat1/pat2/g</tt></b>中的pat1部分Q而Replace输入框对应pat2部分。但是,Z得到vi的执行范围和<b><tt>g</tt></b>选项Q你要用Replace All或者适当的手工Find Next and ReplaceQ译者按Q知道ؓ啥有人骂微Y弱智了吧Q虽然VC中可以选中一个范围的文本Q然后在其中执行替换Q但是M不够vi那么灉|和典雅)?/p><h2>sed</h2><p>Sed?b><u>S</u></b>tream <b><u>ED</u></b>itor的羃写,是Unix下常用的Z文g和管道的~辑工具Q可以在手册中得到关于sed的详l信息?</p><p>q里是一些有的sed脚本Q假定我们正在处理一个叫做price.txt的文件。注意这些编辑ƈ不会改变源文Ӟsed只是处理源文件的每一行ƈ把结果显C在标准输出中(当然很容易用重定向来定ӞQ? </p><p></p><table><tbody><tr><td><b><i>sed脚本</i></b></td><td> </td><td><b><i>描述</i></b></td></tr><tr><td><hr width="100%" /></td><td></td><td><hr width="100%" /></td></tr><tr valign="baseline"><td><b><tt>sed 's/^$/d' price.txt</tt></b></td><td></td><td>删除所有空?/td></tr><tr><td><b><tt>sed 's/^[ \t]*$/d' price.txt</tt></b></td><td></td><td>删除所有只包含I格或者制表符的行</td></tr><tr><td><b><tt>sed 's/"http://g' price.txt</tt></b></td><td></td><td>删除所有引?/td></tr></tbody></table><h2>awk</h2>awk是一U编E语aQ可以用来对文本数据q行复杂的分析和处理。可以在手册中得到关于awk的详l信息。这个古怪的名字是它作者们的姓的羃写(AhoQWeinberger和KernighanQ? <p>在AhoQWeinberger和Kernighan的书<u>The AWK Programming Language</u>中有很多很好的awk的例子,请不要让下面q些微不道的脚本例子限制你对awk强大能力的理解。我们同样假定我们针对price.txt文gq行处理Q跟sed一Pawk也只是把l果昄在终端上。? </p><p></p><table><tbody><tr><td><b><i>awk脚本</i></b></td><td> </td><td><b><i>描述</i></b></td></tr><tr><td><hr width="100%" /></td><td></td><td><hr width="100%" /></td></tr><tr valign="baseline"><td><b><tt>awk '$0 !~ /^$/' price.txt</tt></b></td><td></td><td>删除所有空?/td></tr><tr><td><b><tt>awk 'NF > 0' price.txt</tt></b></td><td></td><td>awk中一个更好的删除所有行的办?/td></tr><tr valign="baseline"><td><b><tt>awk '$2 ~ /^[JT]/ {print $3}' price.txt</tt></b></td><td></td><td>打印所有第二个字段?J'或?T'打头的行中的W三个字D?/td></tr><tr valign="baseline"><td nowrap=""><b><tt>awk '$2 !~ /[Mm]isc/ {print $3 + $4}' price.txt</tt></b></td><td></td><td>针对所有第二个字段不包?Misc'或?misc'的行Q打印第3和第4列的和(假定为数字)</td></tr><tr valign="baseline"><td><b><tt>awk '$3 !~ /^[0-9]+\.[0-9]*$/ {print $0}' price.txt</tt></b></td><td></td><td>打印所有第三个字段不是数字的行Q这里数字是?tt>d.d</tt>或?tt>dq样的Ş式,其中</tt><tt>d</tt>??的Q何数?/td></tr><tr valign="baseline"><td><b><tt>awk '$2 ~ /John|Fred/ {print $0}' price.txt</tt></b></td><td></td><td>如果W二个字D包?John'或?Fred'则打印整?/td></tr></tbody></table><h2>grep</h2>grep是一个用来在一个或者多个文件或者输入流中用REq行查找的程序。它的name~程语言可以用来针对文g和管道进行处理。可以在手册中得到关于grep的完整信息。这个同样古怪的名字来源于vi的一个命令,<b><tt>g/</tt></b><i>re</i><b><tt>/p</tt></b>Q意思是<b>g</b>lobal <b>r</b>egular <b>e</b>xpression <b>p</b>rint? <p>下面的例子中我们假定在文件phone.txt中包含以下的文本Q——其格式是姓加一个逗号Q然后是名,然后是一个制表符Q然后是电话LQ?/p><ul><p><tt>Francis, John           5-3871</tt><br /><tt>Wong, Fred              4-4123</tt><br /><tt>Jones, Thomas           1-4122</tt><br /><tt>Salazar, Richard        5-2522</tt></p></ul><p></p><table><tbody><tr><td><b><i>grep命o</i></b></td><td><b><i> </i></b></td><td><b><i>描述</i></b></td></tr><tr><td><hr width="100%" /></td><td></td><td><hr width="100%" /></td></tr><tr valign="baseline"><td><b><tt>grep '\t5-...1' phone.txt</tt></b></td><td></td><td>把所有电话号码以5开头以1l束的行打印出来Q注意制表符是用<b><tt>\t</tt></b>表示?/td></tr><tr valign="baseline"><td nowrap=""><b><tt>grep '^S[^ ]* R' phone.txt</tt></b></td><td></td><td>打印所有姓以S打头和名以R打头的行</td></tr><tr valign="baseline"><td><b><tt>grep '^[JW]' phone.txt</tt></b></td><td></td><td>打印所有姓开头是J或者W的行</td></tr><tr valign="baseline"><td><b><tt>grep ', ....\t' phone.txt</tt></b></td><td></td><td>打印所有姓?个字W的行,注意制表W是?b><tt>\t</tt></b>表示?/td></tr><tr valign="baseline"><td><b><tt>grep -v '^[JW]' phone.txt</tt></b></td><td></td><td>打印所有不以J或者W开头的?/td></tr><tr valign="baseline"><td><b><tt>grep '^[M-Z]' phone.txt</tt></b></td><td></td><td>打印所有姓的开头是M到Z之间M字符的行</td></tr><tr valign="baseline"><td><b><tt>grep '^[M-Z].*[12]' phone.txt</tt></b></td><td></td><td>打印所有姓的开头是M到Z之间M字符Qƈ且点号号码结是1或?的行</td></tr></tbody></table><h2>egrep</h2>egrep是grep的一个扩展版本,它在它的正则表达式中支持更多的元字符。下面的例子中我们假定在文gphone.txt中包含以下的文本Q——其格式是姓加一个逗号Q然后是名,然后是一个制表符Q然后是电话LQ? <ul><tt>Francis, John           5-3871</tt><br /><tt>Wong, Fred              4-4123</tt><br /><tt>Jones, Thomas           1-4122</tt><br /><tt>Salazar, Richard        5-2522</tt></ul><p></p><table><tbody><tr><td><b><i>egrep command</i></b></td><td><b><i> </i></b></td><td><b><i>Description</i></b></td></tr><tr><td><hr width="100%" /></td><td></td><td><hr width="100%" /></td></tr><tr valign="baseline"><td><b><tt>egrep '(John|Fred)' phone.txt</tt></b></td><td></td><td>打印所有包含名?i>John</i>或?i>Fred</i>的行</td></tr><tr valign="baseline"><td nowrap=""><b><tt>egrep 'John|22$|^W' phone.txt</tt></b></td><td></td><td>打印所有包?i>John</i> 或者以22l束或者以<i>W</i>的行</td></tr><tr><td><b><tt>egrep 'net(work)?s' report.txt</tt></b></td><td></td><td>从report.txt中找到所有包?i>networks</i>或?i>nets</i>的行</td></tr></tbody></table><h2><hr width="100%" /></h2><h1><a name="Regular Expressions Syntax"></a>正则表达式语法支持情?/h1><table cellspacing="0" border="1"><tbody><tr><td><b>命o或环?/b></td><td><b><tt><font face="Courier New">.</font></tt></b></td><td><b><tt><font face="Courier New">[ ]</font></tt></b></td><td><b><tt><font face="Courier New">^</font></tt></b></td><td><b><tt><font face="Courier New">$</font></tt></b></td><td><b><tt><font face="Courier New">\( \)</font></tt></b></td><td><b><tt><font face="Courier New">\{ \}</font></tt></b></td><td><b><tt><font face="Courier New">?</font></tt></b></td><td><b><tt><font face="Courier New">+</font></tt></b></td><td><b><tt><font face="Courier New">|</font></tt></b></td><td><b><tt><font face="Courier New">( )</font></tt></b></td></tr><tr><td>vi</td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr><tr><td>Visual C++</td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr><tr><td>awk</td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> </td><td> X </td><td> X </td><td> X </td><td> X </td></tr><tr><td>sed</td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> </td><td> </td><td> </td></tr><tr><td>Tcl</td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> X </td><td> X </td><td> X </td><td> X </td></tr><tr><td>ex</td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> </td><td> </td><td> </td></tr><tr><td>grep</td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> </td><td> </td><td> </td></tr><tr><td>egrep</td><td> X </td><td> X</td><td> X </td><td> X </td><td> X </td><td> </td><td> X </td><td> X </td><td> X </td><td> X </td></tr><tr><td>fgrep</td><td> X </td><td> X </td><td> X </td><td> X </td><td> X </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr><tr><td>perl</td><td> X</td><td> X</td><td> X</td><td> X</td><td> X</td><td> </td><td> X</td><td> X</td><td> X</td><td> X</td></tr></tbody></table><p> </p><hr /><h1><a name="ViSubstitutionCommandSyntax"></a>vi替换命o?/h1>Vi的替换命令: <ul><b><tt>:</tt></b><i>range</i><b><tt>s/</tt></b><i>pat1</i><b><tt>/</tt></b><i>pat2</i><b><tt>/g</tt></b></ul>其中 <ul><b><tt>:</tt></b> q是Vi的命令执行界面?</ul><ul><i>range </i>是命令执行范围的指定Q可以用百分号Q?Q表C所有行Q用点Q?Q表C当前行Q用美元符P$Q表C最后一行。你q可以用行P例如<b><tt>10,20</tt></b>表示W?0?0行,<b><tt>.,$</tt></b>表示当前行到最后一行,<b><tt>.+2,$-5</tt></b>表示当前行后两行直到全文的倒数W五行,{等? <p><b><tt>s</tt></b> 表示其后是一个替换命令?/p><p><i>pat1 </i>q是要查扄一个正则表辑ּQ这文章中有一大堆例子?/p></ul><ul><i>pat2 </i>q是希望把匹配串变成的模式的正则表达式,q篇文章中有一大堆例子? <p><b><tt>g</tt></b> 可选标志,带这个标志表C替换将针对行中每个匚w的串q行Q否则则只替换行中第一个匹配串?/p></ul>|上有很多vi的在U手册,你可以访问他们以获得更加完整的信息?<img src ="http://m.tkk7.com/raozhh/aggbug/38501.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/raozhh/" target="_blank">饶志?/a> 2006-03-31 16:27 <a href="http://m.tkk7.com/raozhh/articles/38501.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式详l解http://m.tkk7.com/raozhh/articles/38500.html饶志?/dc:creator>饶志?/author>Fri, 31 Mar 2006 08:26:00 GMThttp://m.tkk7.com/raozhh/articles/38500.htmlhttp://m.tkk7.com/raozhh/comments/38500.htmlhttp://m.tkk7.com/raozhh/articles/38500.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/38500.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/38500.html

正则表达式详l解


 
 


字符/
意义Q对于字W,通常表示按字面意义,指出接着的字WؓҎ字符Q不作解释?br />例如Q?b/匚w字符’b?通过在b 前面加一个反斜杠Q也是/b/Q则该字W变成特D字W,表示
匚w一个单词的分界Uѝ?br />或者:
对于几个字符Q通常说明是特D的Q指出紧接着的字W不是特D的Q而应该按字面解释?br />例如Q?是一个特D字W,匚wL个字W?包括0个字W?Q例如:/a*/意味匚w0个或多个a。ؓ了匹配字面上?Q在a前面加一个反斜杠Q例如:/a*/匚w’a*’?br />
字符^
意义Q表C匹配的字符必须在最前边?br />例如Q?^A/不匹?an A,"中的’A’,但匹?An A."中最前面的’A’?br />
字符$
意义Q与^cMQ匹配最末的字符?br />例如Q?t$/不匹?eater"中的’t’,但匹?eat"中的’t’?br />
字符*
意义Q匹?前面的字W?ơ或nơ?br />例如:/bo*/匚w"A ghost booooed"中的’boooo’或"A bird warbled"中的’b’,但不匚w"Agoat g
runted"中的M字符?br />
字符+
意义Q匹?号前面的字符1ơ或nơ。等价于{1,}?br />例如Q?a+/匚w"candy"中的’a’和"caaaaaaandy."中的所有’a’?br />
字符?
意义Q匹?前面的字W?ơ或1ơ?br />例如Q?e?le?/匚w"angel"中的’el’和"angle."中的’le’?br />
字符.
意义Q?数?匚w除换行符外的所有单个的字符?br />例如Q?.n/匚w"nay, an apple is on the tree"中的’an’和’on’,但不匚w’nay’?br />

字符(x)
意义Q匹配’x’ƈ记录匚w的倹{?br />例如Q?(foo)/匚w和记?foo bar."中的’foo’。匹配子串能被结果数l中的素[1], ...,[n] q?br />回,或被RegExp对象的属? ..., q回?br />
字符x│y
意义Q匹配’x’或者’y’?br />例如Q?green│red/匚w"green apple"中的’green’和"red apple."中的’red’?br />
字符{ n }
意义Q这里的n是一个正整数。匹配前面的n个字W?br />例如Q?a{ 2 }/不匹?candy,"中的’a’,但匹?caandy," 中的所有’a’和"caaandy."中前面的两个’a’?br />
字符{ n, }
意义Q这里的n是一个正整数。匹配至n个前面的字符?br />例如Q?a{ 2, }不匹?candy"中的’a’,但匹?caandy"中的所有’a’和"caaaaaaandy."中的所有’a?br />
字符{ n,m }
意义Q这里的n和m都是正整数。匹配至n个最多m个前面的字符?br />例如Q?a{ 1,3 }/不匹?cndy"中的M字符Q但匚w "candy,"中的’a’,"caandy," 中的前面两个
’a’和"caaaaaaandy"中前面的三个’a’,注意Q即?caaaaaaandy" 中有很多个’a’,但只匚w前面的三 个’a’即"aaa"?br />
字符[xyz]
意义Q一字符列表Q匹配列Z的Q一字符。你可以通过q字W?指出一个字W范围?br />例如Q[abcd]跟[a-c]一栗它们匹?brisket"中的’b’和"ache"中的’c’?br />
字符[^xyz]
意义Q一字符补集Q也是_它匹配除了列出的字符外的所有东ѝ?你可以用连字符-指出一 字符范围?br />例如Q[^abc]和[^a-c]{hQ它们最早匹?brisket"中的’r’和"chop."中的’h’?br />
字符
意义Q匹配一个空?不要与bh)

字符b
意义Q匹配一个单词的分界U,比如一个空?不要与؜?
例如Q?bnw/匚w"noonday"中的’no’,/wyb/匚w"possibly yesterday."中的’ly’?br />
字符B
意义Q匹配一个单词的非分界线
例如Q?wBn/匚w"noonday"中的’on’,/yBw/匚w"possibly yesterday."中的’ye’?br />
字符cX
意义Q这里的X是一个控制字W。匹配一个字W串的控制字W?br />例如Q?cM/匚w一个字W串中的control-M?br />
字符d
意义Q匹配一个数字,{h于[0-9]?br />例如Q?d/?[0-9]/匚w"B2 is the suite number."中的?’?br />
字符D
意义Q匹配Q何的非数字,{h于[^0-9]?br />例如Q?D/?[^0-9]/匚w"B2 is the suite number."中的’B’?br />
字符f
意义Q匹配一个表单符

字符n
意义Q匹配一个换行符

字符r
意义Q匹配一个回车符

字符s
意义Q匹配一个单个whiteI格W,包括I格QtabQform feedQ换行符Q等价于[ fnrtv]?br />例如Q?sw*/匚w"foo bar."中的?bar’?br />
字符S
意义Q匹配除whiteI格W以外的一个单个的字符Q等价于[^ fnrtv]?br />例如Q?S/w*匚w"foo bar."中的’foo’?br />
字符t
意义Q匹配一个制表符

字符v
意义Q匹配一个顶头制表符

字符w
意义Q匹配所有的数字和字母以及下划线Q等价于[A-Za-z0-9_]?br />例如Q?w/匚w"apple,"中的’a’,".28,"中的?’和"3D."中的?’?br />
字符W
意义Q匹配除数字、字母外及下划线外的其它字符Q等价于[^A-Za-z0-9_]?br />例如Q?W/或?[^$A-Za-z0-9_]/匚w"50%."中的?’?br />
字符n
意义Q这里的n是一个正整数。匹配一个正则表辑ּ的最后一个子串的n的?计数左圆括号)?br />
例如Q?apple(,)sorange1/匚w"apple, orange, cherry, peach."中的’apple, orange’,下面有一个更加完整的例子?br />注意Q如果左圆括号中的数字比n指定的数字还,则n取下一行的八进制escape作ؓ描述?br />
字符ooctal和xhex
意义Q这里的ooctal是一个八q制的escape|而xhex是一个十六进制的escape|允许在一个正则表辑ּ中嵌入ASCII?br />
?下表是元字符及其在正则表辑ּ上下文中的行为的一个完整列表:

字符 描述 \
下一个字W标Cؓ一个特D字W、或一个原义字W、或一个后向引用、或一个八q制转义W。例如,'n' 匚w字符 "n"?\n' 匚w一个换行符。序?'\' 匚w "" ?"\(" 则匹?"("?
^
匚w输入字符串的开始位|。如果设|了 RegExp 对象?Multiline 属性,^ 也匹?'\n' ?'\r' 之后的位|?
$
匚w输入字符串的l束位置。如果设|了RegExp 对象?Multiline 属性,$ 也匹?'\n' ?'\r' 之前的位|?
*
匚w前面的子表达式零ơ或多次。例如,zo* 能匹?"z" 以及 "zoo"?* {h于{0,}?
+ 匚w前面的子表达式一ơ或多次。例如,'zo+' 能匹?"zo" 以及 "zoo"Q但不能匚w "z"? {h?{1,}?
?
匚w前面的子表达式零ơ或一ơ。例如,"do(es)?" 可以匚w "do" ?"does" 中的"do" ? {h?{0,1}?
{n}
n 是一个非负整数。匹配确定的 n ơ。例如,'o{2}' 不能匚w "Bob" 中的 'o'Q但是能匚w "food" 中的两个 o?
{n,}
n 是一个非负整数。至匹配n ơ。例如,'o{2,}' 不能匚w "Bob" 中的 'o'Q但能匹?"foooood" 中的所?o?o{1,}' {h?'o+'?o{0,}' 则等价于 'o*'?
{n,m}
m ?n 均ؓ非负整数Q其中n <= m。最匹?n ơ且最多匹?m ơ。刘Q?"o{1,3}" 匹?"fooooood" 中的前三?o?o{0,1}' {h?'o?'。请注意在逗号和两个数之间不能有空根{?
?
当该字符紧跟在Q何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面Ӟ匚w模式是非贪婪的。非贪婪模式可能少的匹配所搜烦的字W串Q而默认的贪婪模式则尽可能多的匚w所搜烦的字W串。例如,对于字符?"oooo"Q?o+?' 匹配单?"o"Q?'o+' 匹配所?'o'?
. 
匚w?"\n" 之外的Q何单个字W。要匚w包括 '\n' 在内的Q何字W,请用象 '[.\n]' 的模式?
(pattern)
匚wpattern q获取这一匚w。所获取的匹配可以从产生?Matches 集合得到Q在VBScript 中?SubMatches 集合Q在JScript 中则使用 {CONTENT}?属性。要匚w圆括号字W,请?'\(' ?'\)'?
(?:pattern)
匚w pattern 但不获取匚wl果Q也是说这是一个非获取匚wQ不q行存储供以后用。这在?"? 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 是一个比 'industry|industries' 更简略的表达式?
(?=pattern)
正向预查Q在M匚w pattern 的字W串开始处匚w查找字符丌Ӏ这是一个非获取匚wQ也是_该匹配不需要获取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹?"Windows 2000" 中的 "Windows" Q但不能匚w "Windows 3.1" 中的 "Windows"。预查不消耗字W,也就是说Q在一个匹配发生后Q在最后一ơ匹配之后立卛_始下一ơ匹配的搜烦Q而不是从包含预查的字W之后开始?
(?!pattern)
负向预查Q在M不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字W串开始处匚w查找字符丌Ӏ这是一个非获取匚wQ也是_该匹配不需要获取供以后使用。例?Windows (?!95|98|NT|2000)' 能匹?"Windows 3.1" 中的 "Windows"Q但不能匚w "Windows 2000" 中的 "Windows"。预查不消耗字W,也就是说Q在一个匹配发生后Q在最后一ơ匹配之后立卛_始下一ơ匹配的搜烦Q而不是从包含预查的字W之后开?
x|y 
匚w x ?y。例如,'z|food' 能匹?"z" ?"food"?(z|f)ood' 则匹?"zood" ?"food"?
[xyz]
字符集合。匹配所包含的Q意一个字W。例如, '[abc]' 可以匚w "plain" 中的 'a'?
[^xyz]
负值字W集合。匹配未包含的Q意字W。例如, '[^abc]' 可以匚w "plain" 中的'p'?
[a-z]
字符范围。匹配指定范围内的Q意字W。例如,'[a-z]' 可以匚w 'a' ?'z' 范围内的L写字母字符?
[^a-z]
负值字W范围。匹配Q何不在指定范围内的Q意字W。例如,'[^a-z]' 可以匚wM不在 'a' ?'z' 范围内的L字符?
\b
匚w一个单词边界,也就是指单词和空格间的位|。例如, 'er\b' 可以匚w"never" 中的 'er'Q但不能匚w "verb" 中的 'er'?
\B
匚w非单词边界?er\B' 能匹?"verb" 中的 'er'Q但不能匚w "never" 中的 'er'?
\cx
匚w由x指明的控制字W。例如, \cM 匚w一?Control-M 或回车符?x 的值必Mؓ A-Z ?a-z 之一。否则,?c 视ؓ一个原义的 'c' 字符?
\d
匚w一个数字字W。等价于 [0-9]?
\D
匚w一个非数字字符。等价于 [^0-9]?
\f
匚w一个换늬。等价于 \x0c ?\cL?
\n
匚w一个换行符。等价于 \x0a ?\cJ?
\r
匚w一个回车符。等价于 \x0d ?\cM?
\s
匚wMI白字符Q包括空根{制表符、换늬{等。等价于 [ \f\n\r\t\v]?
\S
匚wM非空白字W。等价于 [^ \f\n\r\t\v]?
\t
匚w一个制表符。等价于 \x09 ?\cI?
\v
匚w一个垂直制表符。等价于 \x0b ?\cK?
\w
匚w包括下划U的M单词字符。等价于'[A-Za-z0-9_]'?
\W
匚wM非单词字W。等价于 '[^A-Za-z0-9_]'?
\xn
匚w nQ其?n 为十六进制{义倹{十六进制{义值必Mؓ定的两个数字长。例如, '\x41' 匚w "A"?\x041' 则等价于 '\x04' & "1"。正则表辑ּ中可以?ASCII ~码?
\num
匚w numQ其?num 是一个正整数。对所获取的匹配的引用。例如,'(.)' 匚w两个q箋的相同字W?
\n
标识一个八q制转义值或一个后向引用。如?\n 之前臛_ n 个获取的子表辑ּQ则 n 为后向引用。否则,如果 n 为八q制数字 (0-7)Q则 n Z个八q制转义倹{?
\nm
标识一个八q制转义值或一个后向引用。如?\nm 之前臛_有is preceded by at least nm 个获取得子表辑ּQ则 nm 为后向引用。如?\nm 之前臛_?n 个获取,?n Z个后跟文?m 的后向引用。如果前面的条g都不满Q若  n ?m 均ؓ八进制数?(0-7)Q则 \nm 匹配八q制转义?nm?
\nml
如果 n 为八q制数字 (0-3)Q且 m ?l 均ؓ八进制数?(0-7)Q则匚w八进制{义?nml?
\un
匚w nQ其?n 是一个用四个十六q制数字表示?Unicode 字符。例如,\u00A9 匚w版权W号 (?)?


]]>
SQLServer,Access,Oracle数据库用户对象信息获?/title><link>http://m.tkk7.com/raozhh/articles/37126.html</link><dc:creator>饶志?/dc:creator><author>饶志?/author><pubDate>Fri, 24 Mar 2006 00:36:00 GMT</pubDate><guid>http://m.tkk7.com/raozhh/articles/37126.html</guid><wfw:comment>http://m.tkk7.com/raozhh/comments/37126.html</wfw:comment><comments>http://m.tkk7.com/raozhh/articles/37126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/raozhh/comments/commentRss/37126.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/raozhh/services/trackbacks/37126.html</trackback:ping><description><![CDATA[------------------------- MS SQLServer ------------------------------------------------------------ <p></p><p>--表说?br />SELECT dbo.sysobjects.name AS TableName, <br />dbo.sysproperties.[value] AS TableDesc<br />FROM dbo.sysproperties INNER JOIN<br />dbo.sysobjects ON dbo.sysproperties.id = dbo.sysobjects.id<br />WHERE (dbo.sysproperties.smallid = 0)<br />ORDER BY dbo.sysobjects.name</p><p>--字段说明<br />SELECT dbo.sysobjects.name AS TableName, dbo.syscolumns.colid, <br />dbo.syscolumns.name AS ColName, dbo.sysproperties.[value] AS ColDesc<br />FROM dbo.sysproperties INNER JOIN<br />dbo.sysobjects ON dbo.sysproperties.id = dbo.sysobjects.id INNER JOIN<br />dbo.syscolumns ON dbo.sysobjects.id = dbo.syscolumns.id AND <br />dbo.sysproperties.smallid = dbo.syscolumns.colid<br />ORDER BY dbo.sysobjects.name, dbo.syscolumns.colid</p><p></p><p>--主键、外键信??<br />select<br />c_obj.name as CONSTRAINT_NAME<br />,t_obj.name as TABLE_NAME<br />,col.name as COLUMN_NAME<br />,case col.colid <br />when ref.fkey1 then 1 <br />when ref.fkey2 then 2 <br />when ref.fkey3 then 3 <br />when ref.fkey4 then 4 <br />when ref.fkey5 then 5 <br />when ref.fkey6 then 6 <br />when ref.fkey7 then 7 <br />when ref.fkey8 then 8 <br />when ref.fkey9 then 9 <br />when ref.fkey10 then 10 <br />when ref.fkey11 then 11 <br />when ref.fkey12 then 12 <br />when ref.fkey13 then 13 <br />when ref.fkey14 then 14 <br />when ref.fkey15 then 15 <br />when ref.fkey16 then 16<br />end as ORDINAL_POSITION<br />from<br />sysobjects c_obj<br />,sysobjects t_obj<br />,syscolumns col<br />,sysreferences ref<br />where<br />permissions(t_obj.id) != 0<br />and c_obj.xtype in ('F ')<br />and t_obj.id = c_obj.parent_obj<br />and t_obj.id = col.id<br />and col.colid in <br />(ref.fkey1,ref.fkey2,ref.fkey3,ref.fkey4,ref.fkey5,ref.fkey6,<br />ref.fkey7,ref.fkey8,ref.fkey9,ref.fkey10,ref.fkey11,ref.fkey12,<br />ref.fkey13,ref.fkey14,ref.fkey15,ref.fkey16)<br />and c_obj.id = ref.constid<br />union<br />select<br />i.name as CONSTRAINT_NAME<br />,t_obj.name as TABLE_NAME<br />,col.name as COLUMN_NAME<br />,v.number as ORDINAL_POSITION<br />from<br />sysobjects c_obj<br />,sysobjects t_obj<br />,syscolumns col<br />,master.dbo.spt_values v<br />,sysindexes i<br />where<br />permissions(t_obj.id) != 0<br />and c_obj.xtype in ('UQ' ,'PK')<br />and t_obj.id = c_obj.parent_obj<br />and t_obj.xtype = 'U'<br />and t_obj.id = col.id<br />and col.name = index_col(t_obj.name,i.indid,v.number)<br />and t_obj.id = i.id<br />and c_obj.name = i.name<br />and v.number > 0 <br />and v.number <= i.keycnt <br />and v.type = 'P'</p><p>order by CONSTRAINT_NAME, ORDINAL_POSITION</p><p><br />--主键、外键对??<br />select<br />fc_obj.name as CONSTRAINT_NAME<br />,i.name as UNIQUE_CONSTRAINT_NAME<br />from <br />sysobjects fc_obj<br />,sysreferences r<br />,sysindexes i<br />,sysobjects pc_obj<br />where <br />permissions(fc_obj.parent_obj) != 0<br />and fc_obj.xtype = 'F'<br />and r.constid = fc_obj.id<br />and r.rkeyid = i.id<br />and r.rkeyindid = i.indid<br />and r.rkeyid = pc_obj.id</p><p><br />------------------------------------------ ORACLE ----------------------------------------------------</p><p>--表信?br />select * from all_tab_comments t<br />where owner='DBO'</p><p>--列信?br />select * from all_col_comments t<br />where owner='DBO'</p><p>--主键、外键对?br />select OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME, R_OWNER, R_CONSTRAINT_NAME<br />from all_constraints<br />where owner='DBO' and (Constraint_Type='P' or Constraint_Type='R')</p><p><br />--主键、外键信?br />select * <br />from all_cons_columns <br />where owner='DBO'<br />order by Constraint_Name, Position</p><p><br />-------------------------------------------- Access ----------------------------------------------------<br />//Access中的pȝ表MSysobjects存储属性的字段是二q制格式Q不能直接分?br />//可以采用ADO自带的OpenSchemaҎ获得相关信息</p><p>//use ADOInt.pas<br />//po: TableName<br />//DBCon:TADOConnection<br />/ds:TADODataSet<br /><br />--表信?br />DBCon.OpenSchema(siTables, VarArrayOf([Null, Null, 'Table']), EmptyParam, ds);</p><p>--列信?br />DBCon.OpenSchema(siColumns, VarArrayOf([Null, Null, 'po']), EmptyParam, ds);<br /><br />--主键<br />DBCon.OpenSchema(siPrimaryKeys, EmptyParam, EmptyParam, ds);<br /><br /><br />--主键、外键对?br />DBCon.OpenSchema(siForeignKeys, EmptyParam, EmptyParam, ds); </p><img src ="http://m.tkk7.com/raozhh/aggbug/37126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/raozhh/" target="_blank">饶志?/a> 2006-03-24 08:36 <a href="http://m.tkk7.com/raozhh/articles/37126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSF自定义验证标{?/title><link>http://m.tkk7.com/raozhh/articles/33890.html</link><dc:creator>饶志?/dc:creator><author>饶志?/author><pubDate>Mon, 06 Mar 2006 09:21:00 GMT</pubDate><guid>http://m.tkk7.com/raozhh/articles/33890.html</guid><wfw:comment>http://m.tkk7.com/raozhh/comments/33890.html</wfw:comment><comments>http://m.tkk7.com/raozhh/articles/33890.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/raozhh/comments/commentRss/33890.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/raozhh/services/trackbacks/33890.html</trackback:ping><description><![CDATA[<div class="wujquvs" id=printhead> <H3>From PmWiki@caterpillar</H3> <H1 class=pagename><A >JavaServerFaces: CustomConverterValidatorTag</A></H1></DIV><!--PageText--> <div class="qgkooeq" id=wikitext>?<A class=wikilink >自訂驗證?/A> 中,我們的驗證器只能驗證一EpatternQ?+[0-9]+Q,我們希望可以在JSF頁面上自a匹配的patternQ然而由於我們?lt;f: validator>這個通用的驗證器標籤Q為了要能提供pattern屬性,我們可以?lt;f:attribute>標籤來設|,例如Q?BR><PRE> <BR> ....<BR> <h:inputSecret value="#{user.password}" required="true"> <BR> <f:validator validatorId="onlyfun.caterpillar.Password"/><BR> <f:attribute name="pattern" value=".+[0-9]+"/><BR> </h:inputSecret><p><BR> ....<BR> <BR></PRE> <P></P>使用<f:attribute>標籤來設定屬性,接著我們可以如下取得所a定的屬性:<BR><PRE> <BR> ....<BR> public void validate(FacesContext context, <BR> UIComponent component, <BR> Object obj)<BR> throws ValidatorException {<BR> ....<BR> String pattern = (String)<BR> component.getAttributes().get("pattern");<BR> ....<BR> }<BR> ....<BR> <BR></PRE> <P></P>您也可以開發自己的一i驗證標c,並提供相關屬性設定,這需要瞭解JSP Tag Library的撰寫,所以請您先參?<A class=wikilink >JSP/Servlet</A> 中有關於JSP Tag Library的介紏V?BR> <P></P>要開發驗證器轉用標籤Q您可以直接J承javax.faces.webapp.ValidatorTagQ這個類別可以幫您處理大部䆾的細Q您所需要的Q就是重新定它的createValidator()ҎQ我們以改寫 <A class=wikilink >自訂驗證?/A> 中的PasswordValidatorZQ?BR> <UL> <LI>PasswordValidator.java </LI></UL><PRE> <BR> package onlyfun.caterpillar;<BR><BR> import javax.faces.application.FacesMessage;<BR> import javax.faces.component.UIComponent;<BR> import javax.faces.context.FacesContext;<BR> import javax.faces.validator.Validator;<BR> import javax.faces.validator.ValidatorException;<BR><BR> public class PasswordValidator implements Validator {<BR> private String pattern;<BR><BR> public void setPattern(String pattern) {<BR> this.pattern = pattern;<BR> }<BR> <BR> public void validate(FacesContext context, <BR> UIComponent component, <BR> Object obj)<BR> throws ValidatorException {<BR> String password = (String) obj;<BR> <BR> if(password.length() < 6) {<BR> FacesMessage message = new FacesMessage(<BR> FacesMessage.SEVERITY_ERROR, <BR> "字元長度於6", "字元長度不得於6");<BR> throw new ValidatorException(message);<BR> }<BR> <BR> if(pattern != null && !password.matches(pattern)) {<BR> FacesMessage message = new FacesMessage(<BR> FacesMessage.SEVERITY_ERROR, <BR> "密碼必須包括字元與數?, <BR> "密碼必須是字元加數字所i成");<BR> throw new ValidatorException(message);<BR> }<BR> }<BR> }<BR> <BR></PRE> <P></P>主要的差別是我們提供了pattern屬性,在validate()Ҏ中進行驗證時,是根據我們所a定的pattern屬性,接著我們繼?javax.faces.webapp.ValidatorTag來撰寫自q驗證標籤Q?BR><PRE> <BR> package onlyfun.caterpillar;<BR><BR> import javax.faces.application.Application;<BR> import javax.faces.context.FacesContext;<BR> import javax.faces.validator.Validator;<BR> import javax.faces.webapp.ValidatorTag;<BR><BR> public class PasswordValidatorTag extends ValidatorTag {<BR> private String pattern;<BR> <BR> public void setPattern(String pattern) {<BR> this.pattern = pattern;<BR> }<BR> <BR> protected Validator createValidator() {<BR> Application application = <BR> FacesContext.getCurrentInstance().<BR> getApplication();<BR> PasswordValidator validator = <BR> (PasswordValidator) application.createValidator(<BR> "onlyfun.caterpillar.Password");<BR> validator.setPattern(pattern);<BR> return validator;<BR> }<BR> }<BR> <BR></PRE> <P></P>application.createValidator()Ҏ建立驗證器物件時Q是Ҏ在faces-config.xml中註冊驗證器的識別(Validater IDQ:<BR> <UL> <LI>faces-config.xml </LI></UL><PRE> <BR> <?xml version="1.0"?><BR> <!DOCTYPE faces-config PUBLIC<BR> "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"<BR> "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"><BR><BR> <faces-config><BR> ....<BR> <validator><BR> <validator-id><BR> onlyfun.caterpillar.Password<BR> </validator-id><BR> <validator-class><BR> onlyfun.caterpillar.PasswordValidator<BR> </validator-class><BR> </validator><BR> ....<BR> </faces-config><BR> <BR></PRE> <P></P>剩下來的工作Q就是佈|tld描述檔了Q我們簡單的定義一下:<BR> <UL> <LI>taglib.tld </LI></UL><PRE> <BR> <?xml version="1.0" encoding="UTF-8" ?> <BR> <BR> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" <BR> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <BR> xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee <BR> web-jsptaglibrary_2_0.xsd" <BR> version="2.0"> <BR> <BR> <description>PasswordValidator Tag</description> <BR> <tlib-version>1.0</tlib-version> <BR> <jsp-version>2.0</jsp-version> <BR> <short-name>co</short-name> <BR> <uri>http://caterpillar.onlyfun.net</uri> <BR><BR> <tag> <BR> <description>PasswordValidator</description> <BR> <name>passwordValidator</name> <BR> <tag-class><BR> onlyfun.caterpillar.PasswordValidatorTag<BR> </tag-class> <BR> <body-content>empty</body-content> <BR> <attribute> <BR> <name>pattern</name> <BR> <required>true</required> <BR> <rtexprvalue>false</rtexprvalue> <BR> </attribute> <BR> </tag> <BR><BR> </taglib><BR> <BR></PRE> <P></P>而我們的index.jsp改寫如下Q?BR> <UL> <LI>index.jsp </LI></UL><PRE> <BR> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %><BR> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %><BR> <%@ taglib uri="/WEB-INF/taglib.tld" prefix="co" %><BR> <%@page contentType="text/html;charset=Big5"%> <BR> <html><BR> <head><BR> <title>驗證器示?lt;/title><BR> </head><BR> <body><BR> <f:view><BR> <h:messages layout="table" style="color:red"/><BR> <h:form><BR> <h3>請入您的名E?lt;/h3><BR> <h:outputText value="#{user.errMessage}"/><p><BR> 名稱: <h:inputText value="#{user.name}" <BR> required="true"/><p><BR> 密碼: <h:inputSecret value="#{user.password}" <BR> required="true"><BR> <co:passwordValidator pattern=".+[0-9]+"/><BR> </h:inputSecret> <p><BR> <h:commandButton value="送出" <BR> action="#{user.verify}"/><BR> </h:form><BR> </f:view><BR> </body><BR> </html><BR> <BR></PRE> <P></P>主要的差別是Q我們用了自己的驗證器標籤Q?BR><PRE> <BR> <co:passwordValidator pattern=".+[0-9]+"/><BR> <BR></PRE> <P></P>如果要自a轉換器標籤Q方法也是類|您要作的是繼承javax.faces.webapp.ConverterTagQ並重新定義?createConverter()Ҏ?BR></DIV> <div class="llwlemn" id=printfoot><BR> <div id="wtqfnvs" class=from>Retrieved from http://caterpillar.onlyfun.net/PmWiki/pmwiki.php/JavaServerFaces/CustomConverterValidatorTag</DIV> <div id="crcnygs" class=lastmod>頁面最後更新於 2005 q?03 ?09 日,12:28 上午</DIV></DIV><img src ="http://m.tkk7.com/raozhh/aggbug/33890.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/raozhh/" target="_blank">饶志?/a> 2006-03-06 17:21 <a href="http://m.tkk7.com/raozhh/articles/33890.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用JSFlginputFileUpload客房端文g保存x务器http://m.tkk7.com/raozhh/articles/32280.html饶志?/dc:creator>饶志?/author>Fri, 24 Feb 2006 04:10:00 GMThttp://m.tkk7.com/raozhh/articles/32280.htmlhttp://m.tkk7.com/raozhh/comments/32280.htmlhttp://m.tkk7.com/raozhh/articles/32280.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/32280.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/32280.html    UploadedFile upFile;
...

    public String upload() throws IOException {
       // This is using Hibernate to figure out what folder path
should be used to store the file.
        Sysctl sys = Sysctl.getRecord();

        FacesContext fc = FacesContext.getCurrentInstance();
        fc.getExternalContext().getApplicationMap().put("fileupload_bytes",
upFile.getBytes());
        fc.getExternalContext().getApplicationMap().put("fileupload_type",
upFile.getContentType());
        fc.getExternalContext().getApplicationMap().put("fileupload_name",
upFile.getName());

        String guid = (new VMID()).toString().replaceAll(":", "");
        writeFile(upFile, sys.getUploadfolder().trim() + guid);
 
        return null;
    }

    private void writeFile(UploadedFile uf, String file) throws IOException {
        InputStream is = uf.getInputStream();
        FileOutputStream fos = new FileOutputStream(file);
        int c;
        while ((c = is.read()) != -1) {
            fos.write(c);
        }
    }

    public UploadedFile getUpFile() {
        return upFile;
    }

    public void setUpFile(UploadedFile x) {
        upFile = x;
    }
}

-------jsp---------
  <x:inputFileUpload id="fileupload"
                     accept="image/*"
                     value="#{MainCtl.upFile}"
                     storage="file"
                     styleClass="input"
                     required="false"/>
<h:commandButton value="load it up" action="#{MainCtl.upload}"
styleClass="button"/>



]]>
利用JSF、SpringFramework和Hibernate构徏Web应用的实例讲q?/title><link>http://m.tkk7.com/raozhh/articles/25743.html</link><dc:creator>饶志?/dc:creator><author>饶志?/author><pubDate>Wed, 28 Dec 2005 08:42:00 GMT</pubDate><guid>http://m.tkk7.com/raozhh/articles/25743.html</guid><wfw:comment>http://m.tkk7.com/raozhh/comments/25743.html</wfw:comment><comments>http://m.tkk7.com/raozhh/articles/25743.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/raozhh/comments/commentRss/25743.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/raozhh/services/trackbacks/25743.html</trackback:ping><description><![CDATA[<CENTER> <H4>利用JSF、SpringFramework和Hibernate构徏Web应用的实例讲q?/H4></CENTER><BR>(来源Qhttp://blog.csdn.net/ylong/archive/2004/07/24/50810.aspx) <BR><BR><FONT face="verdana, arial, helvetica" size=2>[原作者]</FONT><FONT face="verdana, arial, helvetica" size=2><STRONG> Derek Yang Shen<BR></STRONG>[原文链接] <A >http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html</A><BR>[源码链接] <A >http://www.javaworld.com/javaworld/jw-07-2004/jsf/jw-0719-jsf.zip</A><BR>[译] 本h<BR>[点评] 该文是我看的W一讲qJSF与Spring整合的文章,是一个很好的范例Q比较适合于对Spring有了一定了解h学习。其中大量篇q讲q的JSFQ对JSF感兴的也可以来看看?BR>[声明] 该文是本人第一ơ翻译大块头的文章,׃本h才疏学浅、英语较烂,但考虑到和我一样不喜欢看洋文的大有人在Q遂用近4时的时间翻译该文,对一些技术名词和不会译的地方用原文代替Q其中难免有很多错误Q欢q批评指正?BR><BR>[译文]<BR><BR>JSF是一U新的用于构架j2ee应用用户界面的技术,它尤光合于基于MVC架构的应用中。虽已有很多文章介绍q了JSFQ然而它们大多从理论高度来介lJSF而不是面向于实际应用。目前对于实际应用,JSF仍有很多问题没有解决Q例如:如何使JSF适应于MVC整体构架中?如何JSF与其他Java 框架整合hQ是否应该将业务逻辑攄在JSF的backing beans中?如何处理JSF中的安全机制Q更为重要的是如何利用JSF构架现实世界的Web应用Q?BR><BR>本文涉及到上面的这些问题,它将演示如何JSF、Spring和Hibernate整合在一P构架Z个名为JCatalog?/FONT><FONT face="verdana, arial, helvetica" size=2>在线产品Lpȝ</FONT><FONT face="verdana, arial, helvetica" size=2>。利用该DemoQ本文涵盖了Web应用开发的每一个阶D,包括需求收集、分析,技术选择Q系l架构和实现。本文讨Z在JCatalog中涉及到的各U技术的优点和缺点ƈ展示了一些关键部分的设计Ҏ?BR><BR>本文的对象是从事ZJ2ee的Web应用架构人员和开发h员,它ƈ不是对JSF、SpringFramework和Hibernate的简单介l,如果对这些领域不甚了解,请参看相兌源?BR><BR><FONT size=5><B>该范例的功能需?/B></FONT><BR>JCatalog是一个现实世界的Web应用Q我首先描述JCatalog的需求,在通篇的技术决{和架构设计旉涉及到本部分?BR><BR>在设计Web应用的第一阶段是收集系l的功能需求,范例应用是一个典型的电子商务应用pȝQ用户可以浏览品的catalogq查看品的详细情况Q而管理员可以理产品的catalog。通过增加一些其他功能,如inventory理和订单处理等Q该应用可成Z个成熟的电子商务pȝ?BR><BR><B><FONT size=3>Use cases</FONT></B><BR>Use-case分析被用来展C例应用的功能需求,?是该应用的use-case图?BR>     <P align=center><A ><IMG style="WIDTH: 324px; HEIGHT: 196px" height=127 alt="" hspace=0 src="http://www.huihoo.com/java/jsf/jw-0719-jsf1.gif" width=228 align=baseline border=0></A></P><BR>use-case囄于表C系l中的actors以及可能q行的operationsQ在该应用中有七个use-caseQ用戯够浏览?catalog和查看品的详细情况Q一旦用L录到pȝ中,她将成ؓ理员,从而可以创建新的品,~辑已存在的产品或者删除老的产品{?BR><BR><B><FONT size=3>Business rules</FONT></B><BR>JCatalog必须W合以下business rules:</FONT><FONT face="宋体, MS Song"> </FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>每个产品必须h唯一的ID</FONT> <LI><FONT size=2>每个产品必须属于臛_一个category</FONT><FONT face="verdana, arial, helvetica" size=2> <BR></FONT> <LI><FONT face="verdana, arial, helvetica" size=2>产品ID一旦创立不得修?/FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2><B><FONT size=3>Assumptions</FONT></B><BR>我们在系l的设计和实C做以下假定:<BR></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>p讲是~省语言Q且不需事先国际?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>在Catalog不讲不会过500个?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>catalog不会被频繁的修?/FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2><B><FONT size=3>Page flow</FONT></B><BR>?昄了所有的JCatalog的pages以及它们之间的transitions关系Q?BR>     <P align=center><A ><IMG style="WIDTH: 250px; HEIGHT: 159px" height=102 alt="" hspace=0 src="http://www.huihoo.com/java/jsf/jw-0719-jsf2.gif" width=176 align=baseline border=0></A></P><BR>该应用中存在两组pagesQ公开的internet和用于管理的intranetQ其中intranet只能被那些成功登录到pȝ的用戯问?ProductSummary不作Z个单独的page展示l用P它显C在Catalog page中的frame中。ProductList只对理员可视,它包含用于创建、编辑和删除产品的链接?BR><BR>?是一个Catalog面的示意图Q理想状况下Q在需求文档中应该包含每一늚详细C意图?BR>         <P align=center><A ><IMG style="WIDTH: 222px; HEIGHT: 160px" height=114 alt="" hspace=0 src="http://www.huihoo.com/java/jsf/jw-0719-jsf3.gif" width=222 align=baseline border=0></A></P><BR><FONT size=5><B>构架设计</B></FONT><BR>Web应用开发的下一个阶D|构架设计Q它包括应用划分ؓ多个功能lgq将q些lg分割l合成层Q高层的构架设计应该中立于所选用的特定技术?BR><BR><B><FONT size=3>多层架构</FONT></B><BR>多层架构是将整个pȝ清晰的分为多个功能单元:client、presentation、business-logic、integration?EISQ这确保职责得到清晰的划分Q得系l更易于l护和扩展。具有三层或{多层的pȝ被证明比C/S模型h更好的׾~性和灉|性?BR><BR>client层是使用和表C数据模型的地方Q对于一个Web应用Qclient层通常是浏览器Q基于浏览器的瘦客户端不包含M表示逻辑Q它依赖?/FONT><FONT face="verdana, arial, helvetica" size=2>presentation</FONT><FONT face="verdana, arial, helvetica" size=2>层?BR><BR>presentation层将business-logic层的服务展示l用P它应知道如何处理用户的请求,如何同business-logic层交互,q且知道如何选择下一个视图显C给用户?BR><BR>business-logic层包含应用的business objects和business services。它接受来在于presentation层的h、基于请求处理业务逻辑。业务逻辑层组件将受益于系l的服务,如安全管理、事务管理和资源理{?BR><BR>integration层是介于</FONT><FONT face="verdana, arial, helvetica" size=2>business-logic</FONT><FONT face="verdana, arial, helvetica" size=2>层和EIS层之间的桥梁Q它装了与EIS层交互的逻辑。有Ӟintegration层和business-logic层合UCؓ中间层?BR><BR>应用的数据被保存在EIS层中Q它包括关系数据库、面向对象数据库和以及遗留系l等?BR><BR><B><FONT size=3>JCatalog的构架设?/FONT></B><BR>?昄了JCatalog的构架设计以及如何应用于多层构架pȝ中?BR>  <A > <P align=center><IMG style="WIDTH: 326px; HEIGHT: 218px" height=120 alt="" hspace=0 src="http://www.huihoo.com/java/jsf/jw-0719-jsf4.gif" width=196 align=baseline border=0></A></P><BR>该应用采用了多层非分布式的构Ӟ?展示了系l的分层以及每一层中选择的技术,它同时又是该范例的部|图Q它的presentation?business-logic和integration层将存在于同一个web容器中。定义良好的接口孤立每一层的职责Q这一架构使得应用更ؓ单和更好的׾~性?BR><BR>对于presentation层,l验表明Q最好的Ҏ是选择已存在的q已得到证明了的Web应用框架Q而不是自己去设计和开发新的框架。我们拥有多个可选择的框Ӟ如StrutsQWebWork和JSF{,在JCatalog中,我们选择采用JSF?BR><BR>EJB和POJO都可以用来创Z务逻辑层,如果应用是分布式的,采用hremote接口的EJB是一个好的选择Q由于JCatalog是一个典型的不需要远E访问的Web应用Q因此选用POJOQƈ充分利用Spring Framework的帮助,是实现业务逻辑层的更好选择?BR><BR>integration层利用关pd数据库事先数据的持箋化,存在多种Ҏ可用来实玎ͼ<BR></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>JDBCQ这是最为灵zȝҎQ然而,低的JDBC难以使用Q而且质量差的JDBC代码很难q{良好</FONT> <LI><FONT face="verdana, arial, helvetica" size=2>Entity beansQCMP的Entity bean是一U分L据访问代码和处理ORM的昂늚ҎQ它是以应用服务器ؓ中心的方法,即entity bean不是应用与某种数据库类型而是EJB容器U束在一赗?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>O/R mapping frameworkQ一个ORM框架采用以对象ؓ中心的方法实现数据持l化Q一个以对象Z心的应用易于开发ƈh高度的可UL性。在该领域中存在几个框架可用—JDO、Hibernate、TopLink以及CocoBase{。在我们的范例中选用Hibernate?/FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2>现在Q我们将讨论每一层中的设计问题,׃JSF是一个相对较新的技术,因此着重于它的使用Q?BR><BR></FONT><FONT size=3><B><FONT face="verdana, arial, helvetica">presentation</FONT></B></FONT><FONT face="verdana, arial, helvetica" size=2><FONT size=3><B>层和JSF</B></FONT><BR>表示层的功能是收集用L输入、展C数据、控刉面导航ƈ用L输入传递给业务逻辑层,表示层同旉要验证用L输入以及l护应用的session状态。在下面几部分中Q我讨C层设计时的考虑和模式,q说明选择JSF作ؓJCatalog表示层的原因?BR><BR><B>MVC</B><BR>MVC是Java-Blueprints推荐的架构设计模式,MVC几个方面分d来,从而减代码的重复Q它以控制ؓ中心q得应用更h展性。MVC同时可帮助具有不同技能的用户更关注于自己的技能,通过定义良好的接口进行相互合作。MVC是表C层的架构设计模式?BR><BR><B>JSF</B><BR>JSF是Web应用的服务器端用L件框Ӟ它包含以下APIQ表CUIlg、管理它们的状态、处理事件、服务器端验证、数据{换、定义页面导航、支持国际化Qƈ些特性提供扩展能力。它同时包括两个JSP的tag库以在JSP面中表CUIlgQ以及将lgwire为服务器端对象?BR><BR><B>JSF和MVC</B><BR>JSF非常适合于基于MVC的表C层架构Q它在行为和表示之间提供了清晰的分离Q它使得你可以采用熟悉的UIlg和web层概念而无需受限于某U特D的脚本技术或标记语言?BR><BR>JSF backing beans是JSF的Model层,此外Q它同样包含actionsQaction是controller层的扩展Q用于将用户的请求委z业务逻辑层。这里请注意Q从整体的应用构架看Q业务逻辑层也被称为model层。包含JSF标签的JSP面是表C层QFaces Servlet提供了controller的功能?BR><BR><B>Z么选用JSFQ?/B></FONT><FONT face="verdana, arial, helvetica" size=2><BR>JSF不仅仅是另外一个Web框架Q下面这些特性是JSF区别于其他Web框架之所在:</FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>cSwing的面向对象的Web应用开发:服务器端有状态的UIlg模型Q配合event listeners和handlersQ促q了面向对象的Web应用开发?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>backing-bean理Q?backing bean是与面中用的UIlg相关联的javabeanlgQbacking-bean理UIlg对象的定义同执行应用相关处理和拥有数据的对象分离开来。JSF在合适的范围内保存和理q些backing-bean实例?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>可扩展的UI模型QJSF的UI模型是可配置的、可重用的,用以构徏JSF应用的用L面。你可以通过扩展标准的UIlg来开发出更ؓ复杂的组Ӟ例如菜单条、树lg{?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>灉|的rendering模型Qrenderer分离了UIlg的功能和昄Q多个renderers可创建和用来为同一客户端或不同的客L定义不同的显C?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>可扩展的转换和验证模型:Z标准的converter和validatorQ你可以开发出自己的可提供更好的模型保护的converter和validator?/FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2>管如此QJSF目前未成熟Q随同JSF发布?components、converters和validators都是最基础的,而且per-component验证模型不能处理components 和validators间的many-to-many验证。此外,JSF标签不能与JSTL间无~的整合在一赗?BR><BR>在下面的章节中,我将讨论几个在JCatalog实现中的关键部分和设计决{。我首先解释managed bean的定义和使用以及JSF中的backing beanQ然后,我将说明如何处理安全、分ccaching、file upload、验证以及错误信息定制?BR><BR><B>Managed bean,backing bean,view object 和domain object model</B><BR>JSF中引入了两个新的名词Qmanaged bean和backing bean。JSF提供了一个强大的managed-bean工具Q由JSF来管理的JavaBean对象UCؓmanaged-beanQ一?managed bean表述了一个bean如何被创建和理Q它不包含该bean的Q何功能性描q?BR><BR>backing bean定义了与面中用的UIlg相关联的属性和处理逻辑。每一个backing-bean属性邦定于一个组件实例或某实例的value。一?backing-bean同时定义了一l执行组件功能的ҎQ例如验证组件的数据、处理组件触发的事g、实施与lg相关的导航等?BR><BR>一个典型的JSF应用其中的每个面和一个backing-beanl合hQ然而在现实应用中,强制的执行这Uone-on-one的关pM是一U理想的解决ҎQ它可能会导致代码重复等问题。在现实的应用中Q多个页面可以共享一个backing-beanQ例如在JCatalog中, CreateProduct和EditProduct共享同一个ProductBean定义?BR><BR>model对象特定于表C层中的一个view对象Q它包含必须昄在view层的数据以及验证用户输入、处理事件和与业务逻辑层交互的处理逻辑{。在Z JSF的应用中backing bean是view对象Q在本文中backing bean和view对象是可互换的名词?BR><BR>Ҏ于struts中的ActionForm和ActionQ利用JSF中的backing-beanq行开发将能更好的遵@面向对象ҎQ一?backing-bean不仅包含view数据Q而且q包含与q些数据相关的行为,而在struts中,Action和ActionForm分别包含数据和逻辑?BR><BR>我们都应该听说过domain object modelQ那么,domain object model和view对象之间有什么区别呢Q在一个简单的Web应用中,一个domain object model能够横穿所有层中,而在复杂的应用中Q需要用C个单独的view对象模型。domain object model应该属于业务逻辑层,它包含业务数据和与特定业务对象相关的业务逻辑Q一个view对象包含presentation-specific的数据和逻辑。将view对象从domain object model中分d来的~点是在q两个对象模型之间必出现数据映。在JCatalog中,ProductBeanBuilder?UserBeanBuilder利用reflection-based Commons BeanUtils来实现数据映?BR><BR><B>安全</B><BR>目前QJSF没有内徏的安全特性,而对于范例应用来说安全需求是非常基础的:用户d到administration intranet中仅需用户名和密码认证Q而无需考虑授权?BR>针对于JSF的认证,已有几种Ҏ提出Q?BR></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>利用一个backing beanQ这一个方法非常简单,然而它却将backing bean与特D的l承关系l合h?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>利用JSF的ViewHandler decoratorQ这一Ҏ中,安全逻辑紧密C一特定Web层技术联pd了一?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>利用servlet filterQ一个JSF应用与其他的Web应用没有什么两Pfilter仍是处理认证查的最好地方,q种Ҏ中,认证逻辑与Web应用分离开?/FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2>在我们的范例E序中,SecurityFilterc被用来处理用户的认证,目前Q受保护的资源只包含三个面Q出于简单的考虑Q将它们的位|被编码到FiltercM?BR><BR><B>分页</B><BR>该应用中的Catalog面需要分,表示层可用来处理分页Q即它取出所有的数据q保存在q一层;分页同样可在business-logic层?integration层、甚至EIS层中实现。由于在JCatalog中假设不过500个品,因此所有的产品信息能存攑֜一个user session中,我们分逻辑攑֜了ProductListBean中,与分늛关的参数通过JSF managed-bean工具配置?BR><BR><B>Caching</B><BR>Caching是提高Web应用性能的最重要技术之一Q在应用构徏中的很多层中都可以实现caching。JSF managed-bean工具可以使在表示层实现caching非常Ҏ。通过改变一个managed bean的范_q个managed bean中包含的数据可以在不同的范围内缓存?BR><BR>范例应用中采用了两cachingQ第一Ucaching存在于业务逻辑层,CachedCatalogServiceImplcȝ护了一个所有品和目录的读写cacheQSpring该cMZ个singleton service bean来管理,所以,一Ucache是一个应用范围的dcache?BR><BR>Z化分逻辑q进而提高应用的速度Q品同样在session范围内缓存到表示层,每一个用L护着他自qProductListBeanQ这一Ҏ的缺Ҏ内存的消耗和数据的失效问题,在一个用户session中,如果理员更改了catalogQ用户可到的是失效的数据,然而,׃我们假设应用的数据不会经常的改变Q所以这些缺点将能够忍受?BR><BR><B>File upload</B><BR>目前的JSF Sun参考实C不支持file upload。Struts虽已h非常不错的file upload能力Q然而要想用这一Ҏ需要Struts-Faces整合库。在JCatalog中,一个图像与一个品相兌Q在一个用户创Z新的产品后,她必d相应的图片上传,囄保存在应用服务器的文gpȝ里,产品的ID是囑փ名称?BR><BR>范例应用中采?INPUT type=file>、Servlet和Jakarta Common的file-upload API来实现简单的文g上传功能Q该Ҏ包含两个参数Q图像\径和囑փ上传l果面。它们将通过ApplicationBean来配|,详细内容请参?FileUploadServletcR?BR><BR><B>Validation</B><BR>JSF中发布的标准validator是非常基的,无法满现实的需要,但很Ҏ开发出自己的JSF validatorQ在范例中,我开发了SelectedItemsRange validatorQ它用来验证UISelectManylg中选择的数量:<BR><BR>  <?xml:namespace prefix = h /><h:selectManyListbox id=selectedCategoryIds value="#{productBean.selectedCategoryIds}"><BR>     <?xml:namespace prefix = catalog /><catalog:validateSelectedItemsRange minNum="1"></catalog:validateSelectedItemsRange><BR>     <?xml:namespace prefix = f /><f:selectItems id=categories value="#{applicationBean.categorySelectItems}"></f:selectItems><BR>  </h:selectManyListbox><BR><BR>详细情况请参看范例?BR><BR><B>定制错误信息</B><BR>在JSF中,你可以ؓconverters和validators创徏resource bundle和定刉误信息,一个resource bundle可在faces-config.xml中创建:<BR><BR>  <MESSAGE-BUNDLE>catalog.view.bundle.Messages</MESSAGE-BUNDLE><BR><BR>q将错误信息的key-value对加到Message.properties文g中:<BR><BR>  javax.faces.component.UIInput.CONVERSION=Input data is not in the correct type.<BR>  javax.faces.component.UIInput.REQUIRED=Required value is missing.<BR><BR><B><FONT size=3>业务逻辑层和Spring Framework</FONT></B><BR>业务对象和业务服务存在于业务逻辑层中Q一个业务对象不仅包含数据,而且包含相应的逻辑Q在范例应用中包含三个业务对象:Product、Category和User?BR><BR>业务服务与业务对象交互ƈ提供更高U的业务逻辑Q需要首先定义一个正式的业务接口Q它是直接与l端用户交互的服务接口。在JCatalog中,通过?Spring Framework帮助下的POJO实现业务逻辑层,其中共有两个业务服务QCatalogService包含Catalog理相关的业务逻辑Q?UserService中包含User理逻辑?BR><BR>Spring是基于IoC概念的框Ӟ在范例应用中用到的SpringҎ包括:<BR></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>Bean management with application contextsQSpring可以有效地组l我们的中间层对象,它能够消除singleton的proliferationQƈ易于实现良好的面向对象编E方法,即“编E到接口”?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>Declarative Transaction management: Spring利用AOP实现事务理Q而无需借助于EJB容器Q利用这U方法,事务理可以用于MPOJO中。Spring的事务管理不局限于JTAQ而是可以采用不同的事务策略,在范例应用中Q我们将使用declarative transaction management with Hibernate transaction?/FONT> <LI><FONT face="verdana, arial, helvetica" size=2>Data-access exception hierarchyQSpring提供了非常好的异常来代替SQLExceptionQؓ利用Spring的异常,必须在Spring的配|文件中定义以下异常转换Q?/FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2>        <BEAN class="" id=jdbcExceptionTranslator><BR>          <property name="dataSource"><BR>              <REF bean="dataSource"><BR>          </property><BR>        </BEAN><BR><BR>        在范例应用中Q如果一个具有重复ID的新产品被插入,会抛出DataIntegrityViolationExceptionQ这一异常被 <BR>        catchqrethrown一个DuplicateProductIdException。这P该异常就可以与其它的异常区别处理?BR></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>Hibernate integrationQSpring与Hibernateq样的ORM框架整合的非常好QSpring提供了对Hibernate session的高效和安全的处理,它可通过application context配置Hibernate的SessionFactories和JDBC数据源,q得应用易于测试?/FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2><BR><B><FONT size=3>Integration层和Hibernate</FONT></B><BR>Hibernate是一个开源的ORM框架Q它可以支持所有主SQL数据库系l,Hibernate的查询语a为对象和关系架v了非常好的桥梁。Hibernate提供了强大的功能以实玎ͼ数据d和更新、事务管理、数据连接池、查询和实体关系理{?BR><BR><B><FONT size=3>Data Access Ojbect(DAO)</FONT></B><BR>JCatalog中采用了Dao模式Q该模式抽象和封装了所有对数据源的讉KQ该应用中包括两个DAO接口QCatalogDao和UserDaoQ它们相应的实现HibernateCatalogDaoImpl和HibernateUserDAoImpl包含了Hibernate特定的逻辑来实现数据的理和持久化?BR><BR><B><FONT size=5>实现</FONT></B><BR>现在我们来看看如何将上面讨论的这些东西包装在一起以实现JCatalogQ你可以从这个地址下蝲源码Q?A >source code</A><BR><BR><B><FONT size=3>数据库设?/FONT></B><BR>我们范例应用创徏了包?个表的数据库Q如?所C:<BR> <P align=center><A ><IMG style="WIDTH: 290px; HEIGHT: 211px" height=150 alt="" hspace=0 src="http://www.huihoo.com/java/jsf/jw-0719-jsf5.gif" width=248 align=baseline border=0></A></P><BR><B><FONT size=3>c设?/FONT></B><BR>?昄了JCatalog的类?BR> <P align=center><A ><IMG style="WIDTH: 414px; HEIGHT: 255px" height=232 alt="" hspace=0 src="http://www.huihoo.com/java/jsf/jw-0719-jsf6.gif" width=120 align=baseline border=0></A></P><BR>“编E到接口”的思想贯穿了整个设计实CQ在表示层,q到四个backing beanQProductBean、ProductListBean、UserBean和MessageBean;业务逻辑层包含两个业务服?(CatalogService和UserService)和三个业务对?Product、Category和User);Integration层有两个Dao接口和它们相应的Hibernate实现QSpring的application context用来理l大多数的业务逻辑层和integration层的对象QServiceLocatorJSF和业务逻辑层整合在了一赗?BR><BR><B><FONT size=3>Wire everything up</FONT></B><BR>׃幅所限,我们仅D例说明,范例中use case CreateProduct展示了如何装配和构徏应用Q在详细讲述l节前,我们利用sequence??)来说明所有层的end-tp-end整合?BR> <P align=center><A ><IMG style="WIDTH: 470px; HEIGHT: 128px" height=128 alt="" hspace=0 src="http://www.huihoo.com/java/jsf/jw-0719-jsf7.gif" width=120 align=baseline border=0></A></P><BR><BR><B>表示?/B>Q?BR>表示层实现包括创建JSP面、定义页D、创建和配置backing bean以及JSF与业务逻辑层整合?BR></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>JSP pageQcreateProduct.jsp是用来创建新产品的页面,它包含UIlgq将lg打包成ProductBeanQValidateItemsRange标签用来验证用户选择的种cL量,Ҏ一个品至要有一个种c被选中?/FONT></LI></UL> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>面DQ应用中的导航被定义在应用的配置文gfaces-navigation.xml中,CreateProduct的导航准则如下:</FONT></LI></UL> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><NAVIGATION-RULE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <FROM-VIEW-ID>*</FROM-VIEW-ID></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <FROM-OUTCOME>createProduct</FROM-OUTCOME></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <TO-VIEW-ID>/createProduct.jsp</TO-VIEW-ID></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2></NAVIGATION-RULE></FONT><BR></BLOCKQUOTE> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><NAVIGATION-RULE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <FROM-VIEW-ID>/createProduct.jsp</FROM-VIEW-ID></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <FROM-OUTCOME>success</FROM-OUTCOME></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <TO-VIEW-ID>/uploadImage.jsp</TO-VIEW-ID></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <FROM-OUTCOME>retry</FROM-OUTCOME></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <TO-VIEW-ID>/createProduct.jsp</TO-VIEW-ID></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <FROM-OUTCOME>cancel</FROM-OUTCOME></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <TO-VIEW-ID>/productList.jsp</TO-VIEW-ID></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </NAVIGATION-CASE></FONT><BR><FONT face="verdana, arial, helvetica" size=2></NAVIGATION-RULE></FONT><BR></BLOCKQUOTE> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>Backing beanQProductBean不仅包含有将数据映射到页面上的UIlg的属性,q包括三个actionQcreateAction、editAction和deleteActionQ下面是createActionҎ的代码:</FONT></LI></UL> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2>public String createAction() {</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   try {</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      Product product = ProductBeanBuilder.createProduct(this);</FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2>      //Save the product.</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      this.serviceLocator.getCatalogService().saveProduct(product);</FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2>      //Store the current product id inside the session bean.</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      //For the use of image uploader.</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      FacesUtils.getSessionBean().setCurrentProductId(this.id);</FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2>      //Remove the productList inside the cache.</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      this.logger.debug("remove ProductListBean from cache");</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      FacesUtils.resetManagedBean(BeanNames.PRODUCT_LIST_BEAN);</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   } catch (DuplicateProductIdException de) {</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      String msg = "Product id already exists";</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      this.logger.info(msg);</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      FacesUtils.addErrorMessage(msg);</FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2>      return NavigationResults.RETRY;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   } catch (Exception e) {</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      String msg = "Could not save product";</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      this.logger.error(msg, e);</FONT><BR><FONT face="verdana, arial, helvetica" size=2>      FacesUtils.addErrorMessage(msg + ": Internal Error");</FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2>      return NavigationResults.FAILURE;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   }</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   String msg = "Product with id of " + this.id + " was created successfully.";</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   this.logger.debug(msg);</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   FacesUtils.addInfoMessage(msg);</FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2>   return NavigationResults.SUCCESS;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>}</FONT><BR></BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>Managed-bean声明QProductBean必须在JSF配置文gfaces-managed-bean.xml中配|:</FONT></LI></UL> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><MANAGED-BEAN></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <DESCRIPTION></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      Backing bean that contains product information.</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </DESCRIPTION></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <MANAGED-BEAN-NAME>productBean</MANAGED-BEAN-NAME></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <MANAGED-BEAN-CLASS>catalog.view.bean.ProductBean</MANAGED-BEAN-CLASS></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <MANAGED-BEAN-SCOPE>request</MANAGED-BEAN-SCOPE>    </FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <MANAGED-PROPERTY></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <PROPERTY-NAME>id</PROPERTY-NAME></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <VALUE>#{param.productId}</VALUE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </MANAGED-PROPERTY></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <MANAGED-PROPERTY></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <PROPERTY-NAME>serviceLocator</PROPERTY-NAME></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <VALUE>#{serviceLocatorBean}</VALUE></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </MANAGED-PROPERTY></FONT><BR><FONT face="verdana, arial, helvetica" size=2></MANAGED-BEAN></FONT><BR></BLOCKQUOTE> <UL> <LI><FONT face="verdana, arial, helvetica" size=2> 表示层和业务逻辑层之间的整合Q?ServiceLocator抽象了查找服务的逻辑Q在范例应用中,ServiceLocator被定义ؓ一个接口,该接口实Cؓ一个JSF?managed beanQ即ServiceLocatorBeanQ它在Spring的application context中寻找服务:</FONT></LI></UL><FONT face="verdana, arial, helvetica" size=2></FONT> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2>ServletContext context = FacesUtils.getServletContext();</FONT><BR><FONT face="verdana, arial, helvetica" size=2>this.appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(context);</FONT><BR><FONT face="verdana, arial, helvetica" size=2>this.catalogService = (CatalogService)this.lookupService(CATALOG_SERVICE_BEAN_NAME);</FONT><BR><FONT face="verdana, arial, helvetica" size=2>this.userService = (UserService)this.lookupService(USER_SERVICE_BEAN_NAME);</FONT><BR></BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><B>业务逻辑?/B><BR></FONT> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>业务对象Q由于采用Hibernate提供持久化,因此Product和Category两个业务对象需要ؓ它们的所有field提供getter和setter?/FONT></LI></UL> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>业务服务QCatalogService接口中定义了所有的与Catalog management相关的服务:</FONT></LI></UL> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2>public interface CatalogService {</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   public Product saveProduct(Product product) throws CatalogException;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   public void updateProduct(Product product) throws CatalogException;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   public void deleteProduct(Product product) throws CatalogException;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   public Product getProduct(String productId) throws CatalogException;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   public Category getCategory(String categoryId) throws CatalogException;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   public List getAllProducts() throws CatalogException;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>   public List getAllCategories() throws CatalogException;</FONT><BR><FONT face="verdana, arial, helvetica" size=2>}</FONT><BR></BLOCKQUOTE> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>Spring ConfigurationQ这里是CatalogService的Spring配置Q?/FONT></LI></UL> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><!-- Hibernate Transaction Manager Definition --></FONT><BR><FONT face="verdana, arial, helvetica" size=2><BEAN class=org id=transactionManager></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <property name="sessionFactory"><REF local="sessionFactory"></property></FONT><BR><FONT face="verdana, arial, helvetica" size=2></BEAN></FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2><!-- Cached Catalog Service Definition --></FONT><BR><FONT face="verdana, arial, helvetica" size=2><BEAN class=catalog id=catalogServiceTarget init-method="init"></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <property name="catalogDao"><REF local="catalogDao"></property></FONT><BR><FONT face="verdana, arial, helvetica" size=2></BEAN></FONT><BR><BR><FONT face="verdana, arial, helvetica" size=2><!-- Transactional proxy for the Catalog Service --></FONT><BR><FONT face="verdana, arial, helvetica" size=2><BEAN class=org id=catalogService></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <property name="transactionManager"><REF local="transactionManager"></property></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <property name="target"><REF local="catalogServiceTarget"></property></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   <property name="transactionAttributes"></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      <PROPS></FONT><BR><FONT face="verdana, arial, helvetica" size=2>         <PROP key="get*">PROPAGATION_REQUIRED,readOnly</PROP></FONT><BR><FONT face="verdana, arial, helvetica" size=2>       <PROP key="save*">PROPAGATION_REQUIRED</PROP></FONT><BR><FONT face="verdana, arial, helvetica" size=2>       <PROP key="update*">PROPAGATION_REQUIRED</PROP></FONT><BR><FONT face="verdana, arial, helvetica" size=2>       <PROP key="delete*">PROPAGATION_REQUIRED</PROP></FONT><BR><FONT face="verdana, arial, helvetica" size=2>      </PROPS></FONT><BR><FONT face="verdana, arial, helvetica" size=2>   </property></FONT><BR><FONT face="verdana, arial, helvetica" size=2></BEAN></FONT><BR></BLOCKQUOTE> <UL> <LI><FONT face="verdana, arial, helvetica" size=2>Spring和Hibernate的整合:下面是HibernateSessionFactory的配|:</FONT></LI></UL> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><!-- Hibernate SessionFactory Definition --></FONT><BR><CODE> <P><!-- Hibernate SessionFactory Definition --><BR><bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"><BR>   <property name="mappingResources"><BR>      <list><BR>         <value>catalog/model/businessobject/Product.hbm.xml</value><BR>         <value>catalog/model/businessobject/Category.hbm.xml</value><BR>         <value>catalog/model/businessobject/User.hbm.xml</value><BR>      </list><BR>   </property><BR>   <property name="hibernateProperties"><BR>      <props><BR>         <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop><BR>       <prop key="hibernate.show_sql">true</prop><BR>       <prop key="hibernate.cglib.use_reflection_optimizer">true</prop><BR>       <prop key="hibernate.cache.provider_class">net.sf.hibernate.cache.HashtableCacheProvider</prop><BR>      </props><BR>   </property> <BR>   <property name="dataSource"><BR>      <ref bean="dataSource"/><BR>   </property><BR></bean><BR></CODE> <P><CODE>CatalogDao</CODE> uses <CODE>HibernateTemplate</CODE> to integrate between Hibernate and Spring. Here's the configuration for <CODE>HibernateTemplate</CODE>: <P><CODE> <P><!-- Hibernate Template Defintion --><BR><bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate"> <BR>   <property name="sessionFactory"><ref bean="sessionFactory"/></property> <BR>   <property name="jdbcExceptionTranslator"><ref bean="jdbcExceptionTranslator"/></property> <BR></bean> <BR></CODE> <P></FONT><BR><BR></P></BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><B>Integration?/B><BR>Hibernate通过xml配置文g来映业务对象和关系数据库,在JCatalog中,Product.hbm.xml表示了Product对象的映,Category.hbm.xml则用来表CCategory的映,Product.hbm.xml如下Q?BR></FONT> <BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><CODE> <P><?xml version="1.0"?><BR><!DOCTYPE hibernate-mapping PUBLIC <BR>      "-//Hibernate/Hibernate Mapping DTD 2.0//EN"<BR>      "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"><BR><hibernate-mapping package="catalog.model.businessobject"><BR>   <class name="Product" table="product"><BR>      <id name="id" column="ID" unsaved-value="null"><BR>         <generator class="assigned"/><BR>      </id><BR>      <property name="name" column="NAME" unique="true" not-null="true"/><BR>      <property name="price" column="PRICE"/>     <BR>      <property name="width" column="WIDTH"/>      <BR>      <property name="height" column="height"/>      <BR>      <property name="description" column="description"/>   <BR>      <set name="categoryIds" table="product_category" cascade="all"><BR>         <key column="PRODUCT_ID"/><BR>         <element column="CATEGORY_ID" type="string"/><BR>      </set><BR>   </class><BR></hibernate-mapping><BR></CODE> <P><CODE>CatalogDao</CODE> is wired with <CODE>HibernateTemplate</CODE> by Spring: <P><CODE> <P><!-- Catalog DAO Definition: Hibernate implementation --><BR><bean id="catalogDao" class="catalog.model.dao.hibernate.CatalogDaoHibernateImpl"><BR>   <property name="hibernateTemplate"><ref bean="hibernateTemplate"/></property> <BR></bean> <BR></CODE> <P></P></BLOCKQUOTE><FONT face="verdana, arial, helvetica" size=2><B><FONT size=5>l论</FONT></B><BR>本文主要讲述了如何将JSF与Spring、Hibernate整合在一h构徏实际的Web应用Q这三种技术的l合提供了一个强大的Web应用开发框架。在Web应用的高层设计中应该采用多层构架体系QJSF非常适合MVC设计模式以实现表C层QSpring可用在业务逻辑层中理业务对象Qƈ提供事物理和资源管理等QSpring与Hibernatel合的非常出ԌHibernate是强大的O/R映射框架Q它可以在integration层中提供最好的服务?BR><BR>通过整个Web应用分割成多层,q借助于“编E到接口”,应用E序的每一层所采用的技术都是可替换的,例如Struts可以用来替换JSFQJDO可替换Hibernate。各层之间的整合不是不值得研究Q采用IoC和ServiceLocator设计模式可得整合非常容易。JSF提供了其它Web框架Ơ缺的功能,然而,qƈ不意味着你马上抛弃Struts而开始用JSFQ是否采用JSF取决于项目目前的状况和功能需求,以及开发团队的意见{?BR><BR></FONT></FONT><img src ="http://m.tkk7.com/raozhh/aggbug/25743.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/raozhh/" target="_blank">饶志?/a> 2005-12-28 16:42 <a href="http://m.tkk7.com/raozhh/articles/25743.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Log4j 搭徏一个日志服务器http://m.tkk7.com/raozhh/articles/25185.html饶志?/dc:creator>饶志?/author>Fri, 23 Dec 2005 03:14:00 GMThttp://m.tkk7.com/raozhh/articles/25185.htmlhttp://m.tkk7.com/raozhh/comments/25185.htmlhttp://m.tkk7.com/raozhh/articles/25185.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/25185.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/25185.html

使用 Log4j 搭徏一个日志服务器



  最q项目要用到日志服务器,需要把所有服务器的日志统一存入一个日志文件服务器中,于是想CLog4j的SocketAppender?BR>  
  |上一通搜索,l于扑ֈ了相关的只言片语Q内容几乎雷同,和examples\lf5\UsingSocketAppenders中提供的例子没有什么区别!
  
  只好自己研究了!
  
  1.基本使用
  
  1.1服务?/B>
  
  q个日志服务器的服务器端需要运行:
  
  log4j jar包中的org.apache.log4j.net.SocketServer
  
  加参?【本地监听端口】【配|文件】【客L配置文g目录?BR>  
  W三个参数【配|文件目录】其实指的是针对每个客户端的配置文gQ等会详l讲Q现在用?”就可以?
  
  服务器端的配|文件可以用q个Q引自利用Log4j 创徏日志服务?By ??Q:
  
  #文g名socketserver.properties
  #如果需要显C日志界面,可以本行启?BR>  #log4j.rootCategory=, A1
  log4j.rootLogger=DEBUG,A3
  log4j.category.org.apache.log4j.net=INFO
  
  log4j.appender.A1=org.apache.log4j.lf5.LF5Appender
  log4j.appender.A1.MaxNumberOfRecords=700
  
  log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender
  log4j.appender.A4.file=server.log
  log4j.appender.A4.DatePattern='.'yyyyMMdd
  log4j.appender.A4.layout=org.apache.log4j.PatternLayout
  log4j.appender.A4.layout.ConversionPattern=\n\n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
  
  log4j.appender.A3=org.apache.log4j.RollingFileAppender
  log4j.appender.A3.file=server2.log
  log4j.appender.A3.MaxFileSize=1024KB
  log4j.appender.A3.MaxBackupIndex=999
  log4j.appender.A3.layout=org.apache.log4j.PatternLayout
  log4j.appender.A3.layout.ConversionPattern=\n\n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
  
  其中A1是启动Lf5的log监视l端QA3限制大小的文ӞA4是日期滚动文件?BR>  
  单A3QA4是讲所有客L的日志都存放C同一个日志文件中Q我觉的q种Ҏq不好?BR>  
  1.2客户?/B>
  
  客户端的配置文g是这LQ?BR>  log4j.rootCategory=,SOCKET
  log4j.addivity.org.apache=true
  
  #应用于socket
  log4j.appender.SOCKET=org.apache.log4j.net.SocketAppender
  log4j.appender.SOCKET.RemoteHost=localhost  #服务器的IP地址
  log4j.appender.SOCKET.Port=1978       #服务器的监听端口
  log4j.appender.SOCKET.LocationInfo=true   #q个是什么我不知?BR>  log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
  log4j.appender.SOCKET.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%t%m%n
  
  #A2
  log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
  log4j.appender.A2.file=server.log
  log4j.appender.A2.DatePattern='.'yyyy-MM-dd
  log4j.appender.A2.layout=org.apache.log4j.PatternLayout
  log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
  
  启动服务器端,再运行客L可以了!但所有的服务器端/客户端的日志都放C一个日志文件中!
  
  2.E微高点的使用
  
  下面讲如何把各个客户端和服务器端的日志分别放C同的日志文g?
  
  q个我在|上找了好久也没有找?
  
  2.1服务?/B>
  
  服务器的配置文g不用怎么改动Q如果你不需要在同一个文件中存放所有日志,可以把配|文件第一行的A3L?BR>  
  但服务器端有个更大的ȝQ代码有问题Q问题够大了吧,不知道算不算是个bugQ我用的?.2.11版log4jQ?BR>  
  改吧!
  
  打开log4j目录下的src\java\org\apache\log4j\net\SocketServer.java
  
  在这D中改动(看下面代码第12?
  
  LoggerRepository configureHierarchy(InetAddress inetAddress) {
  cat.info("Locating configuration file for "+inetAddress);
  // We assume that the toSting method of InetAddress returns is in
  // the format hostname/d1.d2.d3.d4 e.g. torino/192.168.1.1
  String s = inetAddress.toString();
  int i = s.indexOf("/");
  if(i == -1) {
  cat.warn("Could not parse the inetAddress ["+inetAddress+
  "]. Using default hierarchy.");
  return genericHierarchy();
  } else {
  //q个是什么意?专门?/"W号?明显是错?闭掉
  //  String key = s.substring(0, i);
  //改ؓ
  String key = s.substring(i+1);
  File configFile = new File(dir, key+CONFIG_FILE_EXT);
  if(configFile.exists()) {
  Hierarchy h = new Hierarchy(new RootLogger((Level) Priority.DEBUG));
  hierarchyMap.put(inetAddress, h);
  
  new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h);
  
  return h;
  } else {
  cat.warn("Could not find config file ["+configFile+"].");
  return genericHierarchy();
  }
  }
  }
  
  ~译文g!
  
  打开log4j目录下的src\java\org\apache\log4j\net\SocketNode.java
  
  (改这D|因ؓ我用的时候出?看不出来改不Ҏ什么区?
  
  改第54?BR>  
  ois = new ObjectInputStream(
  new BufferedInputStream(socket.getInputStream()));
  
  ?BR>  
  InputStream is = socket.getInputStream();
  if (is != null) {
  ois = new ObjectInputStream(new BufferedInputStream(is));
  }
  
  文g头加 import java.io.InputStream;
  
  ~译文g!
  
  现在为每个配|客L~配|文?把配|文件放到【客L配置文g目录】中:
  log4j.rootCategory=,A4
  log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender
  log4j.appender.A4.file=127.0.0.1.log  #为每个客L取不同的名字
  log4j.appender.A4.DatePattern='.'yyyyMMdd
  log4j.appender.A4.layout=org.apache.log4j.PatternLayout
  log4j.appender.A4.layout.ConversionPattern=\n\n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
  
  保存文g名ؓ[客户端ip地址].lcf ?92.168.0.126.lcf
  
  2.2 客户?/B>
  
  客户端不用改?太幸q了!!
  
  ok?
  
  启动服务?启动客户?现在服务器的日志攑ֈ了server.log?有配|文件的客户端的日志会放到相应的日志文g?没有配置文g的客L的日志依然放在server.log?
  
  SocketServer.java ?SocketNode.java两个文g可以单独做一个工E?把他们的packageLp?


]]>
log4j参数配置说明http://m.tkk7.com/raozhh/articles/25183.html饶志?/dc:creator>饶志?/author>Fri, 23 Dec 2005 03:10:00 GMThttp://m.tkk7.com/raozhh/articles/25183.htmlhttp://m.tkk7.com/raozhh/comments/25183.htmlhttp://m.tkk7.com/raozhh/articles/25183.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/25183.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/25183.htmllog4j参数配置说明- -

                                      

  Log4j׃个重要的lg构成Q日志信息的优先U,日志信息的输出目的地Q日志信息的输出格式。日志信息的优先U从高到低有ERROR、WARN、INFO、DEBUGQ分别用来指定这条日志信息的重要E度Q日志信息的输出目的地指定了日志打印到控制台还是文件中Q而输出格式则控制了日志信息的昄内容?/P>

  一、定义配|文?/STRONG>

  其实您也可以完全不用配|文Ӟ而是在代码中配置Log4j环境。但是,使用配置文g您的应用E序更加灉|。Log4j支持两种配置文g格式Q一U是XML格式的文Ӟ一U是JavaҎ文Ӟ?|。下面我们介l用JavaҎ文件做为配|文件的ҎQ?/P>

  1.配置根LoggerQ其语法为:

  log4j.rootLogger = [ level ] , appenderName, appenderName, ?

  其中Qlevel 是日志记录的优先U,分ؓOFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的别。Log4j只用四个别,优先U从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的U别Q您可以控制到应用程序中相应U别的日志信息的开兟뀂比如在q里定义了INFOU别Q则应用E序中所有DEBUGU别的日志信息将不被打印出来?appenderName是指B日志信息输出到哪个地斏V您可以同时指定多个输出目的地?

  2.配置日志信息输出目的地AppenderQ其语法为:

  log4j.appender.appenderName = fully.qualified.name.of.appender.class
  log4j.appender.appenderName.option1 = value1
  ?
  log4j.appender.appenderName.option = valueN

  其中QLog4j提供的appender有以下几U:
  org.apache.log4j.ConsoleAppenderQ控制台Q,
  org.apache.log4j.FileAppenderQ文ӞQ?
  org.apache.log4j.DailyRollingFileAppenderQ每天生一个日志文ӞQ?BR>  org.apache.log4j.RollingFileAppenderQ文件大到达指定尺寸的时候生一个新的文ӞQ?
  org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地方)

  3.配置日志信息的格式(布局Q,其语法ؓQ?/P>

  log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
  log4j.appender.appenderName.layout.option1 = value1
  ?
  log4j.appender.appenderName.layout.option = valueN

  其中QLog4j提供的layout有以e几种Q?
  org.apache.log4j.HTMLLayoutQ以HTML表格形式布局Q,
  org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式Q,
  org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串Q,
  org.apache.log4j.TTCCLayoutQ包含日志生的旉、线E、类别等{信息)

  Log4J采用cMC语言中的printf函数的打印格式格式化日志信息Q打印参数如下: %m 输出代码中指定的消息

  %p 输出优先U,即DEBUGQINFOQWARNQERRORQFATAL
  %r 输出自应用启动到输出该log信息耗费的毫U数
  %c 输出所属的cȝQ通常是所在类的全?
  %t 输出产生该日志事件的U程?
  %n 输出一个回车换行符QWindowsq_为“\r\n”,Unixq_为“\n?
  %d 输出日志旉点的日期或时_默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy MMM dd HH:mm:ss,SSS}Q输出类|2002q?0?8?22Q?0Q?8Q?21
  %l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以及在代码中的行数。D例:Testlog4.main(TestLog4.java:10)

  二、在代码中用Log4j

  1.得到记录?/P>

  使用Log4jQ第一步就是获取日志记录器Q这个记录器负责控制日志信息。其语法为:

  public static Logger getLogger( String name)

  通过指定的名字获得记录器Q如果必要的话,则ؓq个名字创徏一个新的记录器。Name一般取本类的名字,比如Q?

  static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )

  2.d配置文g

  当获得了日志记录器之后,W二步将配置Log4j环境Q其语法为:

  BasicConfigurator.configure ()Q?自动快速地使用~省Log4j环境?BR>  PropertyConfigurator.configure ( String configFilename) Q读取用Java的特性文件编写的配置文g?BR>  DOMConfigurator.configure ( String filename ) Q读取XML形式的配|文件?/P>

  3.插入记录信息Q格式化日志信息Q?/P>

  当上两个必要步骤执行完毕Q您可以轻村֜使用不同优先U别的日志记录语句插入到您想记录日志的Q何地方,其语法如下:

  Logger.debug ( Object message ) ;
  Logger.info ( Object message ) ;
  Logger.warn ( Object message ) ;
  Logger.error ( Object message ) ;

- 作者: icefire 2005q?5?8? 星期?17:22



]]>
java调用存储q程 http://m.tkk7.com/raozhh/articles/25167.html饶志?/dc:creator>饶志?/author>Fri, 23 Dec 2005 02:14:00 GMThttp://m.tkk7.com/raozhh/articles/25167.htmlhttp://m.tkk7.com/raozhh/comments/25167.htmlhttp://m.tkk7.com/raozhh/articles/25167.html#Feedback0http://m.tkk7.com/raozhh/comments/commentRss/25167.htmlhttp://m.tkk7.com/raozhh/services/trackbacks/25167.html
java调用存储q程

By zxjygx 发表?2005-10-17 21:40:00

Java 调用存储q程

        本文阐述了怎么使用DBMS存储q程。我阐述了用存储过E的基本的和高Ҏ,比如q回ResultSet。本文假设你对DBMS和JDBC已经非常熟悉Q也假设你能够毫无障地阅读其它语言写成的代码(即不是Java的语aQ,但是Qƈ不要求你有Q何存储过E的~程l历?
存储q程是指保存在数据库q在数据库端执行的程序。你可以使用Ҏ的语法在JavacM调用存储q程。在调用Ӟ存储q程的名U及指定的参数通过JDBCq接发送给DBMSQ执行存储过Eƈ通过q接Q如果有Q返回结果?
使用存储q程拥有和用基于EJB或CORBAq样的应用服务器一L好处。区别是存储q程可以从很多流行的DBMS中免费用,而应用服务器大都非常昂贵。这q不只是许可证费用的问题。用应用服务器所需要花费的理、编写代码的费用Q以及客L序所增加的复杂性,都可以通过DBMS中的存储q程所整个地替代?
你可以用JavaQPythonQPerl或C~写存储q程Q但是通常使用你的DBMS所指定的特定语a。Oracle使用PL/SQLQPostgreSQL使用pl/pgsqlQDB2使用Procedural SQL。这些语a都非常相伹{在它们之间UL存储q程q不比在Sun的EJB规范不同实现版本之间ULSession Bean困难。ƈ且,存储q程是ؓ嵌入SQL所设计Q这使得它们比Java或C{语a更加友好地方式表达数据库的机制?
因ؓ存储q程q行在DBMS自nQ这可以帮助减少应用E序中的{待旉。不是在Java代码中执?个或5个SQL语句Q而只需要在服务器端执行1个存储过E。网l上的数据往q次数的减少可以戏剧性地优化性能?

使用存储q程

单的老的JDBC通过CallableStatementcL持存储过E的调用。该cd际上是PreparedStatement的一个子cR假设我们有一个poets数据库。数据库中有一个设|诗人逝世q龄的存储过E。下面是对老酒鬼Dylan ThomasQold soak Dylan ThomasQ不指定是否有关典故、文化,h评指正。译注)q行调用的详l代码:

try{

     int age = 39; 

    String poetName = "dylan thomas"; 

    CallableStatement proc = connection.prepareCall("{ call set_death_age(?, ?) }"); 

    proc.setString(1, poetName); 

    proc.setInt(2, age); 

    cs.execute();

}catch (SQLException e){ // ....}

传给prepareCallҎ的字串是存储q程调用的书写规范。它指定了存储过E的名称Q?代表了你需要指定的参数?
和JDBC集成是存储过E的一个很大的便利Qؓ了从应用中调用存储过E,不需要存根(stubQ类或者配|文Ӟ除了你的DBMS的JDBC驱动E序外什么也不需要?
当这D代码执行时Q数据库的存储过E就被调用。我们没有去获取l果Q因存储q程q不q回l果。执行成功或p|通过例外得知。失败可能意味着调用存储q程时的p|Q比如提供的一个参数的cd不正)Q或者一个应用程序的p|Q比如抛Z个例外指C在poets数据库中q不存在“Dylan Thomas”)

l合SQL操作与存储过E?

映射Java对象到SQL表中的行相当单,但是通常需要执行几个SQL语句Q可能是一个SELECT查找IDQ然后一个INSERT插入指定ID的数据。在高度规格化(W合更高的范式,译注Q的数据库模式中Q可能需要多个表的更斎ͼ因此需要更多的语句。Java代码会很快地膨胀Q每一个语句的|络开销也迅速增加?
这些SQL语句转移C个存储过E中大大简化代码,仅涉及一ơ网l调用。所有关联的SQL操作都可以在数据库内部发生。ƈ且,存储q程语言Q例如PL/SQLQ允怋用SQL语法Q这比Java代码更加自然。下面是我们早期的存储过E,使用Oracle的PL/SQL语言~写Q?

create procedure set_death_age(poet VARCHAR2, poet_age NUMBER) 

    poet_id NUMBER;

    begin SELECT id INTO poet_id FROM poets WHERE name = poet; 

    INSERT INTO deaths (mort_id, age) VALUES (poet_id, poet_age);

end set_death_age;

很独特?不。我打赌你一定期待看C个poets表上的UPDATE。这也暗CZ使用存储q程实现是多么容易的一件事情。set_death_age几乎可以肯定是一个很烂的实现。我们应该在poets表中d一列来存储逝世q龄。Java代码中ƈ不关心数据库模式是怎么实现的,因ؓ它仅调用存储q程。我们以后可以改变数据库模式以提高性能Q但是我们不必修Ҏ们代码?
下面是调用上面存储过E的Java代码Q?

public static void setDeathAge(Poet dyingBard, int age) throws SQLException{ 

    Connection con = null; 

    CallableStatement proc = null; 

    try {

         con = connectionPool.getConnection(); 

         proc = con.prepareCall("{ call set_death_age(?, ?) }");

         proc.setString(1, dyingBard.getName()); 

          proc.setInt(2, age); 

          proc.execute(); 

   finally { 

         try { proc.close(); } 

         catch (SQLException e) {} 

          con.close(); 

   }

}

Z保可维护性,使用像这儿这LstaticҎ。这也得调用存储过E的代码集中在一个简单的模版代码中。如果你用到许多存储q程Q就会发C需要拷贝、粘贴就可以创徏新的Ҏ。因Z码的模版化,甚至也可以通过脚本自动生调用存储q程的代码?

Functions

存储q程可以有返回|所以CallableStatementcLcMgetResultSetq样的方法来获取q回倹{当存储q程q回一个值时Q你必须使用registerOutParameterҎ告诉JDBC驱动器该值的SQLcd是什么。你也必调整存储过E调用来指示该过E返回一个倹{?
下面接着上面的例子。这ơ我们查询Dylan Thomas逝世时的q龄。这ơ的存储q程使用PostgreSQL的pl/pgsqlQ?

create function snuffed_it_when (VARCHAR) returns integer 'declare 

               poet_id NUMBER; 

               poet_age NUMBER;

begin 

--first get the id associated with the poet. 

             SELECT id INTO poet_id FROM poets WHERE name = $1;

 --get and return the age. 

               SELECT age INTO poet_age FROM deaths WHERE mort_id = poet_id; 

return age;

end;' language 'pl/pgsql';

另外Q注意pl/pgsql参数名通过Unix和DOS脚本?n语法引用。同Ӟ也注意嵌入的注释Q这是和Java代码相比的另一个优性。在Java中写q样的注释当然是可以的,但是看v来很凌ؕQƈ且和SQL语句pQ必d入到Java String中?
下面是调用这个存储过E的Java代码Q?

connection.setAutoCommit(false);

CallableStatement proc = connection.prepareCall("{ ? = call snuffed_it_when(?) }");

proc.registerOutParameter(1, Types.INTEGER);

proc.setString(2, poetName);

cs.execute();

int age = proc.getInt(2);

如果指定了错误的q回值类型会怎样Q那么,当调用存储过E时抛Z个RuntimeExceptionQ正如你在ResultSet操作中用了一个错误的cd所到的一栗?

复杂的返回?

关于存储q程的知识,很多人好像就熟悉我们所讨论的这些。如果这是存储过E的全部功能Q那么存储过E就不是其它q程执行机制的替换方案了。存储过E的功能比这强大得多?
当你执行一个SQL查询ӞDBMS创徏一个叫做cursorQ游标)的数据库对象Q用于在q回l果中P代每一行。ResultSet是当前时间点的游标的一个表C。这是Z么没有缓存或者特定数据库的支持,你只能在ResultSet中向前移动?
某些DBMS允许从存储过E中q回游标的一个引用。JDBCq不支持q个功能Q但是Oracle、PostgreSQL和DB2的JDBC驱动器都支持在ResultSet上打开到游标的指针QpointerQ?
设想列出所有没有活到退休年龄的诗hQ下面是完成q个功能的存储过E,q回一个打开的游标,同样也用PostgreSQL的pl/pgsql语言Q?

create procedure list_early_deaths () return refcursor as 'declare 

    toesup refcursor;

begin 

    open toesup for SELECT poets.name, deaths.age FROM poets, deaths -- all entries in deaths are for poets. -- but the table might become generic. 

    WHERE poets.id = deaths.mort_id AND deaths.age < 60; 

    return toesup;

end;' language 'plpgsql';

下面是调用该存储q程的JavaҎQ将l果输出到PrintWriterQ?
PrintWriter:

static void sendEarlyDeaths(PrintWriter out){ 

    Connection con = null;

    CallableStatement toesUp = null;

    try {

        con = ConnectionPool.getConnection(); 

         // PostgreSQL needs a transaction to do this... con.

        setAutoCommit(false); // Setup the call. 

        CallableStatement toesUp = connection.prepareCall("{ ? = call list_early_deaths () }"); 

         toesUp.registerOutParameter(1, Types.OTHER); 

         toesUp.execute(); 

         ResultSet rs = (ResultSet) toesUp.getObject(1); 

         while (rs.next()) {

                String name = rs.getString(1);

                int age = rs.getInt(2); 

                out.println(name + " was " + age + " years old."); 

          } 

          rs.close(); 

       } 

     catch (SQLException e) { // We should protect these calls. toesUp.close(); con.close();

    }

}

因ؓJDBCq不直接支持从存储过E中q回游标Q我们用Types.OTHER来指C存储过E的q回cdQ然后调用getObject()Ҏq对q回D行强制类型{换?
q个调用存储q程的JavaҎ是mapping的一个好例子。Mapping是对一个集上的操作q行抽象的方法。不是在q个q程上返回一个集Q我们可以把操作传送进L行。本例中Q操作就是把ResultSet打印C个输出流。这是一个值得举例的很常用的例子,下面是调用同一个存储过E的另外一个方法实玎ͼ

public class ProcessPoetDeaths{ 

    public abstract void sendDeath(String name, int age);

}

    static void mapEarlyDeaths(ProcessPoetDeaths mapper){ 

    Connection con = null; 

    CallableStatement toesUp = null; 

    try {

         con = ConnectionPool.getConnection(); 

         con.setAutoCommit(false); 

         CallableStatement toesUp = connection.prepareCall("{ ? = call list_early_deaths () }");

          toesUp.registerOutParameter(1, Types.OTHER); 

          toesUp.execute(); 

          ResultSet rs = (ResultSet) toesUp.getObject(1); 

         while (rs.next()) { 

         String name = rs.getString(1); 

         int age = rs.getInt(2); 

        mapper.sendDeath(name, age); 

rs.close(); 

} catch (SQLException e) { // We should protect these calls. toesUp.close(); 

con.close(); 

}

}

q允许在ResultSet数据上执行Q意的处理Q而不需要改变或者复制获取ResultSet的方法:

static void sendEarlyDeaths(final PrintWriter out){ 

          ProcessPoetDeaths myMapper = new ProcessPoetDeaths() { 

                              public void sendDeath(String name, int age) { 

                                                  out.println(name + " was " + age + " years old."); 

                             } 

         }; 

mapEarlyDeaths(myMapper);

}

q个Ҏ使用ProcessPoetDeaths的一个匿名实例调用mapEarlyDeaths。该实例拥有sendDeathҎ的一个实玎ͼ和我们上面的例子一L方式把结果写入到输出。当Ӟq个技巧ƈ不是存储q程Ҏ的,但是和存储过E中q回的ResultSetl合使用Q是一个非常强大的工具?

l论

存储q程可以帮助你在代码中分逻辑Q这基本上L有益的。这个分ȝ好处有:
&#8226; 快速创建应用,使用和应用一h变和改善的数据库模式?nbsp;
&#8226; 数据库模式可以在以后改变而不影响Java对象Q当我们完成应用后,可以重新设计更好的模式?
&#8226; 存储q程通过更好的SQL嵌入使得复杂的SQL更容易理解?
&#8226; ~写存储q程比在Java中编写嵌入的SQL拥有更好的工PQ大部分~辑器都提供语法高亮Q?
&#8226; 存储q程可以在Q何SQL命o行中试Q这使得调试更加Ҏ?

q不是所有的数据库都支持存储q程Q但是存在许多很的实现Q包括免?开源的和非免费的,所以移植ƈ不是一个问题。Oracle、PostgreSQL和DB2都有cM的存储过E语aQƈ且有在线的社区很好地支持?
存储q程工具很多Q有像TOAD或TORAq样的编辑器、调试器和IDEQ提供了~写、维护PL/SQL或pl/pgsql的强大的环境?
存储q程实增加了你的代码的开销Q但是它们和大多数的应用服务器相比,开销得多。如果你的代码复杂到需要用DBMSQ我整个采用存储q程的方式?/P>



]]>
վ֩ģ壺 ˾޾ƷӰwww| һƵվ| ŷպëƬ߿վ| þù׾ƷѲ| ƷѾƷ߹ۿ| ˵Ƶ߹ۿ| պһƷ߲ƵһƷ| ˳վ18ֹһ| ޾Ʒmv߹ۿ| ޵һ߹ۿ| ޹ŷһ| һëƬ| 99ѹƷ| ҹʱ| ?V?V˵| һӰȷɫԴ| һavĻ| һþAþѾƷ| 91Ƶѹۿ| ƷٸAVѾþϴ| ޳aƬ777777| ޹ƷۺϾþþ| ޹AVվ| ÿ߹ۿapp| ҹƷţӰ| ͵޾Ʒ| ˵߹ۿ | aƬ߹ۿ| hƵѹۿ| ޹ƷƵ| Ƶ| þۺպ޾Ʒɫ| ޳AVƬWWW| þóaëƬѹۿվ| պѹۿһëƬ| ޹һӰ| ˾Ʒձ| ձĻ| ҹ޹˲| ҹav뾫Ʒ| Ļ|