<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>虎穴</title>
    <description>I will do it If I have the chance!!</description>
    <link>http://tantengfei.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Oracle的优化器</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/169784" style="color:red;">http://tantengfei.javaeye.com/blog/169784</a>&nbsp;
          发表时间: 2008年03月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Oracle的优化器有两种优化方式,即基于规则的优化方式(Rule-Based Optimization，简称为RBO)和基于代价的优化方式(Cost-Based Optimization，简称为CBO)，在Oracle8及以后的版本,Oracle强列推荐用CBO的方式 <br />    RBO方式：优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。比如我们常见的，当一个where子句中的一列有索引时去走索引。<br /><br />    CBO方式：它是看语句的代价(Cost),这里的代价主要指Cpu和内存。优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。统计信息给出表的大小、有少行、每行的长度等信息。这些统计信息起初在库内是没有的，是做analyze后才出现的，很多的时侯过期统计信息会令优化器做出一个错误的执行计划,因些应及时更新这些信息。<br /><br />    注意：走索引不一定就是优的，比如一个表只有两行数据，一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时全表扫描(full table scan)是最好<br /><br />    优化模式包括Rule、Choose、First rows、All rows四种方式：<br /><br />    Rule：基于规则的方式。<br /><br />    Choolse：默认的情况下Oracle用的便是这种方式。指的是当一个表或或索引有统计信息，则走CBO的方式，如果表或索引没统计信息，表又不是特别的小，而且相应的列有索引时，那么就走索引，走RBO的方式。<br /><br />    First Rows：它与Choose方式是类似的，所不同的是当一个表有统计信息时，它将是以最快的方式返回查询的最先的几行，从总体上减少了响应时间。<br /><br />    All Rows:也就是我们所说的Cost的方式，当一个表有统计信息时，它将以最快的方式返回表的所有的行，从总体上提高查询的吞吐量。没有统计信息则走RBO的方式。<br /><br />    设定选用哪种优化模式：<br /><br />    A、Instance级别我们可以通过在initSID.ora文件中设定OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS如果没设定OPTIMIZER_MODE参数则默认用的是Choose方式。<br />    B、Sessions级别通过ALTER SESSION SET OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS来设定。<br />    C、语句级别用Hint（/*+ ... */）来设定<br /><br />    为什么表的某个字段明明有索引，但执行计划却不走索引？<br /><br />    1、优化模式是all_rows的方式 <br />    2、表作过analyze，有统计信息<br />    3、表很小，上文提到过的，Oracle的优化器认为不值得走索引。
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/169784#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 10 Mar 2008 13:10:38 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/169784</link>
        <guid>http://tantengfei.javaeye.com/blog/169784</guid>
      </item>
      <item>
        <title>poi简介及应用</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/147605" style="color:red;">http://tantengfei.javaeye.com/blog/147605</a>&nbsp;
          发表时间: 2007年12月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          目前poi版本：poi-bin-3.0.1-FINAL-20070705.zip<br />到官方网站（http://apache.mirror.phpchina.com/poi/release/）下载后解压。<br />Jakarta POI可以让你使用Java来读写MS Excel ,Word文件<br /><br />（1）创建Excel 文档<br />示例1将演示如何利用Jakarta POI API 创建Excel 文档。 <br />示例1程序如下：<br /><br />import org.apache.poi.hssf.usermodel.HSSFWorkbook;<br />import org.apache.poi.hssf.usermodel.HSSFSheet;<br />import org.apache.poi.hssf.usermodel.HSSFRow;<br />import org.apache.poi.hssf.usermodel.HSSFCell;<br />import java.io.FileOutputStream;<br />public class CreateXL {<br /><br />　/** Excel 文件要存放的位置，假定在D盘下*/<br /><br />　public static String outputFile="D:\\test.xls";<br /><br />　public static void main(String argv[]){<br /><br />　try{<br /><br />　　// 创建新的Excel 工作簿<br /><br />　　HSSFWorkbook workbook = new HSSFWorkbook();<br /><br />　　// 在Excel工作簿中建一工作表，其名为缺省值<br />　　　　　　// 如要新建一名为"效益指标"的工作表，其语句为：<br />　　　　　　// HSSFSheet sheet = workbook.createSheet("效益指标");<br /><br />　　HSSFSheet sheet = workbook.createSheet();<br /><br />　　// 在索引0的位置创建行（最顶端的行）<br /><br />　　HSSFRow row = sheet.createRow((short)0);<br /><br />　　//在索引0的位置创建单元格（左上端）<br />　　HSSFCell cell = row.createCell((short) 0);<br />　　// 定义单元格为字符串类型<br />　　cell.setCellType(HSSFCell.CELL_TYPE_STRING);<br />　　// 在单元格中输入一些内容<br />　　cell.setCellValue("增加值");<br />　　// 新建一输出文件流<br />　　FileOutputStream fOut = new FileOutputStream(outputFile);<br />　　// 把相应的Excel 工作簿存盘<br />　　workbook.write(fOut);<br />　　fOut.flush();<br />　　// 操作结束，关闭文件<br />　　fOut.close();<br />　　System.out.println("文件生成...");<br /><br />　}catch(Exception e) {<br />　　System.out.println("已运行 xlCreate() : " + e );<br />　}<br />}<br />}<br />　　<br /><br />（2）读取Excel文档中的数据<br /><br />　　示例2将演示如何读取Excel文档中的数据。假定在D盘JTest目录下有一个文件名为test1.xls的Excel文件。<br /><br />示例2程序如下：<br /><br />import org.apache.poi.hssf.usermodel.HSSFWorkbook;<br />import org.apache.poi.hssf.usermodel.HSSFSheet;<br />import org.apache.poi.hssf.usermodel.HSSFRow;<br />import org.apache.poi.hssf.usermodel.HSSFCell;<br />import java.io.FileInputStream;<br />public class ReadXL {<br />　/** Excel文件的存放位置。注意是正斜线*/<br />　public static String fileToBeRead="D:\\test1.xls";<br />　public static void main(String argv[]){ <br />　try{<br />　　// 创建对Excel工作簿文件的引用<br />　　HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileToBeRead));<br />　　// 创建对工作表的引用。<br />　　// 本例是按名引用（让我们假定那张表有着缺省名"Sheet1"）<br />　　HSSFSheet sheet = workbook.getSheet("Sheet1");<br />　　// 也可用getSheetAt(int index)按索引引用，<br />　　// 在Excel文档中，第一张工作表的缺省索引是0，<br />　　// 其语句为：HSSFSheet sheet = workbook.getSheetAt(0);<br />　　// 读取左上端单元<br />　　HSSFRow row = sheet.getRow(0);<br />　　HSSFCell cell = row.getCell((short)0);<br />　　// 输出单元内容，cell.getStringCellValue()就是取所在单元的值<br />　　System.out.println("左上端单元是： " + cell.getStringCellValue()); <br />　}catch(Exception e) {<br />　　System.out.println("已运行xlRead() : " + e );<br />　}<br />}<br />}<br />　　设置单元格格式<br /><br />　　在这里，我们将只介绍一些和格式设置有关的语句，我们假定workbook就是对一个工作簿的引用。在Java中，第一步要做的就是创建和设置字体和单元格的格式，然后再应用这些格式：<br /><br />　　1、创建字体，设置其为红色、粗体：<br /><br />HSSFFont font = workbook.createFont();<br />font.setColor(HSSFFont.COLOR_RED);<br />font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);<br />　　2、创建格式<br /><br />HSSFCellStyle cellStyle= workbook.createCellStyle();<br />cellStyle.setFont(font);<br />　　3、应用格式 <br /><br />HSSFCell cell = row.createCell((short) 0);<br />cell.setCellStyle(cellStyle);<br />cell.setCellType(HSSFCell.CELL_TYPE_STRING);<br />cell.setCellValue("标题 ");　<br /><br /><br />（3）处理WORD文档<br /><br />import java.io.*; <br />import org.textmining.text.extraction.WordExtractor;<br />import org.apache.poi.hssf.usermodel.HSSFWorkbook;<br />import org.apache.poi.hssf.usermodel.HSSFSheet;<br />import org.apache.poi.hssf.usermodel.HSSFRow;<br />import org.apache.poi.hssf.usermodel.HSSFCell;<br /><br />public class TestPoi { <br />public TestPoi() { <br />} <br />public static void main(String args[]) throws Exception <br />{ <br />FileInputStream in = new FileInputStream ("D:\\a.doc"); <br />WordExtractor extractor = new WordExtractor(); <br />String str = extractor.extractText(in); <br />//System.out.println("the result length is"+str.length()); <br />System.out.println(str); <br />} <br />} <br />向EXCEL文件中导入数据以及读取Excel文档中的数据。
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/147605#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 11 Dec 2007 16:35:08 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/147605</link>
        <guid>http://tantengfei.javaeye.com/blog/147605</guid>
      </item>
      <item>
        <title>ext简介</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/142136" style="color:red;">http://tantengfei.javaeye.com/blog/142136</a>&nbsp;
          发表时间: 2007年11月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>无论你是Ext库的新手，抑或是想了解Ext的人，本篇文章的内容都适合你。本文将简单地介绍Ext的几个基本概念，和如何快速地做出一个动态的页面并运行起来，假设读者已具备了一些JavaScript经验和初级了解HTML Dom。</p>
<div>
<table class="toc mceVisualAid" id="toc" summary="目錄">
    <tbody>
        <tr>
            <td class="mceVisualAid">
            <div id="toctitle">
            <h2>目錄</h2>
            <span class="toctoggle">[<a href="javascript:toggleToc()" class="internal" id="togglelink" mce_href="javascript:toggleToc()">收埋</a>]</span></div>
            <ul>
                <li class="toclevel-1"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E4.B8.8B.E8.BD.BDExt" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E4.B8.8B.E8.BD.BDExt"><span class="tocnumber">1</span> <span class="toctext">下载Ext</span></a> </li>
                <li class="toclevel-1"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E5.BC.80.E5.A7.8B.EF.BC.81" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E5.BC.80.E5.A7.8B.EF.BC.81"><span class="tocnumber">2</span> <span class="toctext">开始！</span></a> </li>
                <li class="toclevel-1"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#Element.EF.BC.9AExt.E7.9A.84.E6.A0.B8.E5.BF.83" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#Element.EF.BC.9AExt.E7.9A.84.E6.A0.B8.E5.BF.83"><span class="tocnumber">3</span> <span class="toctext">Element：Ext的核心</span></a> </li>
                <li class="toclevel-1"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E8.8E.B7.E5.8F.96.E5.A4.9A.E4.B8.AADOM.E7.9A.84.E8.8A.82.E7.82.B9" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E8.8E.B7.E5.8F.96.E5.A4.9A.E4.B8.AADOM.E7.9A.84.E8.8A.82.E7.82.B9"><span class="tocnumber">4</span> <span class="toctext">获取多个DOM的节点</span></a> </li>
                <li class="toclevel-1"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E5.93.8D.E5.BA.94.E4.BA.8B.E4.BB.B6" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E5.93.8D.E5.BA.94.E4.BA.8B.E4.BB.B6"><span class="tocnumber">5</span> <span class="toctext">响应事件</span></a> </li>
                <li class="toclevel-1"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E4.BD.BF.E7.94.A8Widgets" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E4.BD.BF.E7.94.A8Widgets"><span class="tocnumber">6</span> <span class="toctext">使用Widgets</span></a>
                <ul>
                    <li class="toclevel-2"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#MessageBox" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#MessageBox"><span class="tocnumber">6.1</span> <span class="toctext">MessageBox</span></a> </li>
                    <li class="toclevel-2"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#Grid" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#Grid"><span class="tocnumber">6.2</span> <span class="toctext">Grid</span></a> </li>
                    <li class="toclevel-2"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E8.BF.98.E6.9C.89.E6.9B.B4.E5.A4.9A.E7.9A.84.." mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E8.BF.98.E6.9C.89.E6.9B.B4.E5.A4.9A.E7.9A.84.."><span class="tocnumber">6.3</span> <span class="toctext">还有更多的..</span></a></li>
                </ul>
                </li>
                <li class="toclevel-1"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E4.BD.BF.E7.94.A8Ajax" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#.E4.BD.BF.E7.94.A8Ajax"><span class="tocnumber">7</span> <span class="toctext">使用Ajax</span></a>
                <ul>
                    <li class="toclevel-2"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#PHP" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#PHP"><span class="tocnumber">7.1</span> <span class="toctext">PHP</span></a> </li>
                    <li class="toclevel-2"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#ASP.Net" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#ASP.Net"><span class="tocnumber">7.2</span> <span class="toctext">ASP.Net</span></a> </li>
                    <li class="toclevel-2"><a href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#Cold_Fusion" mce_href="http://extjs.com/learn/Tutorial:Introduction_to_Ext_%28Chinese%29#Cold_Fusion"><span class="tocnumber">7.3</span> <span class="toctext">Cold Fusion</span></a></li>
                </ul>
                </li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
