??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区二区三区高清不卡,国产亚洲色婷婷久久99精品91,亚洲成熟xxxxx电影http://www.tkk7.com/xiaosao/category/11006.html不懂我的?, M了我 , 该了解了解我 !而懂我的?, 更离不了?, 因ؓ他们爱我 ?/description>zh-cnFri, 25 Feb 2011 13:14:21 GMTFri, 25 Feb 2011 13:14:21 GMT60<?gt;Oracle内存׃n?/title><link>http://www.tkk7.com/xiaosao/articles/344895.html</link><dc:creator>cAng^Er</dc:creator><author>cAng^Er</author><pubDate>Wed, 23 Feb 2011 02:49:00 GMT</pubDate><guid>http://www.tkk7.com/xiaosao/articles/344895.html</guid><wfw:comment>http://www.tkk7.com/xiaosao/comments/344895.html</wfw:comment><comments>http://www.tkk7.com/xiaosao/articles/344895.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/xiaosao/comments/commentRss/344895.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/xiaosao/services/trackbacks/344895.html</trackback:ping><description><![CDATA[<p>原文:http://bbs.dameng.com/viewthread.php?tid=2202&extra=page%3D1<br /> </p> PGA是一个服务器q程的专用的U有内存区,而SGA则是׃n内存区?br /> <br /> SGA由多个部分组成:<br /> 1Q?固定SGAQFixed SGAQ?br /> 2Q?块缓冲区QDb cacheQ?br /> 3Q?重做日志~冲区(Redo log bufferQ?br /> 4Q?Java池(<span id="7nbpzh7" class="t_tag" onclick="tagshow(event)" href="tag.php?name=Java">Java</span> poolQ?br /> 5Q?大池QLarge poolQ?br /> 6Q?׃n池(Shared poolQ?br /> 7Q?池QStream poolQ?br /> <br /> 有如下参数控制共享池相关lg大小Q?br /> 1Q?JAVA_POOL_SIZEQ控制Java池大?br /> 2Q?SHARED_POOL_SIZEQ?i中控制共享池中占用最大的部分Q?0g以上控制׃n池大?br /> 3Q?LARGE_POOL_SIZEQ控制大池大?br /> 4Q?DB_*K_CACHE_SIZEQ控制不同块大小的缓冲区大小?br /> 5Q?LOG_BUFFERQ控刉做日志缓冲区大小?br /> 6Q?SGA_TARGETQ?0g以上控制自动SGA内存理的d存大?br /> 7Q?SGA_MAX_SIZEQ控制SGA可以辑ֈ的最大大,改变需重启<span id="7tvxln3" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%CA%FD%BE%DD%BF%E2">数据?/span>?br /> <br /> 下面详l介l各个部分的作用和推荐设|?br /> <br /> SGA各组件作?br /> 1Q?SGAQ?br /> <br /> 2Q?块缓冲区Q?br />     查询ӞOracle会先把从盘d的数据放入内存,以后再查询相x据时不用再次d盘。insert和updateӞOracle SGA会现在该Z~存数据Q之后批量写到硬盘中。通过块缓冲区Q?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=Oracle">Oracle</span>可以通过内存~存提高盘的I/O?br />     块缓冲区中有三个区域Q?br /> 默认池(Default poolQ:所有数据默认都在这里缓存?br /> 保持池(Keep poolQ:用来~存需要多ơ重用的数据?br /> 回收池(Recycle poolQ:用来~存很少重用的数据?br /> <br />     原来只有一个默认池Q所有数据都在这里缓存。这样会产生一个问题:大量很少重用的数据会把需重用的数据缓冲区Q造成盘I/O增加Q运行速度下降。后来分Z保持池和回收池根据是<br /> <br /> 否经帔R用来分别~存数据?br />     q三部分内存区需要手动确定大,q且之间没有׃n。例如:保持池中已经满了Q而回收池中还有大量空闲内存,q时回收池的内存不会分配l保持池?br />     9i开始,q可以设|db_nk_cache?i之前数据库只能用相同的块大?i开始同一个数据库可以使用多种块大(2KB,4KB,8KB,16KB,32KBQ,q些块需要在各自的db_nk_cache中缓存。如果ؓ?br /> <br /> 同的表空间指定了不同的块大小Q需要ؓ其设|各自的~冲区?br /> <br /> 3Q?重做日志~冲区(Redo log bufferQ:<br />     数据写到重做日志文g之前在这里缓存,在以下情况中触发Q?br /> 每隔3U?br /> ~存辑ֈ1MB?/3满时<br /> 用户提交?br /> ~冲区的数据写入盘?br /> <br /> 4Q?Java池(Java poolQ:<br />     在数据库中运行Java代码时用到这部分内存。例如:~写Java存储q程在服务器内运行。需要注意的是,该内存与常见的Java~写的B/Spȝq没关系。用JAVA语言代替PL/SQL语言在数据库中写存储<br /> <br /> q程才会用到q部分内存?br /> <br /> 5Q?大池QLarge poolQ:<br />     下面三种情况使用到大池:<br /> q行执行Q存放进E间的消息缓冲区<br /> RMANQ某些情况下用于盘I/O~冲?br /> ׃n服务器模式:׃n服务器模式下UGA在大池中分配Q如果设|了大池Q?br /> <br /> 6Q?׃n池(Shared poolQ?br />     ׃n池是SGA中最重要的内存段之一。共享池太大和太都会严重媄响服务器?br /> SQL和PL/SQL的解释计划、代码,数据字典数据{等都在q里~存?br /> SQL和PL/SQL代码在执行前会进?#8220;解析”来获得执行计划及权限验证{相兌助操作?#8220;解析”很费旉。对于响应时间很短的查询Q?#8220;解析”可以占到全部旉?/3。对于响应时间较长的l计{操<br /> <br /> 作,“解析”所占用的时间比例会下降很多。执行计划及所需的数据字典数据都~存在共享池中,让后l相同的查询可以减少很多旉?br />     不?#8220;l定变量”DQ?br />     pȝ需要花费大量的资源去解析查询?br />     ׃n池中的代码从不重用,pȝp很大代h理q部分内存?br />     关于׃n变量的优~点讨论已经过了这文章的范畴Q简单来Ԍ响应旉短的查询要用共享变量,响应旉长的l计不用共享变量?br />     需要注意的是,SHARED_POOL_SIZE参数?i中控制共享池中占用最大的部分Q?0g以上控制׃n池d?br /> <br /> 7Q?池QStream poolQ?br />     9iR2以上增加?#8220;?#8221;技术,10g以上在SGA中增加了池。流是用来共享和复制数据的工兗? <img src ="http://www.tkk7.com/xiaosao/aggbug/344895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/xiaosao/" target="_blank">cAng^Er</a> 2011-02-23 10:49 <a href="http://www.tkk7.com/xiaosao/articles/344895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title><?gt;oracle性能优化-׃n池调?/title><link>http://www.tkk7.com/xiaosao/articles/344893.html</link><dc:creator>cAng^Er</dc:creator><author>cAng^Er</author><pubDate>Wed, 23 Feb 2011 02:33:00 GMT</pubDate><guid>http://www.tkk7.com/xiaosao/articles/344893.html</guid><wfw:comment>http://www.tkk7.com/xiaosao/comments/344893.html</wfw:comment><comments>http://www.tkk7.com/xiaosao/articles/344893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/xiaosao/comments/commentRss/344893.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/xiaosao/services/trackbacks/344893.html</trackback:ping><description><![CDATA[<a >原文:http://space.itpub.net/79499/viewspace-341794</a><br /> <br /> <span style="font-size: 9pt">一</span><span style="font-size: 9pt">.</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">:</span><span style="font-size: 9pt"><a onclick="javascript:tagshow(event, '%CA%FD%BE%DD%BF%E2');" href="javascript:;" target="_self"><u><strong>数据?/strong></u></a>调整中最为重要的一部分是重写运行效率差?/span><span style="font-size: 9pt"><a onclick="javascript:tagshow(event, 'SQL');" href="javascript:;" target="_self"><u><strong>SQL</strong></u></a></span><span style="font-size: 9pt">代码</span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">重写之后?/span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">代码在运行效率方面可能会与之前的产生极大的差别!</span><span style="font-size: 9pt"><br />       </span><span style="font-size: 9pt">但是当遇到重写之后性能q是未能H破瓉或者你是用?/span><span style="font-size: 9pt">(</span><span style="font-size: 9pt">无法讉K</span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">代码</span><span style="font-size: 9pt">)</span><span style="font-size: 9pt">的时?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">可以通过调整</span><span style="font-size: 9pt"><a onclick="javascript:tagshow(event, 'ORACLE');" href="javascript:;" target="_self"><u><strong>ORACLE</strong></u></a></span><span style="font-size: 9pt">的共享内存结?/span><span style="font-size: 9pt">SGA(System Global Area),</span><span style="font-size: 9pt">最大限度地提高性能Q?/span><span style="font-size: 9pt"><br />        SGA</span><span style="font-size: 9pt">中比较重要的lg是</span><span style="font-size: 9pt">Shared Pool(</span><span style="font-size: 9pt">׃n?/span><span style="font-size: 9pt">),</span><span style="font-size: 9pt">它的作用是高速缓?/span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">语句</span><span style="font-size: 9pt">!</span><span style="font-size: 9pt">׃n池由一个最q最?/span><span style="font-size: 9pt">(LRU,Least Recently Used)</span><span style="font-size: 9pt">法?a onclick="javascript:tagshow(event, '%B9%DC%C0%ED');" href="javascript:;" target="_self"><u><strong>理</strong></u></a></span><span style="font-size: 9pt">!<br />       </span><span style="font-size: 9pt">׃n池的好处</span><span style="font-size: 9pt">:<br /> 1.<span style="color: rgb(51,102,255)">select cust_id,cust_name from col_cust<br /> </span>2.</span><span style="font-size: 9pt">上列语句的算法被转换?/span><span style="font-size: 9pt">ASCII</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">然后通过一个散列算法生一个单独的散列?/span><span style="font-size: 9pt">~~</span><span style="font-size: 9pt">接着</span><span style="font-size: 9pt">Process</span><span style="font-size: 9pt">会查看该散列值在</span><span style="font-size: 9pt">Shared Pool</span><span style="font-size: 9pt">中是否存?/span><span style="font-size: 9pt">,<br /> </span><span style="font-size: 9pt">如果存在</span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">执行高速缓存中语句</span><span style="font-size: 9pt"><br /> 3.</span><span style="font-size: 9pt">如果不存?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">必d该语句进行语法分?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">q些分析步骤会生额外的pȝ开销</span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">该操作是高代L</span><span style="font-size: 9pt">!<br /> 4.</span><span style="font-size: 9pt">查找到匹配的</span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">叫做一ơ高速缓冲区命中</span><span style="font-size: 9pt">(Cache Hit)<br /> 5.</span><span style="font-size: 9pt">反之叫做高速缓冲区脱靶</span><span style="font-size: 9pt">(Cache Miss)<br /> 6.</span><span style="font-size: 9pt">注意是区分大写?/span><span style="font-size: 9pt"><br />  <span style="color: rgb(51,102,255)">SELECT CUST_ID,CUST_NAME FROM COL_CUST</span> <br />  <br />       </span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">.</span><span style="font-size: 9pt">׃n池有三个lgl成</span><span style="font-size: 9pt">,Library Cache(</span><span style="font-size: 9pt">库高速缓存区</span><span style="font-size: 9pt">),Data Dictionary Cache(</span><span style="font-size: 9pt">数据目录高速缓存区</span><span style="font-size: 9pt">),User Global Area(</span><span style="font-size: 9pt">用户全局?/span><span style="font-size: 9pt">)<br />       1.Library Cache(</span><span style="font-size: 9pt">库高速缓存区</span><span style="font-size: 9pt">)</span><span style="font-size: 9pt">是用来缓?/span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">语句的场所</span><span style="font-size: 9pt">.</span><span style="font-size: 9pt">可以通过下面q句话对动态视图进行查?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">Library Cache</span><span style="font-size: 9pt">的内?/span><span style="font-size: 9pt"><br />  <span style="color: rgb(51,102,255)">select p.username,l.sql_text,<br />  lpad(' ' ,4*(LEVEL-2)) || operation || ' ' || options || ' ' || object_name as "Execution Plan"<br />  from (<br />  select s.username,p.address,p.hash_value,p.operation,p.options,p.object_name,p.id,p.parent_id<br />  from v$sql_plan p,v$session s<br />  where (p.address=s.sql_address and p.hash_value=s.sql_hash_value) and s.username='citictest'<br />  ) p,v$sql l<br />  where(l.address=p.address and l.hash_value=p.hash_value)<br />  start with id=0<br />  connect by prior id = parent_id<br /> </span>      2.Data Dictionary Cache(</span><span style="font-size: 9pt">数据目录高速缓存区</span><span style="font-size: 9pt">):</span><span style="font-size: 9pt">数据目录是用来检?/span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">语句所引用的那些表是否已经存在</span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">列名和数据类型是否也正确</span><span style="font-size: 9pt">! Library Cache</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">Data Dictionary Cache</span><span style="font-size: 9pt">使用互相独立?/span><span style="font-size: 9pt">LRU</span><span style="font-size: 9pt">机制</span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">好处是后l用户发布的语句与先前用h发布的语句类g不一?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">虽然?/span><span style="font-size: 9pt">Library Cache</span><span style="font-size: 9pt">中无法找到匹配的</span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">但是在数据目录中会存?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">也会有性能上的提高?/span> <div><span style="font-size: 9pt"><br />       </span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">.(1)</span><span style="font-size: 9pt">量</span><span style="font-size: 9pt">Library Cache(</span><span style="font-size: 9pt">库高速缓存区</span><span style="font-size: 9pt">)</span><span style="font-size: 9pt">的性能</span><span style="font-size: 9pt"><br />       <span style="color: rgb(51,102,255)">select namespace,gethitratio,pinhitratio,reloads,invalidations<br />        from v$librarycache<br />        where namespace in ('SQL_AREA','TABLE/PROCEDURE','BODY','TRIGGER');<br /> </span></span><span style="font-size: 9pt">主要?/span><span style="font-size: 9pt">gethitratio,pinhitratio>90%</span><span style="font-size: 9pt">说明调整充分</span></div> <div><span style="font-size: 9pt">      <span style="color: rgb(51,102,255)">select sum(reloads)/sum(pins) "RELOAD</span></span><span style="font-size: 9pt; color: rgb(51,102,255)"> </span><span style="font-size: 9pt; color: rgb(51,102,255)">RATIO"<br />        from v$librarycache<br /> </span><span style="font-size: 9pt">?/span><span style="font-size: 9pt"><1%</span><span style="font-size: 9pt">意味着不是l常重新语法分析以前被装载到</span><span style="font-size: 9pt">Library Cache</span><span style="font-size: 9pt">的语?/span><span style="font-size: 9pt"><br />  <br />        (2)</span><span style="font-size: 9pt">量</span><span style="font-size: 9pt">Data Dictionary Cache(</span><span style="font-size: 9pt">数据目录高速缓存区</span><span style="font-size: 9pt">)</span><span style="font-size: 9pt">的性能</span><span style="font-size: 9pt"><br />       <span style="color: rgb(51,102,255)">select 1 - (sum(getmisses)/sum(gets)) "DATA DICTIONARY HIT RATIO"<br />        from v$rowcache;<br /> </span></span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">>85%</span><span style="font-size: 9pt">时说明调整充?/span></div> <div><span style="font-size: 9pt">   </span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">.</span><span style="font-size: 9pt">通过改进</span><span style="font-size: 9pt">Library Cache</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">Data Dictionary Cache</span><span style="font-size: 9pt">来提?/span><span style="font-size: 9pt">shared pool</span><span style="font-size: 9pt">性能</span><span style="font-size: 9pt"><br /> (1).</span><span style="font-size: 9pt">得到当前</span><span style="font-size: 9pt">shared pool</span><span style="font-size: 9pt">的大?/span><span style="font-size: 9pt"><br />  <span style="color: rgb(51,102,255)">select pool,sum(bytes) "SIZE" from v$sgastat where pool='shared pool' group by pool;<br /> </span>(2).</span><span style="font-size: 9pt">得到推荐?/span><span style="font-size: 9pt">shared pool</span><span style="font-size: 9pt">大小</span><span style="font-size: 9pt"><br />   <span style="color: rgb(51,102,255)">set echo off<br />   set feedback off<br />   set serveroutput on<br />   declare<br />   v_total_plsql_mem number := 0;<br />   v_total_sql_mem   number := 0;<br />   v_total_sharable_mem number := 0;<br />   begin<br />        select sum(sharable_mem) into v_total_plsql_mem from v$db_object_cache;<br />       <br />        select sum(sharable_mem) into v_total_sql_mem from v$sqlarea where executions > 10;<br />       <br />        v_total_sharable_mem := v_total_plsql_mem + v_total_sql_mem;<br />       <br />        Dbms_Output.put_line('Estimated required shared pool size is:' || to_char(v_total_sharable_mem,'fm9,999,999,999,999') || ' bytes');<br />   end;<br />   /<br /> </span>(3).</span><span style="font-size: 9pt">动态加?/span><span style="font-size: 9pt">shared pool</span><span style="font-size: 9pt">大小</span><span style="font-size: 9pt"><br /> <span style="color: rgb(51,102,255)">alert system set shared_pool_size = 200M;<br /> </span>*</span><span style="font-size: 9pt">大小不能过</span><span style="font-size: 9pt">SGA_MAX_SIZE</span><span style="font-size: 9pt">的?/span><span style="font-size: 9pt"><br /> (4).</span><span style="font-size: 9pt">初始</span><span style="font-size: 9pt">SGA</span><span style="font-size: 9pt">大小的计?/span><span style="font-size: 9pt"><br /> (TSGA)SGA</span><span style="font-size: 9pt">ȝ大小</span><span style="font-size: 9pt">=</span><span style="font-size: 9pt">服务器物理内?/span><span style="font-size: 9pt">*0.55   (1G</span><span style="font-size: 9pt">以上物理内存的话可以相应</span><span style="font-size: 9pt">60%-75%)<br /> (TSGAI)</span><span style="font-size: 9pt">每个实例的?/span><span style="font-size: 9pt">SGA</span><span style="font-size: 9pt">大小</span><span style="font-size: 9pt">=TSGA/oracle</span><span style="font-size: 9pt">上实例的个数</span><span style="font-size: 9pt"><br /> shared pool</span><span style="font-size: 9pt">的d?/span><span style="font-size: 9pt">=TSGAI*0.45<br /> (5).</span><span style="font-size: 9pt">上述四点是其实完成的是同一个做法,是?/span><span style="font-size: 9pt">Shared Pool</span><span style="font-size: 9pt">更大</span><span style="font-size: 9pt"><br /> (6).</span><span style="font-size: 9pt">可以?/span><span style="font-size: 9pt">PL/SQL</span><span style="font-size: 9pt">E序包装?/span><span style="font-size: 9pt">Shared Pool Reserved Area(</span><span style="font-size: 9pt">׃n池保留区</span><span style="font-size: 9pt">)<br /> Shared_Pool_Reserved_Size</span><span style="font-size: 9pt">用来讄q一区域的大,默认?/span><span style="font-size: 9pt">5%</span><span style="font-size: 9pt">Q这是不够的</span><span style="font-size: 9pt"><br /> <span style="color: rgb(51,102,255)">select owner,name,sharable_mem from v$db_object_cache<br /> where type in('PACKAGE','PACKAGE BODY') order by sharable_mem desc;<br /> </span></span><span style="font-size: 9pt">上述q句语句可以查看当前~存Z?/span><span style="font-size: 9pt">PL/SQL</span><span style="font-size: 9pt">E序包的名称和大,当发现大?/span><span style="font-size: 9pt">> Shared_Pool_Reserved_Size</span><span style="font-size: 9pt">时说明保留区的大不够,你需要增?/span><span style="font-size: 9pt">Shared_Pool_Reserved_Size</span><span style="font-size: 9pt">的?/span><span style="font-size: 9pt"><br /> (7).</span><span style="font-size: 9pt">把重要的</span><span style="font-size: 9pt">PL/SQL</span><span style="font-size: 9pt">代码保持在内存中</span><span style="font-size: 9pt"><br /> </span><span style="font-size: 9pt">你可以把常用?/span><span style="font-size: 9pt">PROCEDURE</span><span style="font-size: 9pt">销?/span><span style="font-size: 9pt">(Pinning)</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">Shared_Pool_Reserved_Size</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt"><br /> </span><span style="font-size: 9pt">做法如下</span><span style="font-size: 9pt">:</span></div> <div><span style="font-size: 9pt">          a)sys</span><span style="font-size: 9pt">用户d</span><span style="font-size: 9pt"><br />           b)</span><span style="font-size: 9pt">q行</span><span style="font-size: 9pt">@%ORACLE_HOME%/rdbms\admin\dbmspool.sql<br />           c)SQL>execute DBMS_SHARED_POOL.KEEP('PROCEDURENAME') (</span><span style="font-size: 9pt">销?/span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">必须?/span><span style="font-size: 9pt">sys</span><span style="font-size: 9pt">完成</span><span style="font-size: 9pt">)<br />           d)</span><span style="font-size: 9pt">扑ֈ销定的对象</span><span style="font-size: 9pt">select owner,name,type from v$db_object_cache where kept='YES';<br />           e)</span><span style="font-size: 9pt">销定对单独?/span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">语句无法操作</span><span style="font-size: 9pt">,</span><span style="font-size: 9pt">可能的把大语句做成</span><span style="font-size: 9pt">PROCEDURE</span><span style="font-size: 9pt">Q可以用一下语句寻扑և比较大的语句</span><span style="font-size: 9pt"><br /> <span style="color: rgb(51,102,255)">select substr(sql_text,1,45),length(sql_text) "STMT_SIZE" from v$sqlarea where command_type=47 order by length(sql_text) desc;<br /> </span>          f)</span><span style="font-size: 9pt">可以~写一个脚本,当实例启动之后运行,把所有需要销定的语句执行一?/span><span style="font-size: 9pt"><br />           h)</span><span style="font-size: 9pt">只有使用</span><span style="font-size: 9pt">UNKEEP</span><span style="font-size: 9pt">或者实例关闭时才会取消销?/span><span style="font-size: 9pt"><br /> (8).</span><span style="font-size: 9pt">其他的一些调?/span><span style="font-size: 9pt">Library Cache</span><span style="font-size: 9pt">参数</span><span style="font-size: 9pt"><br /> a)open_cursors :</span><span style="font-size: 9pt">默认</span><span style="font-size: 9pt">50<br /> b)cursor_space_for_time</span><span style="font-size: 9pt">默认</span><span style="font-size: 9pt">false<br /> c)session_cached_cursors</span><span style="font-size: 9pt">默认</span><span style="font-size: 9pt">0(</span><span style="font-size: 9pt">无游标高速缓?/span><span style="font-size: 9pt">)<br /> d)cursor_sharing</span><span style="font-size: 9pt">默认</span><span style="font-size: 9pt">EXACT --2</span><span style="font-size: 9pt">?/span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">语句必须完全匚w才能׃n</span><span style="font-size: 9pt">shared pool</span><span style="font-size: 9pt">中所~存的已分析代码</span><span style="font-size: 9pt">.<br />                  SIMILAR --</span><span style="font-size: 9pt">允许</span><span style="font-size: 9pt">2</span><span style="font-size: 9pt">条仅在字面上不同?/span><span style="font-size: 9pt">SQL</span><span style="font-size: 9pt">语句׃n</span><span style="font-size: 9pt">shared pool</span><span style="font-size: 9pt">中所~存的已分析代码</span><span style="font-size: 9pt">.<br /> </span><span style="font-size: 9pt">例如</span><span style="font-size: 9pt">:<span style="color: rgb(51,102,255)">select cust_id from col_cust where cust_name = 'wang'<br />      select cust_id from col_cust where cust_name = 'huang'<br /> </span></span><span style="font-size: 9pt">上述两句?/span><span style="font-size: 9pt">SIMILAR</span><span style="font-size: 9pt">模式中是相等Q可以用缓存的已分析代?/span><span style="font-size: 9pt">.</span></div> <img src ="http://www.tkk7.com/xiaosao/aggbug/344893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/xiaosao/" target="_blank">cAng^Er</a> 2011-02-23 10:33 <a href="http://www.tkk7.com/xiaosao/articles/344893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title><?gt;Webwork对checkbox复选框Action的处?/title><link>http://www.tkk7.com/xiaosao/articles/97419.html</link><dc:creator>cAng^Er</dc:creator><author>cAng^Er</author><pubDate>Fri, 02 Feb 2007 01:20:00 GMT</pubDate><guid>http://www.tkk7.com/xiaosao/articles/97419.html</guid><wfw:comment>http://www.tkk7.com/xiaosao/comments/97419.html</wfw:comment><comments>http://www.tkk7.com/xiaosao/articles/97419.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/xiaosao/comments/commentRss/97419.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/xiaosao/services/trackbacks/97419.html</trackback:ping><description><![CDATA[?<a >http://blog.csdn.net/chikai/archive/2004/12/06/206371.aspx</a><br />webwork寚w面诸如像checkboxq种表单元素的处理,我们如果只是单的用来讄字段的布|像下面的处理方式,如:<br /><input type="checkbox" name="user.lockedOut" value="true"/>如果用户选中q复选框Q浏览器在查询串中将会送出"user.lockedOut=true"Q此时OGNL执行了action.getUser().setLockedOut(true)。如果用户不选中复选框Q浏览器不会送出查询Ԍ因此Q在开始,应确保已l初始化lockedOut 为falseQ?br />private boolean m_lockedOut = false;<br />public void setLockedOut(boolean lockedOut) { m_lockedOut = lockedOut; } <p>        但更多情况下Q我们是把它当做复选(多项选择Q来用,q有两种情况用checkbox来设|集合:<br /><strong>一.checkbox name相同</strong><br />在一个String cd的Set 集合里面存放许多权限Q用checkbox的HTML如下Q?br /><input type="checkbox" name="user.priv" value="boss"/><br /><input type="checkbox" name="user.priv" value="admin"/><br /><input type="checkbox" name="user.priv" value="manager"/><br />比方_一个用户选中前面的两,览器将会送出q查询串Q?user.priv=boss&user.priv=admin?br />OGNL会处理查询Ԍaction.getUser().setPriv(String[] {"boss", "admin"})?br />Action里面的方法将会是q样Q?br />Set m_privileges = new HashSet();</p><p>    public void setPriv(String[] privs) {<br />        for (int i = 0; i < privs.length; i++) {<br />            m_privileges.add(privs[i]);<br />        }<br />    }<br /><strong>?checkbox name不同<br /></strong>有三U处理方式:<br /><strong>I.</strong><br /> <input type="checkbox" name="xlist[0].id" value="444"><br /> <input type="checkbox" name="xlist[1].id" value="443"><br /> <input type="checkbox" name="xlist[2].id" value="442"><br /> * Action中用List集合来处理:private List xlist = new XWorkList(User.class)<br />    public List getXlist(){             <br />        return xlist;<br />    }<br /><strong>II.</strong> <br /> <input type="checkbox" name="xmap['0'].id" value="444"><br /> <input type="checkbox" name="xmap['1'].id" value="443"><br /> <input type="checkbox" name="xmap['2'].id" value="442"><br />  * Action中用Map集合来处理:private Map xmap = new XWorkMap(User.class)<br />    public List getXmap(){             <br />        return xmap;<br />    }<br /><strong> III.</strong><br /> <input type="checkbox" name="xarray[0]." value="444"><br /> <input type="checkbox" name="xarray[1]" value="443"><br /> <input type="checkbox" name="xarray[2]" value="442"><br />  *Action中用Object[]数组来处理(注意数组的长度必M先确定,不可以动态改动数l的大小Q:<br />     private Object[] xarray = new Object[3]<br />     public Object[] getXarray(){ <br />                return xarray; <br />        } </p><p>        下面用一个稍为复杂一点的例子来加深对List集合处理方式的理解,其它处理方式都是异曲同工?br /><font color="#ff0000">multiSelect.jsp文g</font><br /><<a href="mailto:%@page">%@page</a> pageEncoding="gb2312" contentType="text/html;charset=gb2312"%><br /><<a href="mailto:%@taglib">%@taglib</a> prefix="ww" uri="webwork" %><br /><html><br />   <body><br />   <form name="multi" method="post" action="multiSelect.action"><br />      <%int i = 0; %><br />      <ww:iterator value="ulist"> <br />      <% <br />        String cName = "xlist["+i+"].id";<br />        i++;<br />       %><br />       <input type="checkbox" name="<%=cName%>" value="<ww:property value="id"/>"><br />       <ww:property value="username"/><br />       <br><br />      </ww:iterator><br />      <input type="hidden" name="actionEvent" value="viewSelect"> <br />      <input type="submit" value="选择"> <br />   </form><br />   </body><br /></html></p><p><font color="#ff0000">multiSelect_result.jsp</font>文g<br /><<a href="mailto:%@page">%@page</a> pageEncoding="gb2312" contentType="text/html;charset=gb2312"%><br /><<a href="mailto:%@taglib">%@taglib</a> prefix="ww" uri="webwork" %><br /><html><br />   <body>你的选择是:<br><br />       <ww:iterator value="xlist"> <br />       <ww:property value="id"/><br />       <br><br />      </ww:iterator><br />   </body><br /></html></p><p><font color="#ff0000">MultiSelectAction.java</font>文g</p><p>package com.wzj.rbac.webwork.action;<br />import java.util.List;<br />import com.opensymphony.xwork.Action;<br />import com.opensymphony.xwork.util.XWorkList;<br />import com.wzj.framework.spring.resource.BeanLocator;<br />import com.wzj.rbac.ServiceFacade.UserService;<br />import com.wzj.rbac.domain.object.User;<br />/**<br /> * @desc 复选框 选择提交Actionc?br /> * @author chikai<br><br /> * @link <a href="<a href="mailto:wzj616@etang.com">chikai</a">mailto:wzj616@etang.com">chikai</a</a>><br /> * @version $ MultiSelectAction.java  2004-12-5 19:11:54 $ <br /> * @version $ Project xwork<br /> */<br />public class MultiSelectAction implements Action {</p><p>    private final static String PRE_SUCCESS = "pre_success";<br />    //用户列表<br />    private List ulist;<br />    //选择的用?br />    private List xlist = new XWorkList(User.class);<br />    private UserService uService;<br />    //面执行动作判断<br />    private String actionEvent;<br />    <br />    public String execute() throws Exception {<br />       if(actionEvent!=null&&actionEvent.equals("viewSelect"))<br />       {   <br />           for(int s=0;s<xlist.size();s++){<br />               if(((User)xlist.get(s)).getId()==null){<br />                   xlist.remove(s);<br />                   s--;<br />                   }<br />           }  <br />           return SUCCESS;<br />       }<br />       //获取用户业务服务<br />       uService = BeanLocator.getGlobalServiceLocator().getUserService();<br />       ulist = uService.getAllUser();<br />       return PRE_SUCCESS;<br />    }<br />    public List getUlist(){<br />        return ulist;<br />    }<br />    public List getXlist(){             <br />        return xlist;<br />    }<br />    public void setActionEvent(String ae){<br />        actionEvent = ae;<br />    }<br />}</p><p><br /><font color="#ff0000">xwork.xml</font>文gQ?/p><p><!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "<a ></p><p><xwork><br /> <br /> <include file="webwork-default.xml" /><br />    <include file="config-browser.xml" /><br />    <package name="pklogin" extends="webwork-default"><br /> <br />    <interceptors><br />        <interceptor-stack name="modelParamsStack"><br />     <interceptor-ref name="model-driven" /><br />        <interceptor-ref name="params" /><br />        </interceptor-stack> <br /> </interceptors>  <br /> <br /> <action name="multiSelect" class="com.wzj.rbac.webwork.action.MultiSelectAction"><br />  <result name="success" type="dispatcher"><br />            <param name="location">/multiSelect_result.jsp</param><br />        </result><br />  <result name="pre_success" type="dispatcher"><br />   <param name="location">/multiSelect.jsp</param><br />  </result><br />  <interceptor-ref name="modelParamsStack" /><br /> </action><br />  <br /> </package></p><p></xwork></p><img src ="http://www.tkk7.com/xiaosao/aggbug/97419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/xiaosao/" target="_blank">cAng^Er</a> 2007-02-02 09:20 <a href="http://www.tkk7.com/xiaosao/articles/97419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title><?gt;log4j/log4e的?http://stieglitzcc.spaces.live.com/Blog/cns!6A816552E3F0D074!122.entryhttp://www.tkk7.com/xiaosao/articles/93899.htmlcAng^ErcAng^ErMon, 15 Jan 2007 03:36:00 GMThttp://www.tkk7.com/xiaosao/articles/93899.htmlhttp://www.tkk7.com/xiaosao/comments/93899.htmlhttp://www.tkk7.com/xiaosao/articles/93899.html#Feedback0http://www.tkk7.com/xiaosao/comments/commentRss/93899.htmlhttp://www.tkk7.com/xiaosao/services/trackbacks/93899.htmllog4j/log4e的?/h4>