</div>
<script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "展開"; var tocHideText = "收埋"; showTocToggle(); } </script>
<div><a name=".E4.B8.8B.E8.BD.BDExt" title=".E4.B8.8B.E8.BD.BDExt" class="mceItemAnchor"></a></div>
<h3><span class="mw-headline">下载Ext</span></h3>
<p>如果你未曾下载过，那应从这里下载最新版本的Ext <a href="http://extjs.com/downloads" title="http://extjs.com/downloads" class="external free" rel="nofollow" mce_href="http://extjs.com/downloads">http://extjs.com/downloads</a> 。</p>
<p>针对你的下载需求，有几个不同的弹性选项。通常地，最稳定的版本，是较多人的选择。下载解包后，那个example文件夹便是一个探索Ext的好地方！</p>
<div><a name=".E5.BC.80.E5.A7.8B.EF.BC.81" title=".E5.BC.80.E5.A7.8B.EF.BC.81" class="mceItemAnchor"></a></div>
<h3><span class="mw-headline">开始！</span></h3>
<div>
<table class="mceVisualAid" style="BORDER-RIGHT: rgb(47,111,171) 1px solid; BORDER-TOP: rgb(47,111,171) 1px solid; BACKGROUND: rgb(249,249,249) 0% 50%; FLOAT: right; MARGIN: 10px; BORDER-LEFT: rgb(47,111,171) 1px solid; BORDER-BOTTOM: rgb(47,111,171) 1px solid; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
    <tbody>
        <tr>
            <td class="mceVisualAid"><strong>Download Example File</strong>
            <ul>
                <li><tt><a href="http://extjs.com/downloads/tutorial/introduction-ext/IntroToExt.zip" title="http://extjs.com/downloads/tutorial/introduction-ext/IntroToExt.zip" class="external text" rel="nofollow" mce_href="http://extjs.com/downloads/tutorial/introduction-ext/IntroToExt.zip"><font face="Courier New">IntroToExt.zip</font></a></tt> </li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>我们将使用Ext，来完成一些JavaScript任务。</p>
<p>Zip文件包括三个文件：<strong>ExtStart.html</strong>, <strong>ExtStart.js</strong>和<strong>ExtStart.css</strong>。解包这三个文件到Ext的安装目录中（例如，Ext是在&ldquo;C:\code\Ext\v1.0&rdquo;中，那应该在&quot;v1.0&quot;里面新建目录&ldquo;tutorial&rdquo;。双击<strong>ExtStart.htm</strong>，接着你的浏览器打开启动页面，应该会有一条消息告诉你配置已完毕。如果是一个Javascript错误，请按照页面上的指引操作。</p>
<p>在你常用的IDE中或文本编辑器中，打开ExtStart.js看看：</p>
<p>Ext.onReady可能是你接触的第一个方法。这个方法是指当前DOM加载完毕后，保证页面内的所有元素能被Script引用（reference）。你可删除alert()那行，加入一些实际用途的代码试试：</p>
<div>
<pre class="source source-javascript">Ext.<span class="me1">onReady</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
	<span class="kw3">alert</span><span class="br0">(</span><span class="st0">&quot;Congratulations!  You have Ext configured correctly!&quot;</span><span class="br0">)</span>;
<span class="br0">}</span><span class="br0">)</span>;</pre>
</div>
<div><a name="Element.EF.BC.9AExt.E7.9A.84.E6.A0.B8.E5.BF.83" title="Element.EF.BC.9AExt.E7.9A.84.E6.A0.B8.E5.BF.83" class="mceItemAnchor"></a></div>
<h3><span class="mw-headline">Element：Ext的核心</span></h3>
<p>大多数的JavaScript操作都需要先获取页面上的某个元素（reference）,好让你来做些实质性的事情。传统的JavaScript方法，是通过ID获取Dom节点的：</p>
<div>
<pre>var myDiv = document.getElementById('myDiv');</pre>
</div>
<p>这毫无问题，不过这样单单返回一个对象（DOM节点），用起来并不是太实用和方便。为了要用那节点干点事情，你还将要手工编写不少的代码；另外，对于不同类型浏览器之间的差异，要你处理起来可真头大了。</p>
<p>进入Ext.element 对象。元素（element）的的确确是Ext的心脏地带，--无论是访问元素（elements）还是完成一些其他动作，都要涉及它。Element的 API是整个Ext库的基础，如果你时间不多，只是想了解Ext中的一两个类的话，Element一定是首选！</p>
<p>由ID获取一个Ext Element如下（首页ExtStart.htm包含一个div，ID名字为&ldquo;myDiv&rdquo;，然后，在ExtStart.js中加入下列语句）：</p>
<div>
<pre>Ext.onReady(function() {var myDiv = Ext.get('myDiv');});</pre>
</div>
<p>再回头看看Element对象，发现什么有趣的东东呢？</p>
<div>
<ul>
    <li>Element包含了常见的DOM方法和属性，提供一个快捷的、统一的、跨浏览器的接口（若使用Element.dom的话，就可以直接访问底层DOM的节点。）； </li>
    <li>Element.get()方法内置缓存处理（Cache)，多次访问同一对象效率上有极大优势； </li>
    <li>内置常用的DOM节点的动作，并且是跨浏览器的定位的位置、大小、动画、拖放等等（add/remove CSS classes, add/remove event handlers, positioning, sizing, animation, drag/drop）。</li>
</ul>
</div>
<p>这意味着你可用少量的代码来做各种各样的事情，这里仅仅是一个简单的例子（完整的列表在ElementAPI中）。</p>
<p>继续在ExtStart.js中，在刚才我们获取好myDiv的位置中加入：</p>
<pre class="source source-javascript">myDiv.<span class="me1">highlight</span><span class="br0">(</span><span class="br0">)</span>;      <span class="co1">//黄色高亮显示然后渐退</span>
myDiv.<span class="me1">addClass</span><span class="br0">(</span><span class="st0">'red'</span><span class="br0">)</span>;  <span class="co1">// 添加自定义CSS类 (在ExtStart.css定义)</span>
myDiv.<span class="me1">center</span><span class="br0">(</span><span class="br0">)</span>;         <span class="co1">//在视图中将元素居中</span>
myDiv.<span class="me1">setOpacity</span><span class="br0">(</span>.<span class="nu0">25</span><span class="br0">)</span>;  <span class="co1">// 使元素半透明</span></pre>
<a name=".E8.8E.B7.E5.8F.96.E5.A4.9A.E4.B8.AADOM.E7.9A.84.E8.8A.82.E7.82.B9" title=".E8.8E.B7.E5.8F.96.E5.A4.9A.E4.B8.AADOM.E7.9A.84.E8.8A.82.E7.82.B9" class="mceItemAnchor"></a>
<h3><span class="mw-headline">获取多个DOM的节点</span></h3>
<p>通常情况下，想获取多个DOM的节点，难以依靠ID的方式来获取。有可能因为没设置ID,或者你不知道ID,又或者直接用ID方式引用有太多元素了。这种情况下，你就会不用ID来作为获取元素的依据，可能会用属性（attribute）或CSS Classname代替。基于以上的原因，Ext引入了一个功能异常强大的Dom Selector库，叫做DomQuery。</p>
<p>DomQuery可作为单独的库使用，但常用于Ext，你可以在上下文环境中（Context）获取多个元素，然后通过Element接口调用。令人欣喜的是，Element对象本身便有Element.selcect的方法来实现查询，即内部调用DomQuery选取元素。这个简单的例子中， ExtStart.htm包含若干段落（ </p>
<p>标签），没有一个是有ID的，而你想轻松地通过一次操作马上获取每一段，全体执行它们的动作，可以这样做：</p>
<pre class="source source-javascript"><span class="co1">// 每段高亮显示</span>
Ext.<span class="me1">select</span><span class="br0">(</span><span class="st0">'p'</span><span class="br0">)</span>.<span class="me1">highlight</span><span class="br0">(</span><span class="br0">)</span>;</pre>
<p>DomQuery的选取参数是一段较长的数组，其中包括W3C CSS3 Dom选取器、基本XPatch、HTML属性和更多，请参阅DomQuery API文档以了解这功能强大的库个中细节。</p>
<a name=".E5.93.8D.E5.BA.94.E4.BA.8B.E4.BB.B6" title=".E5.93.8D.E5.BA.94.E4.BA.8B.E4.BB.B6" class="mceItemAnchor"></a>
<h3><span class="mw-headline">响应事件</span></h3>
<p>到这范例为止，我们所写的代码都是放在onReady中，即当页面加载后总会立即执行，功能较单一&mdash;&mdash;这样的话，你便知道，如何响应某个动作或事件来执行你希望做的事情，做法是，先分配一个function，再定义一个event handler事件处理器来响应。我们由这个简单的范例开始，打开ExtStart.js，编辑下列的代码：</p>
<pre class="source source-javascript">Ext.<span class="me1">onReady</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
	Ext.<span class="me1">get</span><span class="br0">(</span><span class="st0">'myButton'</span><span class="br0">)</span>.<span class="me1">on</span><span class="br0">(</span><span class="st0">'click'</span>, <span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span><span class="br0">{</span>
		<span class="kw3">alert</span><span class="br0">(</span><span class="st0">&quot;You clicked the button&quot;</span><span class="br0">)</span>;
	<span class="br0">}</span><span class="br0">)</span>;
<span class="br0">}</span><span class="br0">)</span>;</pre>
<p>加载好页面，代码依然会执行，不过区别是，包含alert()的function是已定义好的，但它不会立即地被执行，是分配到按钮的单击事件中。用浅显的文字解释，就是：获取ID为'myDottom'元素的引用，监听任何发生这个元素上被单击的情况，并分配一个function,以准备任何单击元素的情况。</p>
<p>正路来说，Element.select也能做同样的事情，即作用在获取一组元素上。下一例中，演示了页面中的某一段落被单击后，便有弹出窗口：</p>
<pre class="source source-javascript">Ext.<span class="me1">onReady</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
	Ext.<span class="me1">select</span><span class="br0">(</span><span class="st0">'p'</span><span class="br0">)</span>.<span class="me1">on</span><span class="br0">(</span><span class="st0">'click'</span>, <span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
		<span class="kw3">alert</span><span class="br0">(</span>&quot;You clicked a paragraph&quot;<span class="br0">)</span>;
	<span class="br0">}</span><span class="br0">)</span>;
<span class="br0">}</span><span class="br0">)</span>;</pre>
<p>这两个例子中，事件处理的function均是简单几句，没有函数的名称，这种类型函数称为&ldquo;匿名函数（anonymous function）&rdquo;，即是没有名的的函数。你也可以分配一个有名字的event handler,这对于代码的重用或多个事件很有用。下一例等效于上一例：</p>
<pre class="source source-javascript">Ext.<span class="me1">onReady</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
	<span class="kw2">var</span> paragraphClicked = <span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
		<span class="kw3">alert</span><span class="br0">(</span>&quot;You clicked a paragraph&quot;<span class="br0">)</span>;
	<span class="br0">}</span>
	Ext.<span class="me1">select</span><span class="br0">(</span><span class="st0">'p'</span><span class="br0">)</span>.<span class="me1">on</span><span class="br0">(</span><span class="st0">'click'</span>, paragraphClicked<span class="br0">)</span>;
<span class="br0">}</span><span class="br0">)</span>;</pre>
<p>到目前为止，我们已经知道如何执行某个动作。但当事件触发时，我们如何得知这个event handler执行时是作用在哪一个特定的元素上呢？要明确这一点非常简单，Element.on方法传入到even handler的function中（我们这里先讨论第一个参数，不过你应该浏览API文档以了解even handler更多的细节）。在我们之前的例子中，function是忽略这些参数的，到这里可有少许的改变，&mdash;&mdash;我们在功能上提供了更深层次的控制。必须先说明的是，这实际上是Ext的事件对象（event object）,一个跨浏览器和拥有更多控制的事件的对象。例如，可以用下列的语句，得到这个事件响应所在的DOM节点：<br />
</p>
<pre class="source source-javascript">Ext.<span class="me1">onReady</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
	<span class="kw2">var</span> paragraphClicked = <span class="kw2">function</span><span class="br0">(</span>e<span class="br0">)</span> <span class="br0">{</span>
		Ext.<span class="me1">get</span><span class="br0">(</span>e.<span class="me1">target</span><span class="br0">)</span>.<span class="me1">highlight</span><span class="br0">(</span><span class="br0">)</span>;
	<span class="br0">}</span>
	Ext.<span class="me1">select</span><span class="br0">(</span><span class="st0">'p'</span><span class="br0">)</span>.<span class="me1">on</span><span class="br0">(</span><span class="st0">'click'</span>, paragraphClicked<span class="br0">)</span>;
<span class="br0">}</span><span class="br0">)</span>;</pre>
<p>注意得到的e.target是DOM节点，所以我们首先将其转换成为EXT的Elemnet元素，然后执行欲完成的事件，这个例子中，我们看见段落是高亮显示的。<br />
</p>
<a name=".E4.BD.BF.E7.94.A8Widgets" title=".E4.BD.BF.E7.94.A8Widgets" class="mceItemAnchor"></a>
<h3><span class="mw-headline">使用Widgets</span></h3>
<pre> (Widget原意为&ldquo;小器件&rdquo;，现指页面中UI控件)
</pre>
<p>除了我们已经讨论过的核心JavaScript库，当前的Ext亦包括了一系列的最前端的JavaScirptUI组件库。文本以一个常用的widget为例子，作简单的介绍。</p>
<a name="MessageBox" title="MessageBox" class="mceItemAnchor"></a>
<h4><span class="mw-headline">MessageBox</span></h4>
<p>比起略为沉闷的&ldquo;HelloWolrd&rdquo;消息窗口，我们做少许变化，前面我们写的代码是，单击某个段落便会高亮显示，现在是单击段落，在消息窗口中显示段落内容出来。<br />
在上面的paragraphClicked的function中，将这行代码： </p>
<pre class="source source-javascript">Ext.<span class="me1">get</span><span class="br0">(</span>e.<span class="me1">target</span><span class="br0">)</span>.<span class="me1">highlight</span><span class="br0">(</span><span class="br0">)</span>;</pre>
<p>替换为：</p>
<pre class="source source-javascript"><span class="kw2">var</span> paragraph = Ext.<span class="me1">get</span><span class="br0">(</span>e.<span class="me1">target</span><span class="br0">)</span>;
paragraph.<span class="me1">highlight</span><span class="br0">(</span><span class="br0">)</span>;
Ext.<span class="me1">MessageBox</span>.<span class="me1">show</span><span class="br0">(</span><span class="br0">{</span>
	title: <span class="st0">'Paragraph Clicked'</span>,
	msg: paragraph.<span class="me1">dom</span>.<span class="me1">innerHTML</span>,
	width:<span class="nu0">400</span>,
	buttons: Ext.<span class="me1">MessageBox</span>.<span class="me1">OK</span>,
	animEl: paragraph
<span class="br0">}</span><span class="br0">)</span>;</pre>
<p>这里有些新的概念需要讨论一下。在第一行中我们创建了一个局部变量（Local Variable）来保存某个元素的引用，即被单击的那个DOM节点（本例中，DOM节点指的是段落paragrah,事因我们已经定义该事件与&lt; p&gt;标签发生关联的了）。为什么要这样做呢？嗯...观察上面的代码，我们需要引用同一元素来高亮显示，在MessageBox中也是引用同一元素作为参数使用。<br />
一般来说，多次重复使用同一值（Value）或对象，是一个不好的方式，所以，作为一个具备良好OO思维的开发者，应该是将其分配到一个局部变量中，反复使用这变量！</p>
<p>现在，为了我们接下来阐述新概念的演示，请观察MessageBox的调用。乍一看，这像一连串的参数传入到方法中，但仔细看，这是一个非常特别的语法。实际上，传入到MessageBox.show的只有一个参数：一个Object literal,包含一组属性和属性值。在Javascript中，Object Literal是动态的，你可在任何时候用{和}创建一个典型的对象(object)。其中的字符由一系列的name/value组成的属性，属性的格式是[property name]:[property value]。在整个Ext中，你将会经常遇到这种语法，因此你应该马上消化并吸收这个知识点！<br />
使用Object Literal的原因是什么呢？主要的原因是&ldquo;可伸缩性（flexibility）&rdquo;的考虑&quot;，随时可新增、删除属性，亦可不管顺序地插入。而方法不需要改变。这也是多个参数的情况下，为最终开发者带来不少的方便（本例中的MessageBox.show())。例如，我们说这儿的foo.action方法，有四个参数，而只有一个是你必须传入的。本例中，你想像中的代码可能会是这样的foo.action(null, null, null, 'hello').,若果那方法用Object Literal来写，却是这样， foo.action({ param4: 'hello' })，这更易用和易读。</p>
<a name="Grid" title="Grid" class="mceItemAnchor"></a>
<h4><span class="mw-headline">Grid</span></h4>
<p>Grid是Ext中人们最想先睹为快的和最为流行Widgets之一。好，让我们看看怎么轻松地创建一个Grid并运行。用下列代码替换ExtStart.js中全部语句：</p>
<pre class="source source-javascript">Ext.<span class="me1">onReady</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
	<span class="kw2">var</span> myData = <span class="br0">[</span>
		<span class="br0">[</span><span class="st0">'Apple'</span>,<span class="nu0">29.89</span>,<span class="nu0">0.24</span>,<span class="nu0">0.81</span>,<span class="st0">'9/1 12:00am'</span><span class="br0">]</span>,
		<span class="br0">[</span><span class="st0">'Ext'</span>,<span class="nu0">83.81</span>,<span class="nu0">0.28</span>,<span class="nu0">0.34</span>,<span class="st0">'9/12 12:00am'</span><span class="br0">]</span>,
		<span class="br0">[</span><span class="st0">'Google'</span>,<span class="nu0">71.72</span>,<span class="nu0">0.02</span>,<span class="nu0">0.03</span>,<span class="st0">'10/1 12:00am'</span><span class="br0">]</span>,
		<span class="br0">[</span><span class="st0">'Microsoft'</span>,<span class="nu0">52.55</span>,<span class="nu0">0.01</span>,<span class="nu0">0.02</span>,<span class="st0">'7/4 12:00am'</span><span class="br0">]</span>,
		<span class="br0">[</span><span class="st0">'Yahoo!'</span>,<span class="nu0">29.01</span>,<span class="nu0">0.42</span>,<span class="nu0">1.47</span>,<span class="st0">'5/22 12:00am'</span><span class="br0">]</span>
	<span class="br0">]</span>;
&nbsp;
	<span class="kw2">var</span> ds = <span class="kw2">new</span> Ext.<span class="me1">data</span>.<span class="me1">Store</span><span class="br0">(</span><span class="br0">{</span>
		proxy: <span class="kw2">new</span> Ext.<span class="me1">data</span>.<span class="me1">MemoryProxy</span><span class="br0">(</span>myData<span class="br0">)</span>,
		reader: <span class="kw2">new</span> Ext.<span class="me1">data</span>.<span class="me1">ArrayReader</span><span class="br0">(</span><span class="br0">{</span>id: <span class="nu0">0</span><span class="br0">}</span>, <span class="br0">[</span>
			<span class="br0">{</span><span class="kw3">name</span>: <span class="st0">'company'</span><span class="br0">}</span>,
			<span class="br0">{</span><span class="kw3">name</span>: <span class="st0">'price'</span>, type: <span class="st0">'float'</span><span class="br0">}</span>,
			<span class="br0">{</span><span class="kw3">name</span>: <span class="st0">'change'</span>, type: <span class="st0">'float'</span><span class="br0">}</span>,
			<span class="br0">{</span><span class="kw3">name</span>: <span class="st0">'pctChange'</span>, type: <span class="st0">'float'</span><span class="br0">}</span>,
			<span class="br0">{</span><span class="kw3">name</span>: <span class="st0">'lastChange'</span>, type: <span class="st0">'date'</span>, dateFormat: <span class="st0">'n/j h:ia'</span><span class="br0">}</span>
	<span class="br0">]</span><span class="br0">)</span>
	<span class="br0">}</span><span class="br0">)</span>;
	ds.<span class="me1">load</span><span class="br0">(</span><span class="br0">)</span>;
&nbsp;
	<span class="kw2">var</span> colModel = <span class="kw2">new</span> Ext.<span class="me1">grid</span>.<span class="me1">ColumnModel</span><span class="br0">(</span><span class="br0">[</span>
		<span class="br0">{</span>header: &quot;Company&quot;, width: <span class="nu0">120</span>, sortable: <span class="kw2">true</span>, dataIndex: <span class="st0">'company'</span><span class="br0">}</span>,
		<span class="br0">{</span>header: &quot;Price&quot;, width: <span class="nu0">90</span>, sortable: <span class="kw2">true</span>, dataIndex: <span class="st0">'price'</span><span class="br0">}</span>,
		<span class="br0">{</span>header: &quot;Change&quot;, width: <span class="nu0">90</span>, sortable: <span class="kw2">true</span>, dataIndex: <span class="st0">'change'</span><span class="br0">}</span>,
		<span class="br0">{</span>header: &quot;% Change&quot;, width: <span class="nu0">90</span>, sortable: <span class="kw2">true</span>, dataIndex: <span class="st0">'pctChange'</span><span class="br0">}</span>,
		<span class="br0">{</span>header: &quot;Last Updated&quot;, width: <span class="nu0">120</span>, sortable: <span class="kw2">true</span>, 
		renderer: Ext.<span class="me1">util</span>.<span class="me1">Format</span>.<span class="me1">dateRenderer</span><span class="br0">(</span><span class="st0">'m/d/Y'</span><span class="br0">)</span>, dataIndex: <span class="st0">'lastChange'</span><span class="br0">}</span>
	<span class="br0">]</span><span class="br0">)</span>;
&nbsp;
	<span class="kw2">var</span> grid = <span class="kw2">new</span> Ext.<span class="me1">grid</span>.<span class="me1">Grid</span><span class="br0">(</span><span class="st0">'grid-example'</span>, <span class="br0">{</span>ds: ds, cm: colModel<span class="br0">}</span><span class="br0">)</span>;
		grid.<span class="me1">render</span><span class="br0">(</span><span class="br0">)</span>;
		grid.<span class="me1">getSelectionModel</span><span class="br0">(</span><span class="br0">)</span>.<span class="me1">selectFirstRow</span><span class="br0">(</span><span class="br0">)</span>;
	<span class="br0">}</span><span class="br0">)</span>;</pre>
<p>这看上去很复杂，但实际上加起来，只有七行代码。第一行创建数组并作为数据源。实际案例中，你很可能从数据库、或者WebService那里得到动态的数据。接着，我们创建并加载data store， data store将会告诉Ext的底层库接手处理和格式化这些数据。接着，我们定义一个column模型，用来轻松地调配Grid的每一列参数。最后我们生成这个Grid,传入data store和column模型两个对象，进行渲染并选好第一行。不是太困难吧？如果一切顺利，完成之后你会看到像这样的： <br />
</p>
<p><a href="http://extjs.com/learn/Image:IntroToExt_grid.gif" title="Image:IntroToExt_grid.gif" class="image" mce_href="http://extjs.com/learn/Image:IntroToExt_grid.gif"><img src="http://extjs.com/learn/w/images/c/cd/IntroToExt_grid.gif" longdesc="/learn/Image:IntroToExt_grid.gif" height="135" alt="Image:IntroToExt_grid.gif" mce_src="http://extjs.com/learn/w/images/c/cd/IntroToExt_grid.gif" width="545" /></a> </p>
<p>当然，你可能未掌握这段代码的某些细节（像MemoryProxy究竟是什么？）但先不要紧，这个例子的目的是告诉你，用少量的代码，创建一个富界面的多功能的UI组件而已&mdash;&mdash;这是完全可能的，只要读者您有兴趣学习。这儿有许多学习Grid的资源。Ext Grid教程、交叉Gird演示和Grid API文档。 </p>
<a name=".E8.BF.98.E6.9C.89.E6.9B.B4.E5.A4.9A.E7.9A.84.." title=".E8.BF.98.E6.9C.89.E6.9B.B4.E5.A4.9A.E7.9A.84.." class="mceItemAnchor"></a>
<h4><span class="mw-headline">还有更多的..</span></h4>
<p>这只是冰山一角。还有一打的UI Widgets可以供调用，如 layouts, tabs, menus, toolbars, dialogs, tree view等等。请参阅API文档中范例演示。 </p>
<a name=".E4.BD.BF.E7.94.A8Ajax" title=".E4.BD.BF.E7.94.A8Ajax" class="mceItemAnchor"></a>
<h3><span class="mw-headline">使用Ajax</span></h3>
<p>在弄好一些页面后，你已经懂得在页面和脚本之间的交互原理（interact）。接下来，你应该掌握的是，怎样与远程服务器（remote server）交换数据，常见的是从数据库加载数据（load）或是保存数据（save）到数据库中。通过JavaScript异步无刷新交换数据的这种方式，就是所谓的Ajax。Ext内建卓越的Ajax支持，例如，一个普遍的用户操作就是，异步发送一些东西到服务器，然后，UI元素根据回应（Response）作出更新。这是一个包含text input的表单，一个div用于显示消息（注意，你可以在ExtStart.html中加入下列代码，但这必须要访问服务器）：</p>
<pre>&lt;div id=&quot;msg&quot; style=&quot;visibility: hidden&quot;&gt;&lt;/div&gt; 

Name: &lt;input type=&quot;text&quot; id=&quot;name&quot; /&gt;&lt;br /&gt; 