单的?span lang="EN-US">log4j是帮助开发h员进行日志输出管理的APIcd。它最重要的特点就

可以 配置文g灉|的设|?/span> 日志信息的优先、日志信息的输出目的C及日志信息的输出格式?span lang="EN-US">

Log4j除了可以记录E序q行日志信息外还有一重要的功能就是用?/span> 昄调试信息。程序员l常会遇到脱?span lang="EN-US">java ide环境调试E序的情况,q时大多Ch会选择使用System.out.println语句输出某个变量值的Ҏq行调试。这样会带来一个非帔R烦的问题Q一旦哪天程序员军_不要昄q些System.out.println的东西了只能一行行的把q些垃圾语句注释掉。若哪天又需调试变量|则只能再一行行Lq些注释恢复System.out.println语句。用log4j可以很好的处理类似情c?/span>

log4j使用Ҏ

下面介绍的是log4j一些理论方面的知识Q读者觉得枯燥的话可以蟩q本节直接阅ȝ三节实例部分?/span>

  1、定义配|文?/span>

   首先使用配置文g我们的应用程序更加灵z配|log日志输出方式包括输出优先U、输出目的地、输出格式。Log4j支持两种配置文g格式Q一U是XML 格式的文Ӟ一U是JavaҎ文件log4j.propertiesQ键=|。下面将介绍使用log4j.properties文g作ؓ配置文g的方法:

   ?/span> 配置根LoggerQ其语法为:0

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

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

   ?/span> 配置日志信息输出目的地AppenderQ其语法为:

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

  其中Q?/font> Log4j提供的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指定的地方)

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

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

  其中Q?/font> Log4j提供的layout有以下几U:
  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?/font> 22Q?0Q?8Q?21
  %l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以及在代码中的行数。D例:Testlog4.main(TestLog4.java:10)

  2、在代码中用Log4j

   ?/span> 得到记录?/span>

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

  public static Logger getLogger( String name)

  通过指定的名字获得记录器Q如果必要的话,则ؓq个名字创徏一个新的记录器?span lang="EN-US">Name一般取本类的名字,比如Q?

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

   ?/span> d配置文g

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