&lt;input type=&quot;button&quot; id=&quot;oKButton&quot; value=&quot;OK&quot; /&gt;</pre>
<pre><div id="msg" style="VISIBILITY: hidden"></div> 接着，我们加入这些处理交换数据的JavaScript代码到文件ExtStart.js中(用下面的代码覆盖)：</pre>
<pre class="source source-javascript">Ext.<span class="me1">onReady</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span><span class="br0">{</span>
	Ext.<span class="me1">get</span><span class="br0">(</span><span class="st0">'oKButton'</span><span class="br0">)</span>.<span class="me1">on</span><span class="br0">(</span><span class="st0">'click'</span>, <span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span><span class="br0">{</span>
		<span class="kw2">var</span> msg = Ext.<span class="me1">get</span><span class="br0">(</span><span class="st0">'msg'</span><span class="br0">)</span>;
			msg.<span class="me1">load</span><span class="br0">(</span><span class="br0">{</span>
			url: <span class="br0">[</span>server url<span class="br0">]</span>, <span class="co1">//换成你的URL</span>
			params: <span class="st0">'name='</span> + Ext.<span class="me1">get</span><span class="br0">(</span><span class="st0">'name'</span><span class="br0">)</span>.<span class="me1">dom</span>.<span class="me1">value</span>,
			text: <span class="st0">'Updating...'</span>
&nbsp;
		<span class="br0">}</span><span class="br0">)</span>;
		msg.<span class="me1">show</span><span class="br0">(</span><span class="br0">)</span>;
	<span class="br0">}</span><span class="br0">)</span>;
<span class="br0">}</span><span class="br0">)</span>;</pre>
<p>这种模式看起来已经比较熟悉了吧！先获取按钮元素，加入单击事件的监听。在事件处理器中（event handler），我们使用一个负责处理Ajax请求、接受响应（Response）和更新另一个元素的Ext内建类，称作UpdateManager。 UpdateManager可以直接使用，或者和我们现在的做法一样，通过Element的load方法来引用（本例中该元素是id为&ldquo;msg&ldquo;的 div）。当使用Element.load方法，请求（request)会在加工处理后发送，等待服务器的响应（Response），来自动替换元素的 innerHTML。简单传入服务器url地址，加上字符串参数，便可以处理这个请求（本例中，参数值来自&ldquo;name&rdquo;元素的value),而text值是请求发送时提示的文本，完毕后显示那个msg的div（因为开始时默认隐藏）。当然，和大多数Ext组件一样，UpdateManager有许多的参数可选，不同的Ajax请求有不同的方案。而这里仅演示最简单的那种。</p>
<a name="PHP" title="PHP" class="mceItemAnchor"></a>
<h4><span class="mw-headline">PHP</span></h4>
<pre>&lt;? if(isset($_GET['name'])) {
    echo 'From Server: '.$_GET['name'];
}
?&gt;</pre>
<p><a name="ASP.Net" title="ASP.Net" class="mceItemAnchor"></a></p>
<h4><span class="mw-headline">ASP.Net</span></h4>
<pre>protected void Page_Load(object sender, EventArgs e)
{
    if (Request[&quot;name&quot;]&nbsp;!= null)
       {
		Response.Write(&quot;From Server: &quot; + Request[&quot;name&quot;]);
		Response.End();
	}
}
</pre>
<a name="Cold_Fusion" title="Cold_Fusion" class="mceItemAnchor"></a>
<h4><span class="mw-headline">Cold Fusion </span><cfif></cfif></h4>
<pre>&lt;cfif StructKeyExists(url, &quot;name&quot;)&gt;
	&lt;cfoutput&gt;From Server: #url.name#&lt;/cfoutput&gt;
&lt;/cfif&gt;</pre>
<p>最后一个关于Ajax隐晦的地方就是，服务器实际处理请求和返回（Resposne）是具体过程。这个过程会是一个服务端页面，一个Servlet，一个 Http调度过程，一个WebService,甚至是Perl或CGI脚本，即不指定一个服务器都可以处理的http请求。让人无法预料的是，服务器返回什么是服务器的事情，无法给一个标准的例子来覆盖阐述所有的可能性。(这段代码输出刚才我们传入'name'的那个值到客户端，即发送什么，返回什么）。</p>
<p>使用Ajax的真正挑战，是需要进行适当的手工编码，并相应格式化为服务端可用接受的数据结构。有几种格式供人们选择（最常用为JSON/XML)。正因 Ext是一种与服务器语言免依赖的机制，使得其它特定语言的库亦可用于Ext处理Ajax服务。只要页面接受到结果是EXT能处理的数据格式，Ext绝不会干涉服务器其他的事情！要全面讨论这个问题，已超出本文的范围。推荐正在Ajax环境下开发的您，继续深入阅读Ext Ajax教程。</p>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/142136#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 20 Nov 2007 18:14:54 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/142136</link>
        <guid>http://tantengfei.javaeye.com/blog/142136</guid>
      </item>
      <item>
        <title>缓存技术（oscache ）与（ehcache）</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/142130" style="color:red;">http://tantengfei.javaeye.com/blog/142130</a>&nbsp;
          发表时间: 2007年11月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>一.ehcache主要是对数据库访问的缓存,相同的查询语句只需查询一次数据库,</p>