BasicConfigurator.configure ()Q?自动快速地使用~省Log4j环境?br />  PropertyConfigurator.configure ( String configFilename) Q读取用Java的特性文件编写的配置文g?/font>

例:PropertyConfigurator.configure (".\\src\\log4j.properties")
  DOMConfigurator.configure ( String filename ) Q读取XML形式的配|文件?/font>

   ?/span> 插入记录信息Q格式化日志信息Q?/span>

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

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

log4j范例E序

下面用一个最单的范例E序来进一步说?span lang="EN-US">log4j的用方法。程序代码如下:

 

import org.apache.log4j.*;

 

public class LogTest {

 

 

    static Logger logger = Logger.getLogger(LogTest.class.getName());

 

    public static void main(String[] args) {

 

        PropertyConfigurator.configure ( ?\\src\ log4j.properties ? Q?/span>

logger.debug( "Debug ..." );

 

        logger.info( "Info ..." );

 

        logger.warn( "Warn ..." );

 

        logger.error( "Error ..." );

 

    }

}

E序说明Q?span lang="EN-US">

?/span> static Logger logger = Logger.getLogger(LogTest.class.getName()); 是创徏一个属?/span> LogTest Logger 对象Q创建时要告?/span> Logger 你当前的 Class 是什么?/span>

?/font> PropertyConfigurator.configure ( ?/span> log4j.properties ? 是说用当前工E目录下?/span> src 文g夹中?/span> log4j.properties 文g作ؓ配置文g。若?/span> log4j.properties 攑֜工程根目录下也可不写此句Q程序会自动扑ֈ配置文g?/span>

?/font> logger.debug 是输出 debug 的信息, logger.info 是输出提示信息Q?/font> logger.warn 是昄警告信息Q?/font> logger.error 是昄错误信息?/font>

 

下面是配|文?/font> log4j.properties 的内容:

log4j.rootCategory=DEBUG, stdout Q?/span> R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender

log4j.appender.R.File=log.txt

log4j.appender.R.MaxFileSize=100KB

log4j.appender.R.MaxBackupIndex=1

log4j.appender.R.layout=org.apache.log4j.PatternLayout

log4j.appender.R.layout.ConversionPattern=%d { yyyy MMM dd HH:mm:ss } %-5p %c - %m%n

E序说明Q?span lang="EN-US">

?/span> log4j.rootCategory=DEBUG, stdout Q?/span> R

是说我要显C所有优先权{於和高?/font> Debug的信息?br />"stdout"Q?/font> ”R?/font> 表示我定义了两个输出?/font> ( 随便什么名字都?/font> ) ?/font>

?/font> 下面的三行说 stdout 输出端其实是标准输出 Console Q也是屏幕。输出的格式?/font> Pattern Layout 。{换方式是 %5p (%F:%L) - %m%n Q即前五格用来显CZ先权Q再昄当前的文件名Q加当前的行数。最后是 logger.debug() ?/span> logger.info() ?/span> logger.warn() ?/span> logger.error() 里的信息?/span> %n 表示回RI?/span>

?/font> 再加上下面六行则 log 信息不光昄在屏q上Q而且被保存在一个叫 "log.txt" 的文仉Q文件最大ؓ 100KB 。如果文件大超q?/font> 100KB Q文件会被备份成 "log.txt.1" Q新?/font> "log.txt" l箋记录 log 信息?/font>

接下来我们可以改?/font> log4j.properties Q而不需重新~译可以控?/font> log 信息是否昄?/font> log 信息的输出端cd、输出方式、输出格式,{等。D例如下:

?/font> ?/font> log4j.properties 文g里把 "log4j.rootCategory=DEBUG,stdout,R" 改写?/font> "log4j.rootCategory=OFF, stdout,R" Q这h有的 log信息都不会显CZQ解决了本文开始提出的问题?br />?/font> ?/font> log4j.properties 文g里把 "log4j.rootCategory=DEBUG,stdout,R" 改写?/font> "log4j.rootCategory=INFO, stdout,R" Q这样只昄 INFO, WARN, ERROR ?/font> log 信息Q?/font> DEBUG 信息不会被显C;

 

?span lang="EN-US">webE序中用log4j注意问题

1?span style="FONT: 7pt 'Times New Roman'">    ׃jsp或servlet在执行状态时没有当前路径概念Q所有?/span> PropertyConfigurator.configure Q?/span> String Q语句找 log4j.properties 文g时要l出相对于当?/span> jsp ?/span> servlet 的\径{化成Z个绝对的文gpȝ路径。方法是使用 servletcontext.getrealpath(string) 语句。例Q?/span>

//得到当前jsp路径

String prefix =  getServletContext().getRealPath( "/");

//d log4j.properties

PropertyConfigurator.configure(prefix+ "\\WEB-INF\\log4j.properties");

2、相应的log4j.properties讄某个属性时也要在程序中讄l对路径。例Q?/font>

log4j.appender.R.File属性设|日志文件存放位|。我们可以用d.properties配置文g的方法进行灵z设|?span style="COLOR: black">


log4e使用说明

在了解了log4j的功能后Q我们肯定会我们的程序中 ~写一?/span> Log4j 日志记录。对于?/span> Eclipse 的程序员 Log4e 是我们最得力?/span> log4j 日志~写助手Q现在开?/span> Log4e 之旅?/span>

Log4e 是一个免费的 Eclipse Plugin Q它可帮助你在你?/font> Java 工程中快速加?/font> Log Q?/font> 我们可以?/font> http://log4e.jayefem.de/index.php/Download |站上下?/font> Log4e 最新版本。下载后相应文件夹拯?/font> Eclipse 的插件目录下Q重?/font> Eclipse Q在首选项中会多出一?/font> Log4e 选项?/font>

Log4e 可以有多个插?/font> Log Z个方法、类Q当然也可以在当前位|插?/font> Log Q同时其也可以把 Sysout.out.println() 的{换ؓ log Q所有的q一切只需要你点点鼠标或者按一ơ快捷键Q下面我们只以ؓ一个方法插?/font> Log Z来讲?/font>

1.JPG

?/font> Java ~辑上下文中点击右键Q选择 Log4E Q你看到如下界面:

2.JPG点击 Insert Log Statement For This Method Q你看到验证页面:

3.JPG
Finish
后这时你看到插?/font> Log后的函数如下Q?br />4.JPG


cAng^Er 2007-01-15 11:36 发表评论
]]>
使用JSF和MyFaces实现文g上蝲http://www.tkk7.com/xiaosao/articles/87628.htmlcAng^ErcAng^ErThu, 14 Dec 2006 02:02:00 GMThttp://www.tkk7.com/xiaosao/articles/87628.htmlhttp://www.tkk7.com/xiaosao/comments/87628.htmlhttp://www.tkk7.com/xiaosao/articles/87628.html#Feedback0http://www.tkk7.com/xiaosao/comments/commentRss/87628.htmlhttp://www.tkk7.com/xiaosao/services/trackbacks/87628.html 最q要做上传,但是MultiPartRequestWrapper中的很多的方法都是过时的了,在晚上看看到q篇文章挺好的,攑֜q里Q学习一下!
原文q接地址Q?br />
http://www.java3z.com/cwbwebhome/article/article2a/2136.jsp?id=463
Web览器ؓ我们利用Web应用E序发送文件提供了一条简单的途径Q但是当前版本的Java Web标准Qservlets、JSP和JSFQ却无法为我们提供Q何帮助。幸q的是,有一些第三方框架lgQ例如Apache Commons File Upload?Apache MyFaces和Oracle ADF FacesQ实Cq种Ҏ,它们都暴露了单的API和定制的标记QtagQ?br />
   本文的前面一部分介绍文g上蝲操作是如何实现的Q解释了MyFaces和通用文g上蝲Q前者在内部使用了后者)。我们了解这些开放源代码框架lg的内部工作方式是非常重要的,因ؓ只有q样我们才能高效率地使用它们Q才能根据自q需要对它们q行修改。本文的W二部分介l一个简单的应用E序Q它让用户用web览器上载文件?


   ZWeb的文件上?/b>

   我们?上蝲"q个专业术语用得有点q滥了。Web理员在自己的站点上发布文g的时候,它会说自?上蝲"了一个文件。Web开发者在建立HTMLH体和脚本,让普通用户通过web览器发送一个文件的时候,他也会说自己实现了文?上蝲"功能?br />
   q两U含义在某些斚w是重叠的Q因为web理员可能用基于web的界面来发布文gQ页面、图像、脚本等{)。免Ҏ供个人web站点的公司(例如YahooQ,实现Zweb的文件上载功能的目的是ؓ了让Z上蝲自己的页面。它允许M一个拥有web览器和互联|访问能力的个h发布一个小型的web站点。但是,目前有一些更好的、可用于发布web内容的方式,例如FTP或安全FTP。在q种情况下,你可以利用专用的应用E序Q例如FTP客户端)代替web览器把自己的内容上载到web服务器上?br />
   本文从web开发者的角度来讨论文件上载的问题。例如,一个基于web的邮件应用程序(例如Yahoo邮gQ,实C文g上蝲Q因为只有这P用户才能够发送那些带有附件的消息。另一个比较好的例子是扑ַ作的web站点Q它允许用户把自q历发送给招聘人员。本文的CZ应用E序计算上蝲文g的散列倹{你可以在自q应用E序中对上蝲的文件进行Q意的处理Q例如把它们的内容存储在数据库中或把它们作ؓ邮g附g发送。现在,让我们看看如何在web应用E序中实现文件上载吧?br />
   一个HTMLH体中可以包含一个或多个Qinput type="file"Q元素,览器把它们作ؓ输入字段来显C(呈现Q,在这些字D中允许用户输入文g路径。在每个文g输入字段的后面,web览器会d一个按钮,它会打开一个文件对话框Q让用户选择一个文Ӟ代替输入路径Q:


?Q包含文件输入字D늚webH体

   当用Lȝ体的"提交QSubmitQ?按钮的时候,web览器对H体的数据进行编码,其中包括被选中的文件、文件名Q或路径Q和H体的其它一些参数。接着Q浏览器把编码后的数据发送给web服务器,web服务器把q些数据传递给QformQ标记的action属性所指定的脚本来处理。如果你开发一个Java web应用E序Q那么操作脚本可能是一个servletQ小服务E序Q或JSP面?br />
   ׃H体数据默认的编码方式和默认的GETҎ都不适合文g上蝲Q所以包含文件输入字D늚H体必须在<formQ标C指定multipart/form-data~码方式和POSTҎQ?br />

Qform enctype="multipart/form-data" method="POST" action="..."Q?br />...
Qinput type="file" name="..."Q?br />...
Q?formQ?/p>


   但是事情qq么单,因ؓ实现servlet和JSP规范的应用程序服务器不一定能够处理multipart/form-data~码方式。因此,你必d析请求的输入,例如Apache通用文g上蝲是一个小型的JavaE序包,它让你能够从~码的数据中获取被上载文件的内容。这个程序包的API是很灉|的,它允怽把小文g存储在内存中Q把大文件存储在盘的时目录中。你可以指定一个文件大的阀|大于q个值的文g都会被写到磁盘上Q而不会保留在内存中,而且你还可以规定允许的被上蝲文g的最大大?br />
   前面提到的org.apache.commons.fileuploadE序包包含一个叫作DiskFileUpload的类Q它的parseRequest()Ҏ获取HttpServletRequest参数Qƈq回org.apache.commons.fileupload.FileItem实例列表。编码后的窗体数据从servleth的getInputStream()Ҏ所q回的数据流中d。FileItemq个名字Ҏ使h误解Q因个接口的实例同时表现了被上蝲的文件和正常的请求参数?br />
   通用文g上蝲E序包所提供的API赋予了你讉K分解后的H体数据的权利,但是servleth的getParameter()和getParameterValues()Ҏ却无法工作。这是一个难题,因ؓ在输入字Dc检查框、单选框和列表框后台q行的JSFlg需要调用这两个Ҏ。我们可以利用Servlets API提供的两个特性(qo器和h包装器)来解册个问题。下一部分描述了Apache MyFaces如何实现qo器,d了大量必要的Ҏ件上载的支持Q而不会中断已有的JSFlg。此外,MyFaces为JavaBeans提供了APIQ同时还提供了一个定制的JSFlgQ它表现为<input type="file"Q元素?/p>

  配置JSF和MyFaces扩展

   目前QJSF规范的主要实现是JSF参考实玎ͼRIQ,与此同时QApache提供了另外一个实玎ͼ是MyFaces。当然可能存在其它一些JSF实现Q但是JSF RI和MyFaces是其中最行的两个。很多开发者更喜欢前者,因ؓSun把它UCؓ"官方?实现Q但是,MyFaces拥有一些有的扩展Q例如对上蝲文g操作的支持)。如果你愿意Q可以把MyFaces扩展与Sun的JSF RI一起用。你只需要把myfaces-extensions.jar文g、JSF RI的JAR文g和commons-fileupload-1.0.jar文g一h到自qweb应用E序的WEB-INF/lib目录中就可以了。下面是需要的JAR文gQ?br />

JSF 1.1 RI jsf-api.jarjsf-impl.jar
JSTL 1.1 RI jstl.jarstandard.jar
MyFaces扩展 myfaces-extensions.jar
Apache CommonsQ供JSF和MyFaces 扩展使用Q?commons-collections.jarcommons-digester.jarcommons-beanutils.jarcommons-logging.jarcommons-fileupload-1.0.jar


   org.apache.myfaces.component.html.utilE序包中的MultipartRequestWrappercd当MyFaces和通用文g上蝲之间的桥梁。这个类扩展了HttpServletRequestWrapperQ重载了getParameterMap()、getParameterNames()、getParameter()和getParameterValues()ҎQ这样它们才能适应multipart/form-data~码方式。此外,MultipartRequestWrapper提供了两个新的方法,分别是getFileItem()和getFileItems()Q它允许你通过org.apache.commons.fileupload.FileItem接口来访问被上蝲的文件?br />
   当MyFaces到~码方式的时候,org.apache.myfaces.component.html.utilE序包中的ExtensionsFilter徏立MultipartRequestWrapper实例。因此,你不需要关心窗体数据的分解Q但是如果你希望改变被上载文件的处理方式Q那么了解它是如何实现的很有用处了。在典型的应用程序中Q你必须在自qweb应用E序的web.xml描述信息中配|ExtensionsFilterQ这样它才能在JSF的FacesServlet前面截取HTTPhQ?br />

Q?xml version="1.0" encoding="UTF-8"?Q?br />
Q?DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd"Q?br />
Qweb-appQ?br />
Qcontext-paramQ?br />Qparam-nameQjavax.faces.STATE_SAVING_METHODQ?param-nameQ?br />Qparam-valueQclientQ?param-valueQ?br />Q?context-paramQ?br />
QservletQ?br />Qservlet-nameQFacesServletQ?servlet-nameQ?br />Qservlet-classQ?br />javax.faces.webapp.FacesServlet
Q?servlet-classQ?br />Qload-on-startupQ?Q?load-on-startupQ?br />Q?servletQ?br />
Qservlet-mappingQ?br />Qservlet-nameQFacesServletQ?servlet-nameQ?br />Qurl-patternQ?faces/*Q?url-patternQ?br />Q?servlet-mappingQ?br />
Qservlet-mappingQ?br />Qservlet-nameQFacesServletQ?servlet-nameQ?br />Qurl-patternQ?.facesQ?url-patternQ?br />Q?servlet-mappingQ?br />
QfilterQ?br />Qfilter-nameQExtensionsFilterQ?filter-nameQ?br />Qfilter-classQ?br />org.apache.myfaces.component.html.util.ExtensionsFilter
Q?filter-classQ?br />Qinit-paramQ?br />Qparam-nameQuploadMaxFileSizeQ?param-nameQ?br />Qparam-valueQ?0mQ?param-valueQ?br />Q?init-paramQ?br />Qinit-paramQ?br />Qparam-nameQuploadThresholdSizeQ?param-nameQ?br />Qparam-valueQ?00kQ?param-valueQ?br />Q?init-paramQ?br />Q?filterQ?br />
Qfilter-mappingQ?br />Qfilter-nameQExtensionsFilterQ?filter-nameQ?br />Qservlet-nameQFacesServletQ?servlet-nameQ?br />Q?filter-mappingQ?br />
Qwelcome-file-listQ?br />Qwelcome-fileQindex.jspQ?welcome-fileQ?br />Q?welcome-file-listQ?br />
Q?web-appQ?/p>
   前面CZ中的两个qo器(filterQ参数告诉MyFaces把小?00K的文件放入内存中Qƈ且忽略(即不处理Q占?0MB以上盘I间的文件。大介于uploadThresholdSize和uploadMaxFileSize之间的文件将作ؓ临时文g存储在磁盘上。如果你试图载入一个太大的文gQMyFaces当前版本忽略所有的H体数据Q就像用h交了一个空表单一栗如果你希望l上载文件失败的用户一些提CZ息,需要更改MyFaces的MultipartRequestWrapperc,扑ֈ捕捉SizeLimitExceededException异常的位|,q用FacesContext.getCurrentInstance().addMessage()来警告用戗?br />
   前面提到QMyFaces扩展包含了文件上载组Ӟ我们可以在JSF面中用它。下一部分介l如何实现这L操作?使用MyFaces的文件上载组件?br />
   Z在web面中用JSF和MyFacesQ你必须在<%@taglib%Q指令中声明它们的标记库Q?br />

Q?@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%Q?br />Q?@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%Q?br />Q?@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%Q?/p>
   JSF的<h:formQ标记没有method属性,q是因ؓ它只支持POSTҎQ但它拥有enctype属性,如果你希望上载文Ӟ必M用该属性,把窗体数据设|ؓ多部分(multipartQ编码类型:

Qf:viewQ?br />Qh:form id="MyForm" enctype="multipart/form-data" Q?br />...
Qx:inputFileUpload id="myFileId"
value="#{myBean.myFile}"
storage="file"
required="true"/Q?br />...
Q?h:formQ?br />Q?f:viewQ?/p>
   MyFaces的<x:inputFileUploadQ标C你能够定义UIlg的属性,它的呈现部gQrendererQ生成<input type="file"Q元素。org.apache.myfaces.custom.fileuploadE序包包含了UIlgc(HtmlInputFileUploadQ、呈现部ӞHtmlFileUploadRendererQ、定制的标记处理E序QHtmlInputFileUploadTagQ、UploadedFile接口和其它一些辅助类。HtmlInputFileUploadcL展了JSF标准的HtmlInputTextlgQ重载了它的一些方法。HtmlFileUploadRenderer负责生成HTML标记Q从MultipartRequestWrapper中获取FileItem?br />
   MyFacesq没有让你直接访问通用文g上蝲所建立的FileItem实例Q它提供了自qUploadedFile接口来获取被上蝲的文件的内容、内容类型、文件名和文件大。JSFH体的后台bean必须拥有一个UploadedFilecd的属性。前面的例子用JSF表达式(#{myBean.myFile}Q把UIlg的值绑定到了这样一个bean上。JSF框架lg获取HtmlInputFileUploadlg的|它是一个UploadedFile实例Qƈ且会讄后台bean的myFile属性:

import org.apache.myfaces.custom.fileupload.UploadedFile;
...
public class MyBean {
private UploadedFile myFile;

public UploadedFile getMyFile() {
return myFile;
}

public void setMyFile(UploadedFile myFile) {
this.myFile = myFile;
}
...
}


   MyFaces拥有UploadedFile接口的两U实现方式:UploadedFileDefaultMemoryImpl和UploadedFileDefaultFileImpl。当Qx:inputFileUploadQ标记没有带storage属性,或者这个属性的值是memory的时候,׃用前者。当storage属性的值是file的时候用后者?br />
   UploadedFileDefaultMemoryImplcMFileItem实例中获取被上蝲文g的内宏V文件名、文件大和内容cdQƈ把所有这些信息存储在U有字段中。因此,即通用文g上蝲把这个文件保存在盘上,UploadedFile的这U实C会把被上载文件的内容保存在内存中Q浪费了资源?br />
   UploadedFileDefaultFileImplcM用一个过渡字D|保存FileItem实例的指针,仅仅在调用getInputStream()Ҏ的时候,才用它来获取被上蝲文g的内宏V这U实现节U了内存I间Q但是,如果它是序列化的QserializeQ,那么在还原序列化QdeserializationQ之后,你就无法获取文g内容了。因此,文g上蝲H体的后台bean不能保存在session作用域(scopeQ中Q因为当应用E序重新启动或服务器关闭的时候,应用E序服务器会序列化对话(sessionQbean?br />
   如果你希望得C一个工作正常的、效率很高的解决ҎQ那么就把后台bean保存在request作用域中Qƈ在<x:inputFileUploadQ中指定storage="file"以节U内存资源。你也可以通过dwriteObject()ҎQ它用于序列化被上蝲文g的内容)来解决UploadedFileDefaultFileImplcȝ序列化问题。ؓ了保证UploadedFile的这U实现的高效性,相应的readObject()Ҏ应该重新建立一个时文Ӟ而不是从内存中读取内宏V?br />
   使用MyFaces的时候还需要注意一个问题:UploadedFile接口q没有定义一个用于删除通用文g上蝲在磁盘上所建立的时文件的Ҏ。当FileItem实例作ؓ垃圾被清理的时候,应该删掉这些文件。通用文g上蝲的DefaultFileItemcL有一个finalize()ҎQ当理临时文g的对象被从内存中删除的时候,它可以删除它们所理的时文件。如果你的应用程序正在上载大型文件的时候,你可能希望在它们被处理后立即删除Q而不用等待垃圾清除过E。ؓ了实现这L功能Q你必须d一个getFileItem()ҎQ在UploadedFileDefaultFileImpl中)Q它应该q回FileItem实例Q而该实例拥有delete()Ҏ?

  CZ应用E序

   前面的部分介l了是MyFaces如何在通用文g上蝲的帮助下支持文g上蝲的。现在我们来看一个实际的利用了这U特性的应用E序。JSFH体QMyForm.jspQ让用户选择一个文件和一个报文摘要算法,后台beanQ?MyBean.javaQ用这个算法计出一个散列|昄在另外一个web面QMyResult.jspQ中。这些页面和后台bean通过一个JSF配置文gQfaces-config.xmlQ结合在一赗?br />
   MyForm.jsp面

   q个JSFH体使用了MyFaces的<x:inputFileUploadQ标讎ͼ同时q用了其它一些标准的JSF标记来呈现标{、消息、包含报文摘要算法的下拉列表、用JSF表达式(#{myBean.processMyFile}Q指定了处理被上载文件的操作Ҏ的命令按钮:

Q?@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%Q?br />Q?@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%Q?br />Q?@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%Q?br />
Qf:viewQ?br />Qh:form id="MyForm" enctype="multipart/form-data" Q?br />  Qh:messages globalOnly="true" styleClass="message"/Q?br />  Qh:panelGrid columns="3" border="0" cellspacing="5"Q?br />  Qh:outputLabel for="myFileId" value="File: "/Q?br />  Qx:inputFileUpload id="myFileId" value="#{myBean.myFile}" storage="file" required="true"/Q?br />  Qh:message for="myFileId"/Q?br />  Qh:outputLabel for="myParamId" value="Param: "/Q?br />  Qh:selectOneMenu id="myParamId" value="#{myBean.myParam}" required="true"Q?br />  Qf:selectItem itemLabel="" itemValue=""/Q?br />  Qf:selectItem itemLabel="MD5" itemValue="MD5"/Q?br />  Qf:selectItem itemLabel="SHA-1" itemValue="SHA-1"/Q?br />  Qf:selectItem itemLabel="SHA-256" itemValue="SHA-256"/Q?br />  Qf:selectItem itemLabel="SHA-384" itemValue="SHA-384"/Q?br />  Qf:selectItem itemLabel="SHA-512" itemValue="SHA-512"/Q?br />Q?h:selectOneMenuQ?br />Qh:message for="myParamId"/Q?br />
Qh:outputText value=" "/Q?br />Qh:commandButton value="Submit"
action="#{myBean.processMyFile}"/Q?br />Qh:outputText value=" "/Q?br />
Q?h:panelGridQ?br />Q?h:formQ?br />Q?f:viewQ?/p>
   MyBeanc?br />
   后台bean拥有三个属性:myFile、myParam和myResult。前面已l解释了myFile属性的角色。它让你获取被上载文件的内容和文件名、文件大、内容类型。myParam属性的值是报文摘要法。myResult属性将保存processMyFile()Ҏ执行之后的散列倹{MyBeancMؓ自己的所有属性提供了get和setҎQ?br />

package com.devsphere.articles.jsfupload;

import org.apache.myfaces.custom.fileupload.UploadedFile;
...
public class MyBean {
  private UploadedFile myFile;
  private String myParam;
  private String myResult;

  public UploadedFile getMyFile() {
   return myFile;
  }

  public void setMyFile(UploadedFile myFile) {
   this.myFile = myFile;
  }

  public String getMyParam() {
   return myParam;
  }

  public void setMyParam(String myParam) {
   this.myParam = myParam;
  }

  public String getMyResult() {
   return myResult;
  }

  public void setMyResult(String myResult) {
   this.myResult = myResult;
  }
  ...
}


   processMyFile()通过一个输入流获取被上载文件的内容Q这个输入流是通过myFile.getInputStream()获得的。散列值是在java.security.MessageDigest的帮助下计算出来的,然后把它转换为字W串Q这样就可以被myResult属性访问了Q?br />

package com.devsphere.articles.jsfupload;
...
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import java.io.*;

public class MyBean {
  ...
  public String processMyFile() {
   try {
    MessageDigest md= MessageDigest.getInstance(myParam);
    InputStream in = new BufferedInputStream(
    myFile.getInputStream());
    try {
     byte[] buffer = new byte[64 * 1024];
     int count;
     while ((count = in.read(buffer)) Q?0)
      md.update(buffer, 0, count);
   } finally {
    in.close();
   }
   byte hash[] = md.digest();
   StringBuffer buf = new StringBuffer();
   for (int i = 0; i Q?hash.length; i++) {
    int b = hash[i] & 0xFF;
    int c = (b Q> 4) & 0xF;
    c = c Q?10 ? '0' + c : 'A' + c - 10;
    buf.append((char) c);
    c = b & 0xF;
    c = c Q?10 ? '0' + c : 'A' + c - 10;
    buf.append((char) c);
   }
   myResult = buf.toString();
   return "OK";
  } catch (Exception x) {
   FacesMessage message = new FacesMessage(
   FacesMessage.SEVERITY_FATAL,
   x.getClass().getName(), x.getMessage());
   FacesContext.getCurrentInstance().addMessage(null, message);
   return null;
  }
}

}


   faces-config.xml文g

   JSF配置文g把后台bean定义在request作用域中Qƈ且指定了一个导航规则:

Q?xml version="1.0" encoding="UTF-8"?Q?br />
Q?DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd"Q?br />
Qfaces-configQ?br />
Qmanaged-beanQ?br />Qmanaged-bean-nameQmyBeanQ?managed-bean-nameQ?br />Qmanaged-bean-classQ?br />com.devsphere.articles.jsfupload.MyBean
Q?managed-bean-classQ?br />Qmanaged-bean-scopeQrequestQ?managed-bean-scopeQ?br />Q?managed-beanQ?br />
Qnavigation-ruleQ?br />Qfrom-view-idQ?MyForm.jspQ?from-view-idQ?br />Qnavigation-caseQ?br />Qfrom-outcomeQOKQ?from-outcomeQ?br />Qto-view-idQ?MyResult.jspQ?to-view-idQ?br />Q?navigation-caseQ?br />Q?navigation-ruleQ?br />
Q?faces-configQ?/p>
   MyResult.jsp面

   q个web面昄了被上蝲文g的一些信息:

Q?@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%Q?br />Q?@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%Q?br />
Qf:viewQ?br />
Qh:panelGrid columns="2" border="0" cellspacing="5"Q?br />
Qh:outputText value="FileName:"/Q?br />Qh:outputText value="#{myBean.myFile.name}"/Q?br />
Qh:outputText value="FileSize:"/Q?br />Qh:outputText value="#{myBean.myFile.size}"/Q?br />
Qh:outputText value="Param:"/Q?br />Qh:outputText value="#{myBean.myParam}"/Q?br />
Qh:outputText value="Result:"/Q?br />Qh:outputText value="#{myBean.myResult}"/Q?br />
Q?h:panelGridQ?br />
Q?f:viewQ?/p>
   被显C的文g名可能带有客L文gpȝ的完整\径,如下所C:


?Q结果页面生的输出信息

   ȝ

   在很多情况下Q用户需要通过览器上载文Ӟ但是在服务器端却没有处理q些文g的理x法。把文g的内容保存在内存中对于小型文件来说是可以接受的,但是把被上蝲的文件存储在临时文g中ɘq种情况变复杂了。MyFaces让你能够选择一个适合应用E序需求的解决ҎQ但是这个框架组件也有一些小问题。当你不再需要时文件的时候,它无法让你删除它们;文g名有时候带有文件\径;当用户上载过大的文g的时候也没有警告信息。这些缺h可以修补的,因ؓ我们可以使用源代码,而且本文׃l了MyFaces代码可以改进的一些的地方。无论如何,对于多数应用E序来说QMyFaces不做修改合乎需求。本文的例子是用JSF 1.1.01、MyFaces 1.0.9和通用文g上蝲1.0环境试的?

cAng^Er 2006-12-14 10:02 发表评论
]]>
վ֩ģ壺 99ƷƷ| ëƬ߹ۿ| Ʒѿþþ㽶| ִִӲֳ | ѹۿƷ| Ůۺһ| ëƬȫһ| ձۺϸ| ޳ַ| ҹþþþƷӰԺ| vƬѹۿƵ| 츾AVһլ| ˬAëƬѿ| AVպAVɫ| h˻ƽ| ڵһ| ޳avƬ߹ۿ| þùƷ2020m3u8 | ŷһ| ƷƵվ| ޾ƷþþþþͼƬ | avڹƬ| AVþ| þøԴվѿ| ޾ƷƬ| ޸avվ| Ļպר| 91۲˽˳ӰԺ| 91ѹۿվ| þþƷAVδʮ| ˳ɫ7777߹ۿ| ߹ۿƬAVվ| ޹һ| Ҹ߳Ƶ| aƵѹۿ| Ӱ| AV뾫Ʒ| Ѳ߹ۿAV| þAV| պŷcom91tv| ѹۿվ߲|