<p>&nbsp; 从而提高了查询的速度,使用spring的AOP可以很容易实现这一功能.</p>
<p>&nbsp; <!--href="http://ehcache.sourceforge.net-->[ehcache.sourceforge.net]</p>
<p>&nbsp; ehcache.xml</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;cache name=&quot;sampleCache1&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxElementsInMemory=&quot;10000&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eternal=&quot;false&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToIdleSeconds=&quot;300&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToLiveSeconds=&quot;600&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; overflowToDisk=&quot;true&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&gt;</p>
<p>org.springframework.cache.ehcache.EhCacheManagerFactoryBean</p>
<p>org.springframework.cache.ehcache.EhCacheFactoryBean</p>
<p>org.springframework.aop.support.RegexpMethodPointcutAdvisor</p>
<p>二.&nbsp; oscache 主要是对页面的缓存,可以整页或者指定网页某一部分缓存,同时</p>
<p>&nbsp; 指定他的过期时间,这样在此时间段里面访问的数据都是一样的</p>
<p>1.log4j-1.2.8.jar,oscache-2.3.2.jar,commons-logging.jar,jgroups-all.jar</p>
<p>2.拷贝cach\etc\下的oscache.tld,oscache.properties 到WEB-INF\</p>
<p>3.web.xml</p>
<p>&nbsp;&lt;taglib&gt;&lt;taglib-uri&gt;oscache&lt;/taglib-uri&gt;&lt;taglib-location&gt;/WEB-INF/classes/ oscache.tld&lt;/taglib-location&gt;&lt;/taglib&gt; <br />
&nbsp;&nbsp; &lt;filter&gt;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp; &lt;filter-name&gt;CacheFilter&lt;/filter-name&gt;<br />
&nbsp;&nbsp; &lt;filter-class&gt;com.opensymphony.oscache.web.filter.CacheFilter&lt;/filter-class&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;time&lt;/param-name&gt;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;60&lt;/param-value&gt;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/init-param&gt;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;init-param&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;scope&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;session&lt;/param-value&gt;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/init-param&gt;<br />
<br />
&nbsp;&nbsp; &lt;/filter&gt;<br />
&lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;CacheFilter&lt;/filter-name&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/*.jsp&lt;/url-pattern&gt;<br />
&lt;/filter-mapping&gt;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>可以使用内存、硬盘空间、同时使用内存和硬盘或者提供自己的其他资源（需要自己提供适配器）作为缓存区。</p>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/142130#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 20 Nov 2007 18:04:26 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/142130</link>
        <guid>http://tantengfei.javaeye.com/blog/142130</guid>
      </item>
      <item>
        <title>彻底清除IE收藏夹无法删除网页链接</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/134480" style="color:red;">http://tantengfei.javaeye.com/blog/134480</a>&nbsp;
          发表时间: 2007年10月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="tit">彻底清除IE收藏夹无法删除网页链接</div>
<div class="date">2007-09-16 13:01:14</div>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt">
            <p>在注册表中清理Internet Explorer文件夹！</p>
            <p>下面提供解决方法：<br />
            点击&ldquo;开始&rdquo;&mdash;&mdash;&ldquo;运行&rdquo;&mdash;&mdash;&ldquo;regedit&rdquo;将如下东西：<br />
            HKEY_CURRENT_USER\software\microsoft\Internet Explorer\Extensions<br />
            HKEY_CURRENT_USER\software\microsoft\Internet Explorer\Extensions\CmdMapping<br />
            找到后把这两个里面所有形如{xxxxxxxx...}的东西全部删除。只要留&ldquo;默认&rdquo;和&ldquo;NextId&rdquo;就可以了。</p>
            <p>最后在浏览器中把那些你不想要的混蛋网址删了。搞定~</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/134480#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 22 Oct 2007 16:26:19 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/134480</link>
        <guid>http://tantengfei.javaeye.com/blog/134480</guid>
      </item>
      <item>
        <title>ORM性能比iBATIS好</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/133547" style="color:red;">http://tantengfei.javaeye.com/blog/133547</a>&nbsp;
          发表时间: 2007年10月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div style="MARGIN-TOP: 1px; MARGIN-LEFT: 15px"><font face="Arial">为什么ORM性能比iBATIS好?</font></div>
<div style="MARGIN-TOP: 10px; MARGIN-LEFT: 15px; OVERFLOW: auto">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>缓存是有很多层次的，有web server前端缓存，有动态页面静态化，有页面片断缓存，有查询缓存，也有对象缓存。不同层面的缓存适用于不同的应用场景，作用也各自不同，如果可以，你全部一起用上，他们不矛盾，但这个话题比较大，现在不展开谈。</p>
            <p>针对OLTP类型的web应用，只要代码写的质量没有问题，最终的性能瓶颈毫无疑问还是数据库查询。应用服务器层面可以水平扩展，但是数据库是单点的，很难水平扩展，所以如何有效降低数据库查询频率，减轻数据库压力，是web应用性能问题的根源。</p>
            <p>以上所有的缓存方式都可以直接或者间接的降低数据库访问，但缓存是有应用场景的，虽然新闻网站非常适合使用动态页面静态化技术，但是例如电子商务网站就不适合动态页面静态化，而页面缓存和查询缓存可以使用的场景也不多。但是对象缓存是所有缓存技术当中适用场景最广泛的，任何OLTP应用，即使实时性要求很高，你也可以使用对象缓存，而且好的ORM实现，对象缓存是完全透明的，不需要你的程序代码进行硬编码。</p>
            <p>用不用对象缓存，怎么用对象缓存，不是一个调优的技巧问题，而是整个应用的架构问题。在你开发一个应用之前，你就要想清楚，这个应用最终的场景是什么？会有多大的用户量和数据量。你将采用什么方式来架构这个应用：</p>
            <p>OK，也许你偏爱SQL，那么你选择iBATIS，数据库设计当中大表有很多冗余字段，会尽量消除大表之间的关联关系，最终用户量和访问量很高以后，你会选择使用Oracle，雇佣资深的DBA，进行数据库调优和SQL调优，这是大多数公司走的路。</p>
            <p>但是我告诉你，你还有另外一条路可以走。你可以选择ORM(不见得一定是Hibernate)，数据库设计当中避免出现大表，比较多的表关联关系，通过ORM以对象化方式操作。当用户量和访问量很高以后，除了数据库端本身的优化，你还有对象缓存这条途径。对象缓存是怎样提高性能的呢？随便举个例子：</p>
            <p>论坛的列表页面，需要显示topic的分页列表，topic作者的名字，topic最后回复帖子的作者，如果是iBATIS，你准备怎么做？</p>
            <p>&nbsp;</p>
            <div class="code_title">sql 代码</div>
            <div class="code_div">
            <div class="dp-highlighter">
            <div class="bar"></div>
            <ol class="dp-sql">
                <li class="alt"><span><span class="keyword">select</span><span>&nbsp;...&nbsp;</span><span class="keyword">from</span><span>&nbsp;topic&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;</span><span class="func">user</span><span>&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;post&nbsp;.....&nbsp;&nbsp;</span></span></li>
            </ol>
            </div>
            </div>
            <script>render_code();</script>
            <p>&nbsp;</p>
            <p>你需要通过join user表来取得topic作者的名字，然后你还需要join post表取得最后回复的帖子，post再join user表取得最后回贴作者名字。</p>
            <p>也许你说，我可以设计表冗余，在topic里面增加username，在post里面增加username，所以通过大表冗余字段，消除了复杂的表关联：</p>
            <p>&nbsp;</p>
            <div class="code_title">sql 代码</div>
            <div class="code_div">
            <div class="dp-highlighter">
            <div class="bar"></div>
            <ol class="dp-sql">
                <li class="alt"><span><span class="keyword">select</span><span>&nbsp;...&nbsp;</span><span class="keyword">from</span><span>&nbsp;topic&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;post...&nbsp;&nbsp;</span></span></li>
            </ol>
            </div>
            </div>
            <script>render_code();</script>
            <p>&nbsp;</p>
            <p>OK，且不说冗余字段的维护问题，现在仍然是两张大表的关联查询。然后让我们看看ORM怎么做？</p>
            <p>&nbsp;</p>
            <div class="code_title">sql 代码</div>
            <div class="code_div">
            <div class="dp-highlighter">
            <div class="bar"></div>
            <ol class="dp-sql">
                <li class="alt"><span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;topic&nbsp;</span><span class="keyword">where</span><span>&nbsp;...&nbsp;</span><span class="comment">--分页条件</span><span>&nbsp;&nbsp;</span></span></li>
            </ol>
            </div>
            </div>
            <script>render_code();</script>
            <p>&nbsp;</p>
            <p>就这么一条SQL搞定，比上面的关联查询对数据库的压力小多了。</p>
            <p>也许你说，不对阿，作者信息呢？回贴作者信息呢？这些难道不会发送SQL吗？如果发送SQL，这不就是臭名昭著的n+1条问题吗？</p>
            <p>你说的对，最坏情况下，会有很多条SQL： <br />
            </p>
            <div class="code_title">sql 代码</div>
            <div class="code_div">
            <div class="dp-highlighter">
            <div class="bar"></div>
            <ol class="dp-sql">
                <li class="alt"><span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;</span><span class="func">user</span><span>&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;=&nbsp;topic_id...; &nbsp;&nbsp;</span></span></li>
                <li class=""><span>.... &nbsp;&nbsp;</span></li>
                <li class="alt"><span></span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;</span><span class="func">user</span><span>&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;=&nbsp;topic_id...; &nbsp;&nbsp;</span></li>
                <li class=""><span>&nbsp;&nbsp;</span></li>
                <li class="alt"><span></span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;post&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;=&nbsp;last_topic_id...; &nbsp;&nbsp;</span></li>
                <li class=""><span>.... &nbsp;&nbsp;</span></li>
                <li class="alt"><span></span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;post&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;=&nbsp;last_topic_id...; &nbsp;&nbsp;</span></li>
                <li class=""><span>&nbsp;&nbsp;</span></li>
                <li class="alt"><span></span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;</span><span class="func">user</span><span>&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;=&nbsp;post_id...; &nbsp;&nbsp;</span></li>
                <li class=""><span>.... &nbsp;&nbsp;</span></li>
                <li class="alt"><span></span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;</span><span class="func">user</span><span>&nbsp;</span><span class="keyword">where</span><span>&nbsp;id&nbsp;=&nbsp;post_id...;&nbsp;&nbsp;</span></li>
            </ol>
            </div>
            </div>
            <script>render_code();</script>
            <p>&nbsp;</p>
            <p>事实上何止n+1，根本就是3n+1条SQL了。那你怎么还说ORM性能高呢？</p>
            <p><span style="COLOR: red">因为对象缓存在起作用，你可以观察到后面的3n条SQL语句全部都是基于主键的单表查询，这3n条语句在理想状况下(比较繁忙的web网站)，全部都可以命中缓存。</span>所以事实上只有一条SQL，就是：</p>
            <p>&nbsp;</p>
            <div class="code_title">sql 代码</div>
            <div class="code_div">
            <div class="dp-highlighter">
            <div class="bar"></div>
            <ol class="dp-sql">
                <li class="alt"><span><span class="keyword">select</span><span>&nbsp;*&nbsp;</span><span class="keyword">from</span><span>&nbsp;topic&nbsp;</span><span class="keyword">where</span><span>&nbsp;...</span><span class="comment">--分页条件</span><span>&nbsp;&nbsp;</span></span></li>
            </ol>
            </div>
            </div>
            <script>render_code();</script>
            <p>&nbsp;</p>
            <p>这条单表的条件查询和iBATIS通过字段冗余简化过后的大表关联查询相比，当数据量大到一定程度以后(十几万条)，查询的速度会差至少一个数量级，而且对数据库的压力很小，这就是对象缓存的真正威力！</p>
            <p><span style="COLOR: red">更进一步分析，使用ORM，我们不考虑缓存的情况，那么就是3n+1条SQL。但是这3n+1条SQL的执行速度一定比iBATIS的大表关联查询慢吗？不一定！</span>因为使用ORM的情况下，第一条SQL是单表的条件查询，在有索引的情况下，速度很快，后面的3n条SQL都是单表的主键查询，在繁忙的数据库系统当中，3n条SQL几乎可以全部命中数据库的data buffer。但是使用iBATIS的大表关联查询，很可能会造成全表扫描，这样性能是非常差的。</p>
            <p><span style="COLOR: red">所以结论就是：即使不使用对象缓存，ORM的n+1条SQL性能仍然很有可能超过iBATIS的大表关联查询，而且对数据库造成的压力要小很多。这个结论貌似令人难以置信，但经过我的实践证明，就是事实。前提是数据量和访问量都要比较大，否则看不出来这种效果</span></p>
            <p>还是拿上面这个例子的应用场景来说，由于JavaEye网站用RoR的ActiveRecord，所以这个场景事实上就会发送3n+1条SQL语句。我从log里面看到这密密麻麻的SQL，着实非常担忧性能，所以尝试使用了find的:include选项去eager fetch，迫使ActiveRecord发送单条复杂的关联查询。但非常不幸的是，在网站服务器的production.log里面经过前后对比，发现使用:include以后，单条复杂关联查询耗时更多，数据库压力更大。</p>
            <p>在使用memcached之后，比3n+1条的性能进一步明显提升。所以性能对比就是这样的：</p>
            <p>ORM + Cache &gt; ORM n+1 &gt; iBATIS 关联查询</p>
            <p>那为什么应用Cache可以进一步提高性能，是因为访问Cache的开销比访问数据库小的得多造成的。</p>
            <p>应用程序根据主键key去Cache Server取value，是非常简单的算法，开销极小。 <br />
            而发送一条主键查询的SQL到数据库，要经过非常复杂的过程，有SQL的解析，执行计划的优化，占位符参数的代入，只读事务的保护和隔离等等，最终虽然也命中了数据库的data buffer，但是开销确实很大。</p>
            <p>BerkeleyDB就是一个极好的证明，它号称其查询速度是Oracle的1000倍，不是因为它做的比Oracle牛，而是因为它本质上就是一个大Cache，查询没有额外的开销。</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/133547#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 19 Oct 2007 23:38:35 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/133547</link>
        <guid>http://tantengfei.javaeye.com/blog/133547</guid>
      </item>
      <item>
        <title>java吐血推荐书籍</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/133545" style="color:red;">http://tantengfei.javaeye.com/blog/133545</a>&nbsp;
          发表时间: 2007年10月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="FONT-SIZE: 18pt">一、Java编程入门类</span></p>
<p>对于没有Java编程经验的程序员要入门，随便读什么入门书籍都一样，这个阶段需要你快速的掌握Java基础语法和基本用法，宗旨就是&ldquo;囫囵吞枣不求甚解&rdquo;，先对Java熟悉起来再说。用很短的时间快速过一遍Java语法，连懵带猜多写写代码，要&ldquo;知其然&rdquo;。</p>
<p>1、《Java编程思想》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1959358.jpg" border="0" alt="" /> <br />
在有了一定的Java编程经验之后，你需要&ldquo;知其所以然&rdquo;了。这个时候《Java编程思想》是一本让你知其所以然的好书，它对于基本的面向对象知识有比较清楚的交待，对Java基本语法，基本类库有比较清楚的讲解，可以帮你打一个良好的Java编程基础。这本书的缺点是实在太厚，也比较罗嗦，不适合现代人快节奏学习，因此看这本书要懂得取舍，不是每章每节都值得一看的，挑重点的深入看就可以了。</p>
<p>2、《Agile Java》中文版 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s2008093.jpg" border="0" alt="" /> <br />
这本书是出版社送给我的，我一拿到就束之高阁，放在书柜一页都没有翻过，但是前两天整理书柜的时候，拿出来一翻，竟然发现这绝对是一本好书！这本书一大特点是以单元测试和TDD来贯穿全书的，在教你Java各种重要的基础知识的过程中，潜移默化的影响你的编程思维走向敏捷，走向TDD。另外这本书成书很新，以JDK5.0的语法为基础讲解，要学习JDK5.0的新语法也不错。还有这本书对于内容取舍也非常得当，Java语言毕竟类库庞大，可以讲的内容太多，这本书选择的内容以及内容的多寡都很得当，可以让你以最少的时间掌握Java最重要的知识，顺便培养出来优秀的编程思路，真是一本不可多得的好书。</p>
<p>虽然作者自己把这本书定位在入门级别，但我不确定这本书用来入门是不是稍微深了点，我自己也准备有空的时候翻翻这本书，学习学习。</p>
<p><span style="FONT-SIZE: 18pt">二、Java编程进阶类</span></p>
<p>打下一个良好的Java基础，还需要更多的实践经验积累，我想没有什么捷径。有两本书值得你在编程生涯的这个阶段阅读，培养良好的编程习惯，提高你的代码质量。</p>
<p>1、《重构 改善既有代码的设计》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1826359.jpg" border="0" alt="" /> <br />
这本书名气很大，不用多介绍，可以在闲暇的时候多翻翻，多和自己的实践相互印证。这本书对你产生影响是潜移默化的。</p>
<p>2、《测试驱动开发 by Example》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1441607.jpg" border="0" alt="" /> <br />
本书最大特点是很薄，看起来没有什么负担。你可以找一个周末的下午，一边看，一边照做，一个下午就把书看完，这本书的所有例子跑完了。这本书的作用是通过实战让你培养TDD的思路。</p>
<p><span style="FONT-SIZE: 18pt">三、Java架构师之路</span></p>
<p>到这个阶段，你应该已经非常娴熟的运用Java编程，而且有了一个良好的编程思路和习惯了，但是你可能还缺乏对应用软件整体架构的把握，现在就是你迈向架构师的第一步。</p>
<p>1、《Expert One-on-One J2EE Design and Development》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1501574.jpg" border="0" alt="" /> <br />
这本书是Rod Johnson的成名著作，非常经典，从这本书中的代码诞生了springframework。但是好像这本书没有中译本。</p>
<p>2、《Expert One-on-One J2EE Development without EJB》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1496227.jpg" border="0" alt="" /> <br />
这本书由gigix组织翻译，多位业界专家参与，虽然署名译者是JavaEye，其实JavaEye出力不多，实在是忝居译者之名。</p>
<p>以上两本书都是Rod Johnson的经典名著，Java架构师的必读书籍。在我所推荐的这些书籍当中，是我看过的最仔细，最认真的书，我当时读这本书几乎是废寝忘食的一气读完的，有小时候挑灯夜读金庸武侠小说的劲头，书中所讲内容和自己的经验知识一一印证，又被无比精辟的总结出来，读完这本书以后，我有种被打通经脉，功力爆增的感觉。</p>
<p>但是后来我看过一些其他人的评价，似乎阅读体验并没有我那么high，也许是因为每个人的知识积累和经验不同导致的。我那个时候刚好是经验知识积累已经足够丰富，但是还没有系统的整理成型，让这本书一梳理，立刻形成完整的知识体系了。</p>
<p>3、《企业应用架构模式》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1607804.jpg" border="0" alt="" /> <br />
Martin的又一本名著，但这本书我只是泛泛的看了一遍，并没有仔细看。这本书似乎更适合做框架的人去看，例如如果你打算自己写一个ORM的话，这本书是一定要看的。但是做应用的人，不看貌似也无所谓，但是如果有空，我还是推荐认真看看，会让你知道框架为什么要这样设计，这样你的层次可以晋升到框架设计者的角度去思考问题。Martin的书我向来都是推崇，但是从来都没有像Rod Johnson的书那样非常认真去看。</p>
<p>4、《敏捷软件开发 原则、模式与实践》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1671095.jpg" border="0" alt="" /> <br />
Uncle Bob的名著，敏捷的经典名著，这本书比较特别，与其说是讲软件开发过程的书，不如说讲软件架构的书，本书用了很大篇幅讲各种面向对象软件开发的各种模式，个人以为看了这本书，就不必看GoF的《设计模式》了。</p>
<p><span style="FONT-SIZE: 18pt">四、软件开发过程</span></p>
<p>了解软件开发过程不单纯是提高程序员个人的良好编程习惯，也是增强团队协作的基础。</p>
<p>1、《UML精粹》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1648691.jpg" border="0" alt="" /> <br />
UML其实和软件开发过程没有什么必然联系，却是软件团队协作沟通，撰写软件文档需要的工具。但是UML真正实用的图不多，看看这本书已经足够了，完全没有必要去啃《UML用户指南》之类的东西。要提醒大家的是，这本书的中译本翻译的非常之烂，建议有条件的看英文原版。</p>
<p>2、《解析极限编程 拥抱变化》XP <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s2008432.jpg" border="0" alt="" /> <br />
这是Kent Beck名著的第二版，中英文对照。没什么好说的，必读书籍。</p>
<p>3、《统一软件开发过程》UP <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1843342.jpg" border="0" alt="" /> <br />
其实UP和敏捷并不一定冲突，UP也非常强调迭代，测试，但是UP强调的文档和过程驱动却是敏捷所不取的。不管怎么说，UP值得你去读，毕竟在中国真正接受敏捷的企业很少，你还是需要用UP来武装一下自己的，哪怕是披着UP的XP。</p>
<p>4、《敏捷建模》AM <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1264986.jpg" border="0" alt="" /> <br />
Scott Ambler的名著，这本书非常的progmatic，告诉你怎么既敏捷又UP，把敏捷和UP统一起来了，又提出了很多progmatic的建议和做法。你可以把《解析极限编程 拥抱变化》、《统一软件开发过程》和《敏捷建模》这三本书放在一起读，看XP和UP的不同点，再看AM是怎么统一XP和UP的，把这三种理论融为一炉，形成自己的理论体系，那么你也可以去写书了。</p>
<p><span style="FONT-SIZE: 18pt">五、软件项目管理</span></p>
<p>如果你突然被领导提拔为项目经理，而你完全没有项目管理经验，你肯定会心里没底；如果你觉得自己管理项目不善，很想改善你的项目管理能力，那么去考PMP肯定是远水不解近渴的。</p>
<p>1、《快速软件开发》 <br />
<img src="mhtml:file://E:\My Documents\MYWORK\study\Java程序员的推荐阅读书籍--海阔天空 -JavaEye做最棒的软件开发交流社区.mht!http://www.douban.com/lpic/s1696681.jpg" border="0" alt="" /> <br />
这也是一本名著。可以这样说，有本书在手，你就有了一个项目管理的高级参谋给你出谋划策，再也不必担心自己不能胜任的问题了。这本书不是讲管理的理论的，在实际的项目管理中，讲这些理论是不解决问题的，这本书有点类似于&ldquo;软件项目点子大全&rdquo;之类的东西，列举了种种软件项目当中面临的各种问题，以及应该如何解决问题的点子，你只需要稍加变通，找方抓药就行了。</p>
<p><span style="FONT-SIZE: 18pt">六、总结</span></p>
<p>在这份推荐阅读书籍的名单中，我没有列举流行的软件框架类学习书籍，例如Struts，Hibernate，Spring之类，也没有列举AJAX方面的书籍。是因为这类书籍容易过时，而上述的大半书籍的生命周期都足够长，值得你去购买和收藏。</p>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/133545#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 19 Oct 2007 23:35:45 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/133545</link>
        <guid>http://tantengfei.javaeye.com/blog/133545</guid>
      </item>
      <item>
        <title>java鄙见</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/133544" style="color:red;">http://tantengfei.javaeye.com/blog/133544</a>&nbsp;
          发表时间: 2007年10月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span class="tpc_content">JAVA配置环境变量<br />
在下载并安装完JDK之后，如果系统已安装Oracle，请务必将系统PATH里Oracle的c:\Oracle\jre\1.3.1\bin去掉，否则启动JAVA报错<br />
新建以下变量名和值: <br />
变量名:JAVA_HOME <br />
变量值:D:\JDK;<br />
<br />
变量名:path <br />
变量值:%JAVA_HOME%\bin;<br />
<br />
变量名:CLASSPATH <br />
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;<br />
<br />
字符窜比较<br />
String 是个对象，要对比两个不同的String对象的值是否相同要用到 equals() 这个方法. 而== 比较的是内存地址的值(我自己的感觉)<br />
String str1 = new String(&quot;abc&quot;);<br />
String str2 = new String(&quot;abc&quot;);<br />
System.out.println(str1 == str2); //false<br />
System.out.println(str1.equals(str2)); //true<br />
<br />
Java使用三个修饰符关键字： <br />
public 任何人都是可用 <br />
private 在自己的类和该类型的内部方法之外谁都不能碰 <br />
protected 它与private作用相当，只是多了让继承类可以访问<br />
<br />
数据成员可以分静态变量、非静态变量两种. <br />
静态成员：静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员.<br />
<br />
非成静态员：所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中..<br />
<br />
<br />
JAVA整型数<br />
byte largestByte = Byte.MAX_VALUE;<br />
short largestShort = Short.MAX_VALUE;<br />
int largestInteger = Integer.MAX_VALUE;<br />
JAVA实型数<br />
float largestFloat = Float.MAX_VALUE;<br />
double largestDouble = Double.MAX_VALUE;<br />
字符型和布尔型等等<br />
char aChar = 'S';<br />
boolean aBoolean = true;<br />
<br />
各个数据类型的最大值<br />
The largest byte value is 127<br />
The largest short value is 32767<br />
The largest integer value is 2147483647<br />
The largest long value is 9223372036854775807<br />
The largest float value is 3.40282e+38<br />
The largest double value is 1.79769e+308<br />
<br />
<br />
各种数据类型之间的转换<br />
1. 由各种数据类型转换成 String <br />
String 类别中已经提供了将基本资料型态转换成 String 的 static 方法 <br />
也就是 String.valueOf() 这个参数多载的方法 <br />
有下列几种 <br />
String.valueOf(boolean b) : 将 boolean 变量 b 转换成字符串 <br />
String.valueOf(char c) : 将 char 变量 c 转换成字符串 <br />
String.valueOf(char[] data) : 将 char 数组 data 转换成字符串 <br />
String.valueOf(char[] data, int offset, int count) : <br />
将 char 数组 data 中 由 data[offset] 开始取 count 个元素 转换成字符串 <br />
String.valueOf(double d) : 将 double 变量 d 转换成字符串 <br />
String.valueOf(float f) : 将 float 变量 f 转换成字符串 <br />
String.valueOf(int i) : 将 int 变量 i 转换成字符串 <br />
String.valueOf(long l) : 将 long 变量 l 转换成字符串 <br />
String.valueOf(Object obj) : 将 obj 对象转换成 字符串, 等于 obj.toString() <br />
用法如: <br />
int i = 10; <br />
String str = String.valueOf(i); <br />
这时候 str 就会是 &quot;10&quot; <br />
2. 由 String 转换成 数字类型<br />
要将 String 转换成其他类型 大多需要使用各基本资料型态的包装类别 <br />
比如说 String 转换成 byte <br />
可以使用 Byte.parseByte(String s) <br />
这一类的方法如果无法将 s 分析 则会丢出 NumberFormatException <br />
byte : <br />
Byte.parseByte(String s) : 将 s 转换成 byte <br />
Byte.parseByte(String s, int radix) : 以 radix 为基底 将 s 转换为 byte <br />
比如说 Byte.parseByte(&quot;11&quot;, 16) 会得到 17 <br />
double : <br />
Double.parseDouble(String s) : 将 s 转换成 double <br />
float : <br />
Double.parseFloat(String s) : 将 s 转换成 float <br />
int : <br />
Integer.parseInt(String s) : 将 s 转换成 int <br />
long : <br />
Long.parseLong(String s) : 将 s 转换成 long<br />
<br />
异常处理语句<br />
try {<br />
语句（参数）<br />
} catch (异常错误类型 名字) {<br />
语句（参数）<br />
} finally {<br />
语句（参数）<br />
}<br />
<br />
分支语句<br />
break语句<br />
未标志形式的break语句被用来终止内部的switch、for、while或者do-while。而标志形式的break语句终止一个外部的语句，它是通过在break语句中使用一个标志来实现的<br />
continue语句<br />
public static void main(String[] args) {<br />
String searchMe = &quot;Look for a substring in me&quot;;<br />
String substring = &quot;sub&quot;;<br />
boolean foundIt = false;<br />
int max = searchMe.length() - substring.length();<br />
test:<br />
for (int i = 0; i &lt;= max; i++) {<br />
&nbsp; int n = substring.length();<br />
&nbsp; int j = i;<br />
&nbsp; int k = 0;<br />
&nbsp; while (n-- != 0) {<br />
&nbsp; if (searchMe.charAt(j++) != substring.charAt(k++)) {<br />
&nbsp; continue test;<br />
&nbsp; }<br />
&nbsp; }<br />
&nbsp; foundIt = true;<br />
&nbsp; break test;<br />
}<br />
System.out.println(foundIt ? &quot;Found it&quot; : &quot;Didn't find it&quot;);<br />
}<br />
<br />
return语句 <br />
你可以使用return 来退出当前的方法。控制流程返回到调用方法的下一个语句。这个return语句有两种形式：一种是返回一个数值，另外一种没有返回数值。为了返回一个数值，简单地，可以将数值放置在return关键字后面即可。<br />
<br />
while语句<br />
　　你可以使用while语句当条件保持为true的时候，持续执行语句块。While语句的通常语法为： <br />
while (expression) {<br />
statement<br />
}<br />
　　首先，while语句执行表达式，它将返回一个boolean数（true或者false）。如果表达式返回true，while语句执行相应的语句。While语句继续测试表达式并执行块代码直到表达式返回false。<br />
<br />
do-while语句<br />
　　JAVA编程语言提供了另外一个语句，它跟while语句和相似，即do-while语句。Do-while的语法为： <br />
do {<br />
statement(s)<br />
} while (expression);<br />
　　不象while语句，do-while语句是先执行循环中的语句后再计算表达式的，所以do-while语句就至少执行一次语句。<br />
<br />
for语句<br />
　　for语句提供了一个简便的方法来进行循环。For语句的语法如下：<br />
for (初始条件;终止条件;增量) {<br />
语句<br />
}<br />
　　初始条件是初始化循环的表达式，它在循环开始的时候就被执行一次。而终止条件决定什么时候终止循环。这个表达式在每次循环的过程都被计算。当表达式计算结果为false的时候，这个循环结束。最后,增量是循环一次增加多少（即步长）的表达式。所有的这些都是可选的。实际上，为了实现无限制的循环，这三个表达式都可以省略。 <br />
for ( ; ; ) { // 无限制的循环<br />
...<br />
}<br />
<br />
if-else语句<br />
　　如果if部分为false，则执行else块。另外一种else语句的格式是else if，它根据执行另外的表达式执行语句。一个if语句可以跟着任意个else if语句，但只能有一个else语句。<br />
if (表达式) {<br />
语句（参数）<br />
}<br />
<br />
switch语句<br />
使用switch语句可以根据一个整型表达式有条件地执行语句。<br />
int month = 8;<br />
. . .<br />
switch (month) {<br />
case 1: System.out.println(&quot;January&quot;); break;<br />
case 2: System.out.println(&quot;February&quot;); break;<br />
case 3: System.out.println(&quot;March&quot;); break;<br />
case 4: System.out.println(&quot;April&quot;); break;<br />
case 5: System.out.println(&quot;May&quot;); break;<br />
case 6: System.out.println(&quot;June&quot;); break;<br />
case 7: System.out.println(&quot;July&quot;); break;<br />
case 8: System.out.println(&quot;August&quot;); break;<br />
case 9: System.out.println(&quot;September&quot;); break;<br />
case 10: System.out.println(&quot;October&quot;); break;<br />
case 11: System.out.println(&quot;November&quot;); break;<br />
case 12: System.out.println(&quot;December&quot;); break;<br />
default: System.out.println(&quot;Hey, that's not a valid month!&quot;); break;<br />
}<br />
<br />
JAVA获取上M的HTTP数据流时的正确读取法<br />
ServletInputStream inStream = request.getInputStream(); //取HTTP请求流<br />
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();<br />
byte[] buff = new byte[8192]; //buff用于存放循环读取的临时数据<br />
int rc = 0;<br />
while ((rc = inStream.read(buff, 0, 1024)) &gt; 0) {<br />
&nbsp; swapStream.write(buff, 0, rc);<br />
}<br />
byte[] in_b = swapStream.toByteArray(); //in_b为转换之后的结果 <br />
Payload = new String(in_b); //将接受到的数据转换成String<br />
<br />
为减少数据库读取和防止并发，由JAVA应用直接生成表主键<br />
GenGUID GenGUID = new GenGUID();<br />
String XMLDATAId = GenGUID.GetGUID();<br />
<br />
在Oracle数据库中插入CLOB字段的JAVA代码实例<br />
conn.setAutoCommit(false);<br />
/* 插入一个空的CLOB对象 */<br />
String sql = &quot;insert into TB_CLOB (SID,CLOBDATA) values( '&quot;<br />
+ CLOBDATAId + &quot;',EMPTY_CLOB())&quot;;<br />
opst=(oracle.jdbc.driver.OraclePreparedStatement)conn.prepareStatement(sql);<br />
opst.executeUpdate();<br />
opst.clearParameters();<br />
/* 查询此CLOB对象并锁定 */<br />
sql = &quot;select CLOBDATA from TB_CLOB where &quot; + &quot; SID='&quot;<br />
+ CLOBDATAId + &quot;' FOR update&quot;;<br />
// System.out.println(&quot;start select^^^^^&quot; + sql);<br />
opst=(oracle.jdbc.driver.OraclePreparedStatement)conn.prepareStatement(sql);<br />
ors=(oracle.jdbc.OracleResultSet)opst.executeQuery();<br />
while (ors.next()) {<br />
/* 取出此CLOB对象 */<br />
// System.out.println(&quot;start getout clob^^^^^&quot;);<br />
oracle.sql.CLOB clob = (oracle.sql.CLOB) ors.getClob(&quot;CLOBDATA&quot;);<br />
/* 向CLOB对象中写入数据 */<br />
// System.out.println(&quot;start writer clob^^^^^&quot;);<br />
clob.putString(1, input);<br />
PreparedStatement stmt2 = conn<br />
.prepareStatement(&quot;update TB_CLOB set CLOBDATA = ? where&quot;<br />
+ &quot; SID='&quot; + CLOBDATAId + &quot;'&quot;);<br />
stmt2.setClob(1, clob);<br />
stmt2.executeUpdate();<br />
}<br />
conn.commit();<br />
<br />
<br />
取得Oracle数据库返回数据类型是XMLDATA的JAVA代码实例<br />
Connection conn = ORACLEConnect.getConnection();<br />
//Call function(不是PROC) <br />
String SQLTEXT = &quot;{? = call nspGetXMLDATA()}&quot;;<br />
OracleCallableStatement stmt = (OracleCallableStatement)conn.prepareCall(SQLTEXT);<br />
//注册参数 类型是XMLDATA<br />
stmt.registerOutParameter (1, OracleTypes.OPAQUE,&quot;SYS.XMLTYPE&quot;);<br />
stmt.execute();<br />
//得到返回的长度<br />
XMLType XML = XMLType.createXML(stmt.getOPAQUE(1));<br />
returnstr = ((XMLType)XML).getStringVal();<br />
stmt.close();<br />
conn.close();<br />
<br />
将字符窜写入文本<br />
String impstring = &quot;ok&quot;; //需要写入的内容<br />
String tmpstring = null; //临时变量<br />
PrintWriter outfile = new PrintWriter(new BufferedWriter(<br />
new FileWriter(&quot;C:/log.txt&quot;, true)));<br />
//每次写入日志前记录插入的时间<br />
Calendar c=Calendar.getInstance(); <br />
outfile.println(c.get(Calendar.YEAR)+&quot;年&quot;+c.get(Calendar.MONTH)+1+&quot;月&quot;+c.get(Calendar.DAY_OF_MONTH)+&quot;日&quot;+c.get(Calendar.HOUR_OF_DAY)+&quot;时&quot;+c.get(Calendar.MINUTE)+&quot;分&quot;+c.get(Calendar.SECOND)+&quot;秒&quot;); <br />
BufferedReader Readerin = new BufferedReader(new StringReader(_s));<br />
while ((s = Readerin.readLine()) != null) {<br />
outfile.println(s);<br />
}</span><br />
<!----></p>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/133544#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 19 Oct 2007 23:33:19 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/133544</link>
        <guid>http://tantengfei.javaeye.com/blog/133544</guid>
      </item>
      <item>
        <title>EJB新特性</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/133543" style="color:red;">http://tantengfei.javaeye.com/blog/133543</a>&nbsp;
          发表时间: 2007年10月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <font face="Arial">1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一套以注释为基础的EJB编程模型，再加上EJB2.1中定义的通过部署描述符和几个接口定义的应用程序行为。<br />
<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新的实体Bean持久化模型，EJBQL也有许多重要的改变。<br />
<br />
还有一些有关上述的提议，比如：一个新的客户端编程模型，业务接口的使用以及实体Bean的生命周期。请注意EJB2.1编程模型（包括部署描述符和home/remote接口）仍然是有效的。新的简化模型并没有完全取代EJB2.1模型。<br />
<br />
EJB注释<br />
<br />
EJB规范组织一个重要的目标是减轻原始代码的数量，并且他们为此给出了一个完美而简介的办法。在EJB3.0的里，任何类型的企业级Bean只是一个加了适当注释的简单Java对象(POJO)。注释可以用于定义bean的业务接口、O/R映射信息、资源引用信息，效果与在EJB2.1中定义部署描述符和接口是一样的。在EJB3.0中部署描述符不再是必须的了；home接口也没有了，你也不必实现业务接口（容器可以为你完成这些事情）。<br />
<br />
比如，你可以使用@Stateless注释标记类把Java类声明为一个无状态回话bean。对于有状态回话bean来说，@Remove注释可以用来标记一个特定的方法，通过这个注释来说明在调用这个方法之后bean的实例将被清除掉。<br />
<br />
为了减少描述组件的说明信息，规范组织还采纳了由异常进行配置（configuration-by-exception）的手段，意思是你可以为所有的注释提供一个明确的缺省值，这样多数常规信息就可以据此推断得出。<br />
<br />
新的持久化模型<br />
<br />
新的实体bean也是一个加了注释的简单Java对象(POJO)。一旦它被EntityManager访问它就成为了一个持久化对象，并且成为了持久化上下文（context）的一部分。一个持久化上下文与一个事务上下文是松耦合的；严格的讲，它隐含的与一个事务会话共存。<br />
<br />
实体关系也是通过注释来定义的，O/R映射也是，并提供几种不同的数据库规范操作，在EJB2.1中这些要通过开发人员自己的设计模式或者其它技术来完成的（比如，自增长主键策略）。<br />
<br />
深入研究<br />
<br />
现在是时候详细了解EJB3.0草案了。让我们开始探讨所有EJB中四种企业级bean，并看看他们在新的规范中是什么样子。<br />
<br />
无状态回话bean<br />
<br />
在EJB3.0规范中，写一个无状态回话bean(SLSB)只需要一个简单的Java文件并在类层加上@Stateless注释就可以了。这个bean可以扩展javax.ejb.SessionBean接口，但这些不是必须的。<br />
<br />
一个SLSB不再需要home接口，没有哪类EJB再需要它了。Bean类可以实现业务接口也可以不实现它。如果没有实现任何业务接口，业务接口会由任意public的方法产生。如果只有几个业务方法会被暴露在业务接口中，这些方法可以使用@BusinessMethod注释。缺省情况下所有产生的接口都是local（本地）接口，你也可以使用@Remote注释来声明这个接口为remote（远程）接口。<br />
<br />
下面的几行代码就可以定义一个HelloWorldbean了。而在EJB2.1中同样的bean至少需要两个接口，一个实现类和几个空的实现方法，再加上部署描述符。<br />
<br />
import javax.ejb.*;<br />
<br />
/**<br />
* A stateless session bean requesting that a remote business<br />
* interface be generated for it.<br />
*/<br />
@Stateless<br />
@Remote<br />
public class HelloWorldBean {<br />
&nbsp;&nbsp; public String sayHello() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &quot;Hello World!!!&quot;;<br />
&nbsp;&nbsp; }<br />
}<br />
<br />
有状态回话bean<br />
<br />
除了几个SFSB的特别说明之外，有状态回话bean(SFSB)和SLSB一样精简：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;一个SFSB应该有一个方法来初始化自己（在EJB2.1中是通过ejbCreate()来实现的）。在EJB3.0的规范中建议这些初始化操作可以通过自定义方法完成，并把他们暴露在业务接口中。在使用这个bean之前由客户端来调用相应的初始化方法。目前规范组织就是否提供一个注释来标记某个方法用于初始化还存在争议。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bean的提供者可以用@Remove注释来标记任何SFSB的方法，以说明这个方法被调用之后bean的实例将被移除。同样，规范组织仍然在讨论是否要有一种机制来处理这种特殊的情况，即当这个方法出现异常的情况下bean的实例是否被移除。<br />
<br />
下面是对以上问题我个人的观点：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 是否应该有一个注释来标明一个方法进行初始化呢？我的观点是――应该有，这样容器就可以在调用其他方法之前至少调用一个方法来进行初始化。这不仅可以避免不必要的错误(由于没有调用初始化方法)而且可以使容器更明确的判断是否可以重用SFSB实例。我暂且把这个问题放一放，规范组织只考虑为一个方法提供一个注释来声明它是一个初始化方法。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于第二个问题我的观点也是肯定的。这有利于Bean的提供者合客户端程序对其进行控制。只有一个遗留的问题：那就是一旦调用这个方法失败，是否能移除这个bean 的实例？答案是不能，但是它将会在回话结束的时候被移除。<br />
<br />
消息驱动Bean<br />
<br />
消息驱动Bean是唯一一种必须实现一个业务接口的Bean。这个接口指出bean支持的是哪一种消息系统。对于以JMS为基础的MDB来说，这个接口是javax.jms.MessageListener。注意MDB业务接口不是一个真正意义上的业务接口，它只是一个消息接口。<br />
<br />
实体Bean<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实体Bean使用@Entity注释来标记，所有实体bean中的属性/字段不必使用@Transient注释来标记。实体bean的持久化字段可以通过JavaBean-style机制或者声明为public/protected字段来实现。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实体bean可以使用助手类来描述其状态，但是这些类的实例并没有持久化唯一性（persistent identity）的特性(即，唯一标识这个bean的字段等)，实际上这些助手类与他们的实体bean实例是紧密结合的；并且这些对象还是以非共享方式来访问实体对象的。<br />
<br />
实体关联<br />
<br />
EJB3.0同时支持Bean之间双向的合单向的关联，它们可以是一对一、一对多、多对一或者是多对多的关联。然而双向关联的两端还要分为自身端（owning side）和对方端（inverse side）不同的端。自身端负责向数据库通告关联的变更。对于多对多的关联自身端必须明确的声明。实际上对方端通过isInverse=true进行注释（由此自身端就不必说明了而是由另一段推断出）。看来上面的描述，规范组织还能说让EJB变的简单了吗？<br />
<br />
O/R映射<br />
<br />
EJB3.0中的O/R映射模型也有了重要的改变，它从原来的abstract-persistence-schema-based变成了现在的Hibernate-inspired模式。尽管目前规范组织还在就此进行讨论但是一个明确的模型将会出现在下一个版本的草案中。<br />
<br />
举例来说，O/R映射模型将通过bean类中的注释来声明。而且此方法还会指出对应的具体表和字段。O/R映射模型提供了一套自有的SQL；而且除了提供一些基本的SQL外还支持某些高层开发的功能。比如，有一个通过@Column注释声明的字段columnDefinition，那么可以写这样的SQL：columnDefinition=&quot;BLOB NOT NULL&quot;<br />
<br />
客户端程序模型<br />
<br />
一个EJB客户端可以通过@Inject注释以一种&ldquo;注入&rdquo;的方式获得一个bean的业务接口引用。你也可以使用另一个注释@javax.ejb.EJBContext.lookup()来完成上面的操作，但是规范中没有告诉我们一个普通的Java客户端怎样获得一个Bean的实例，因为这个普通的Java客户端是运行在一个客户端容器中，它无法访问@javax.ejb.EJBContex对象。现在还有另外一种机制来完成上面的工作那就是使用一个超级上下文环境对象：@javax.ejb.Context()。但是规范中没有指出该如何在客户端中使用这个对象。<br />
<br />
EJB QL<br />
<br />
EJB QL可以通过@NamedQuery来注释。这个注释有两个成员属性分别是name和queryString.一旦定义了这些属性，就可以通过EntityManager.createNamedQuery(name)来指向这个查询。你也可以创建一个标准的JDBC风格的查询并使用EntityManager.createQuery(ejbqlString)或EntityManager.createNativeQuery(nativeSqlString)(这个方法用于执行一个本地查询)来执行查询。<br />
<br />
EJB QL有两个地方可以定义其参数。javax.ejb.Query接口提供了定义参数、指向查询、更新数据等等方法。下面是一个EJBQL指向查询的例子：<br />
<br />
.. ..<br />
@NamedQuery(<br />
name=&quot;findAllCustomersWithName&quot;,<br />
queryString=&quot;SELECT c FROM Customer c WHERE c.name LIKE :custName&quot;<br />
)<br />
.. ..<br />
@Inject public EntityManager em;<br />
customers = em.createNamedQuery(&quot;findAllCustomersWithName&quot;)<br />
.setParameter(&quot;custName&quot;, &quot;Smith&quot;)<br />
.listResults();<br />
<br />
下面列出了一些EJB QL的增强特性：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持批量更新和删除。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 直接支持内连接和外连接。FETCH JOIN运行你指出关联的实体，Order可以指定只查询某个字段。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查询语句可以返回一个以上的结果值。实际上，你可以返回一个依赖的类比如下面这样：SELECT new CustomerDetails(c.id, c.status, o.count)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM Customer c JOIN c.orders o<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WHERE o.count &gt; 100<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持group by 和having。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持where子句的嵌套子查询。<br />
<br />
在提交的EJB3.0草案中，EJB QL与标准SQL非常的接近。实际上规范中甚至直接支持本地的SQL(就像我们上面提到的那样)。这一点对某些程序员来说也许有些不是很清楚，我们将在下面进行更详细的讲解。<br />
<br />
多样性<br />
<br />
方法许可(Method permissions)可以通过@MethodPermissions或@Unchecked注释来声明；同样的，事务属性也可以通过@TransactionAttribute注释来声明。规范中仍然保留资源引用和资源环境引用。这些一样可以通过注释来声明，但是有一些细微的差别。比如，上下文(context)环境要通过注入工具控制。容器根据bean对外部环境引用自动初始化一个适当的已经声明的实例变量。比如，你可以象下面这样获得一个数据源（DataSource）：<br />
<br />
@Resource(name=&quot;myDataSource&quot;) //Type is inferred from variable<br />
public DataSource customerDB;<br />
<br />
在上面的例子中如果你不指定引用资源的名称(name)那么其中的customerDB会被认为是默认值。当所有的引用属性都可得到时，@Injec注释就可以这样写：<br />
<br />
@Inject public DataSource customerDB;<br />
<br />
容器负责在运行时初始化customerDB数据源实例。部署人员必须在此之前在容器中定义好这些资源属性。<br />
<br />
更好的消息是：那些以前必须检测的异常将一去不复返。你可以声明任意的应用程序异常，而不必在再抛出或捕获其他类似CreateException和FinderException这样的异常。容器会抛出封装在javax.ejb.EJBException中的系统级异常或者只在必要时候抛出IllegalArgumentException或IllegalStateException异常。<br />
<br />
EJB文件处理模式<br />
<br />
在我们结束本节之前，让我的快速的浏览一下容器提供商在EJB处理模式方面可能的变更。规范中对此并没有明确的表态，但我可以想到至少两种模式。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一种办法是首先利用EJB文件生成类似于EJB2.1部署模式的文件（包括必要的接口和部署描述符）然后再用类似于EJB2.1的方式来部署这个EJB组件。当然，这样产生的部署描述符可能并不标准但是它可以解决同一个容器对EJB2.1和EJB3.0兼容的问题。下面这幅图描述了这一过程。<br />
<strong><u>IMG</u></strong> /Java/UploadFiles_6889/200705/20070512001921964.jpg[/IMG]<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另一种方法是一种类似于JSP托放的部署模式。你可以把一个EJB文件放到一个预先定义的目录下，然后容器会识别这个EJB并处理它，然后部署并使之可以使用。这种方法可以建立于上面那种方法之上，在支持反复部署时有很大的帮助。考虑到部署的简单性也是EJB3.0规范的目的之一，我真诚的希望在下一个草案出来时能够确定一个模式(至少能有一个非正式的)。<br />
<br />
你有什么想法？<br />
<br />
EJB3.0规范的制定正在有序的进行，为了使EJB的开发变得更加容易，EJB规范组织作出的努力是有目共睹的。就像他们说的那样，一切对会变得简单，但做到这一点并不容易。目前已经定义了50个注释标记(还有几个将在下一个草案中发布)，每一个都有自己的缺省规则和其他的操作。当然，我真的不希望EJB3.0变成EJB2.1的一个翻版&quot;EJB 3.0 = EJB 2.1 for dummies&quot;（希望这个等式不要成立）。最后，我还是忍不住要提一些我自己的观点：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先，规范确实使反复部署变得容易了，并且有一个简单的模式来访问运行时环境。我还是觉得home接口应该放弃。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在早期的EJB规范中，实体bean用于映射一个持久化存储。理论上(也许只是理论上)可能需要把实体bean映射到一个遗留的EIS(enterprise information system)系统中。出于将来扩展的考虑这样作是有好处的，并且可以使更多的业务数据模型采用实体bean。也因此其伴随的复杂性使得实体bean不被看好。在本次提交的草案中，一个实体bean只是一个数据库的映射。并且是基于非抽象持久化模式和简单的数据访问模式的更加简单开发。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我对模型变更持保留态度，我认为在EJB中包含SQL脚本片断并不是个好注意。一些开发人员完全反对包含某些&ldquo;SQL片段（SQLness）&rdquo;（比如@Table 和 @Column注释）。我的观点是这些SQLness是好的，据此我们可以清楚的知道我们到底要数据库作些什么。但是某些SQL段我看来并不是很好，比如columnDefinition=&quot;BLOB NOT NULL&quot;，这使得EJB代码和SQL之间的耦合太过紧密了。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 尽管对于本地SQL的支持看似很诱人，其实在EJB代码中嵌入SQL是一个非常糟糕的主意。当然，有些办法可以避免在EJB中硬编码SQL，但是这应该在规范中说明，而不能是某些开发人员自己定义的模式。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 假设@Table注释只用于类。在运行时通过@Table注释的name属性定义的表名称将必须对应一个实际的数据库表。规范对此应该给予清楚的说明和一致的模式。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 规范还需要更清楚的说明客户端编程模型，尤其是普通java客户端。规范中所有的参考都假设或者隐含的使用EJB客户端。而且规范中对客户端的向后兼容方面也没有给出明确的说法。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transient注释应该重新命名以避免和已有的transient关键字发生冲突。事实上，在这一点上我们更乐于稍微的背离一下configuration-by-exception原则并且定义一个@Persistent注释来明确的定义持久化字段。@Persistent注释可以仅仅是一个标记注释或者它可以有几个属性来关联O/R映射注释。<br />
<br />
与其他规范的关联<br />
<br />
目前可能影响到EJB3.0的JSR有JSR175（java语言元数据工具）和JSR181（Java Web服务元数据）<br />
<br />
JSR175已经初步完成并且不会和EJB3.0有太大的冲突；但是JSR181与EJB3.0有两个关联的地方：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Web service接口：EJB规范将采用一种机制适应JSR181以便可以把一个bean实现为一个Web service并告诉Web service如何被客户端调用。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSR 181计划采用不同的机制来处理安全问题。在早期的规范中EJB建议使用一个一致的机制（MethodPermissions），但是JSR 181计划使用一个稍微不同的方式（SecurityRoles和SecurityIdentity注释）。同样的RunAs注释的定义也存在这些许差别。这一问题还在解决中最终会在J2EE层的规范中维持其一致性。<br />
<br />
在J2EE 1.5中的一些开发规范可能与EJB3.0有关联。除了上面说到的几个关联之外现在没有其他的开发规范与EJB3.0有冲突。<br />
</font>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/133543#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 19 Oct 2007 23:25:36 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/133543</link>
        <guid>http://tantengfei.javaeye.com/blog/133543</guid>
      </item>
      <item>
        <title>oracle工具</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/133541" style="color:red;">http://tantengfei.javaeye.com/blog/133541</a>&nbsp;
          发表时间: 2007年10月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;
<table cellspacing="0" border="0" width="100%" cellpadding="7">
    <tbody>
        <tr>
            <td>
            <table cellspacing="0" border="0" width="99%" cellpadding="0">
                <tbody>
                    <tr align="left" valign="top">
                        <td colspan="2"><img src="mhtml:file://E:\My Documents\MYWORK\study\Oracle SQL Developer.mht!http://www.oracle.com/technology/products/database/sql_developer/SQLDevLogo.png" align="left" vspace="5" hspace="5" alt="" />
                        <h1>Oracle SQL Developer</h1>
                        <span class="bodycopy">Oracle SQL Developer 是一个<strong>免费的</strong>图形化数据库开发工具。使用 SQL Developer，您可以浏览数据库对象、运行 SQL 语句和 SQL 脚本，并且还可以编辑和调试 PL/SQL 语句。您还可以运行所提供的任何数量的报表，以及创建和保存您自己的报表。SQL Developer 可以提高工作效率并简化数据库开发任务</span>。 </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<p>不用安装oracle客户端，只需解压便可以，适用于团队开发，大多数oracle开发者。。。。。。</p>
          <br/>
          <span style="color:red;">
            <a href="http://tantengfei.javaeye.com/blog/133541#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 19 Oct 2007 23:22:25 +0800</pubDate>
        <link>http://tantengfei.javaeye.com/blog/133541</link>
        <guid>http://tantengfei.javaeye.com/blog/133541</guid>
      </item>
      <item>
        <title>js正则表达式</title>
        <author>tantengfei</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://tantengfei.javaeye.com">tantengfei</a>&nbsp;
          链接：<a href="http://tantengfei.javaeye.com/blog/133539" style="color:red;">http://tantengfei.javaeye.com/blog/133539</a>&nbsp;
          发表时间: 2007年10月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="FONT-SIZE: 18pt">JS的正则表达式</span></p>
<p>//校验是否全由数字组成 <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>function&nbsp;isDigit(s) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>var&nbsp;patrn=/^[</span><span class="number">0</span><span>-</span><span class="number">9</span><span>]{</span><span class="number">1</span><span>,</span><span class="number">20</span><span>}$/; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<script>render_code();</script>
<p>&nbsp;</p>
<p>//校验登录名：只能输入5-20个以字母开头、可带数字、&ldquo;_&rdquo;、&ldquo;.&rdquo;的字串 <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>function&nbsp;isRegisterUserName(s) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>var&nbsp;patrn=/^[a-zA-Z]{</span><span class="number">1</span><span>}([a-zA-Z0-</span><span class="number">9</span><span>]|[._]){</span><span class="number">4</span><span>,</span><span class="number">19</span><span>}$/; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<script>render_code();</script>
<p>&nbsp;</p>
<p>//校验用户姓名：只能输入1-30个以字母开头的字串 <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>function&nbsp;isTrueName(s) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>var&nbsp;patrn=/^[a-zA-Z]{</span><span class="number">1</span><span>,</span><span class="number">30</span><span>}$/; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>}} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="comment">//校验密码：只能输入6-20个字母、数字、下划线 </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>[code] &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>function&nbsp;isPasswd(s) &nbsp;&nbsp;</span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>var&nbsp;patrn=/^(\w){</span><span class="number">6</span><span>,</span><span class="number">20</span><span>}$/; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<script>render_code();</script>
<p>&nbsp;</p>
<p>//校验普通电话、传真号码：可以&ldquo;+&rdquo;开头，除数字外，可含有&ldquo;-&rdquo; <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>function&nbsp;isTel(s) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="comment">//var&nbsp;patrn=/^[+]{0,1}(\d){1,3}[&nbsp;]?([-]?(\d){1,12})+$/; </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>var&nbsp;patrn=/^[+]{</span><span class="number">0</span><span>,</span><span class="number">1</span><span>}(\d){</span><span class="number">1</span><span>,</span><span class="number">3</span><span>}[&nbsp;]?([-]?((\d)|[&nbsp;]){</span><span class="number">1</span><span>,</span><span class="number">12</span><span>})+$/; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<script>render_code();</script>
<p>&nbsp;</p>
<p>//校验手机号码：必须以数字开头，除数字外，可含有&ldquo;-&rdquo; <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>function&nbsp;isMobil(s) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>var&nbsp;patrn=/^[+]{</span><span class="number">0</span><span>,</span><span class="number">1</span><span>}(\d){</span><span class="number">1</span><span>,</span><span class="number">3</span><span>}[&nbsp;]?([-]?((\d)|[&nbsp;]){</span><span class="number">1</span><span>,</span><span class="number">12</span><span>})+$/; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<script>render_code();</script>
<p>&nbsp;</p>
<p>//校验邮政编码 <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>function&nbsp;isPostalCode(s) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="comment">//var&nbsp;patrn=/^[a-zA-Z0-9]{3,12}$/; </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>var&nbsp;patrn=/^[a-zA-Z0-</span><span class="number">9</span><span>&nbsp;]{</span><span class="number">3</span><span>,</span><span class="number">12</span><span>}$/; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<script>render_code();</script>
<p>&nbsp;</p>
<p>//校验搜索关键字 <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>function&nbsp;isSearch(s) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>var&nbsp;patrn=/^[^`~!@#$%^&amp;*()+=|\\\][\]\{\}:;'\,.&lt;&gt;/?]{</span><span class="number">1</span><span>}[^`~!@$%^&amp;()+=|\\\] &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[\]\{\}:;'\,.&lt;&gt;?]{</span><span class="number">0</span><span>,</span><span class="number">19</span><span>}$/; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>function&nbsp;isIP(s)&nbsp;</span><span class="comment">//by&nbsp;zergling </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>var&nbsp;patrn=/^[</span><span class="number">0</span><span>-</span><span class="number">9</span><span>.]{</span><span class="number">1</span><span>,</span><span class="number">20</span><span>}$/; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">if</span><span>&nbsp;(!patrn.exec(s))&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<script>render_code();</script>
<p>&nbsp;</p>
<p><span style="FONT-SIZE: 18pt">正则表达式</span> <br />
</p>
<div class="code_title">代码</div>
<div class="code_div">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="string">&quot;^\\d+$&quot;</span><span>　　</span><span class="comment">//非负整数（正整数&nbsp;+&nbsp;0） </span><span>&nbsp;&nbsp;</span></span