<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>爱博</title>
    <description>人生没有彩排！</description>
    <link>http://sussi.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>使用CVSACL进行CVS权限访问控制 for Linux</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/191883" style="color:red;">http://sussi.javaeye.com/blog/191883</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p style="text-align: center;"><strong><span style="font-size: small;">使用CVSACL进行CVS权限访问控制（for Linux）</span></strong> </p>
<p style="text-align: left;"><br />&nbsp;&nbsp;&nbsp; CVS是一个很成熟的版本控制系统，它是开源世界的杰作，并且已经成为开源组织使用的标准版本控制系统，在几乎所有的开源项目中得到应用。</p>
<p>&nbsp;&nbsp;&nbsp; 也正是由于CVS产生和应用于开源世界，使得它在代码的访问控制方面存在先天性的不足，在应用于大中型的商业项目的代码管理中收到一定的限制。因为这类型的项目通常都需要比较细致的分工，不同的小组分别负责不同模块的开发，代码需要比较严格的访问控制，不同的开发人员只能访问授权的代码。</p>
<p>&nbsp;&nbsp;&nbsp; 幸运的是，CVS是一个开源的软件，我们有什么需要的话可以通过修改它的源代码来实现。CVSACL就是实现访问控制的CVS补丁。它本身也是一个开源的项目，项目主页是<a href="http://cvsacl.sourceforge.net/index.html">http://cvsacl.sourceforge.net/index.html</a> 。它提供了对CVS的模块，目录和文件以及分支和tag的高级访问控制。CVSACL定义了8级不同的访问权限,分别是:</p>
<p>
<table cellspacing="0" border="1" cellpadding="0">
<tbody>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">权限</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">关键字</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">说明</p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">没有权限</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">n</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">用户不能做任何cvs操作</p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">读权限</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">r</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">可以执行annotate, checkout, diff, export, log, rannotate, rdiff, rlog, status命令</p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">写权限</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">w</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">可以执行commit/checkin命令</p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">tag</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">t</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">可以执行tag/rtag命令,依赖读权限 </p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">创建</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">c</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">可以执行add import 命令</p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">删除</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">d</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">可以执行rm命令</p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">全部权限</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">a</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">可以执行所有cvs命令处理cvsacl管理命令</p>
</td>
</tr>
<tr>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">管理权限</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="center" style="font-size: 10pt; color: #000000;">p</p>
</td>
<td style="font-size: 10pt; color: #000000;">
<p align="left" style="font-size: 10pt; color: #000000;">可以执行所有命令</p>
</td>
</tr>
</tbody>
</table>
</p>
<p>1．&nbsp; 下载CVSACL：</p>
<p>通过如下网址可以下载到CVSACL相关程序，目前最新版本是cvsacl-1.2.5：</p>
<p><a href="https://sourceforge.net/project/showfiles.php?group_id=75057&amp;package_id=77484&amp;release_id=423655">https://sourceforge.net/project/showfiles.php?group_id=75057&amp;package_id=77484&amp;release_id=423655</a> </p>
<p>cvsacl-1.2.5-for-cvs-1.11.22.tar.gz</p>
<p>cvs-1.11.22-cvsacl-1.2.5-patched.tar.gz</p>
<p>2．&nbsp; 安装CVSACL：</p>
<p>安装方法：cvs-1.11.22-cvsacl-1.2.5-patched.tar.gz</p>
<p>[root@localhost setup_cvs]# tar -zxvf cvs-1.11.22-cvsacl-1.2.5-patched.tar.gz</p>
<p>//解压缩cvs-1.11.22-cvsacl-1.2.5-patched.tar.gz</p>
<p>[root@localhost setup_cvs]# mv cvs-1.11.22-cvsacl-1.2.5-patched cvs-1.11.22</p>
<p>//修改cvs-1.11.22-cvsacl-1.2.5-patched目录名称为 cvs-1.11.22</p>
<p>[root@localhost setup_cvs]# cd cvs-1.11.22&nbsp;&nbsp;&nbsp; //进入cvs-1.11.22</p>
<p>[root@localhost cvs-1.11.22]# ./configure&nbsp;&nbsp;&nbsp; //编译安装</p>
<p>[root@localhost cvs-1.11.22]# make</p>
<p>[root@localhost cvs-1.11.22]# make install</p>
<p>[root@localhost setup_cvs]# cvs &ndash;version&nbsp;&nbsp;&nbsp; //查看cvs版本</p>
<p>Concurrent Versions System (CVS) 1.11.22 (client/server)</p>
<p>with CVSACL Patch 1.2.5 (cvsacl.sourceforge.net)</p>
<p>注：不需要特意删除旧版本的CVS。</p>
<p>3．&nbsp; CVS服务器的配置：</p>
<p>（1） 修改配置文件：</p>
<p>[root@localhost /]# vi /etc/services</p>
<p>查看是否有：</p>
<p>cvspserver 2401/tcp #CVS client/server operations<br />cvspserver 2401/udp #CVS client/server operations</p>
<p>注：系统自带了CVS时，这2行也已经有了，只需要确认一下。如果没有，请自己加上去。 </p>
<p>（2） 创建CVS启动脚本：</p>
<p>[root@localhost /]# vi /etc/xinetd.d/cvspserver</p>
<p>内容如下：</p>
<p>service cvspserver<br />{<br />disable = no<br />flags = REUSE<br />socket_type = stream<br />wait = no<br />user = root<br />server = /usr/bin/cvs<br />server_args = -f --allow-root=/home/cvsroot pserver<br />log_on_success += USERID<br />log_on_failure += USERID<br />}</p>
<p>注：其中，server指定CVS可执行文件路径，默认安装就是/usr/bin/cvs，server_args指定源代码库路径及认证方式等，例子中把源代码存放在cvsroot的主目录中，也可以另外指定路径，但必须注意权限设置，pserver是密码认证方式，这种方式的安全性要差一些，但操作起来比较简单。请注意每行等号左右都有一个空格，否则无法启动服务。</p>
<p>（3） 重新启动xinetd服务：</p>
<p>[root@localhost /]# service xinetd restart</p>
<p>查看是否启动：[root@localhost /]# netstat -l | grep cvspserver</p>
<p>屏幕显示：tcp 0 0 *:cvspserver *:* LISTEN</p>
<p>说明已经正常启动，如果没有请做如下检查：</p>
<p>&lt;1&gt;请检查vi /etc/xinetd.d/cvspserver文件中的server = /usr/bin/cvs路径和实际执行文件所在位置是否一致；(一般这步骤即可解决该问题)</p>
<p>&lt;2&gt;请重新检查配置过程是否有错误或者遗漏；</p>
<p>&lt;3&gt;最后还必须检查防火墙的设置，把2401端口打开。</p>
<p>4．&nbsp; CVSACL权限设置：</p>
<p>（1） 创建用于CVS的专用系统组和用户：</p>
<p>[root@localhost /]# groupadd cvsroot</p>
<p>[root@localhost /]# useradd &ndash;g cvsroot cvsadmin</p>
<p>（2） 初始化cvs服务器环境：</p>
<p>[root@localhost /]# cvs -d /cvstest init</p>
<p>（3） 设置CVS配置库归属及权限：</p>
<p>[root@localhost /]# chown &ndash;R cvsadmin.cvsroot /cvstest</p>
<p>[root@localhost /]# chmod &ndash;R 770 /cvsroot</p>
<p>（4） 修改CVSROOT/CVSROOT/aclconfig配置文件：</p>
<p>[root@localhost /]# vi /cvstest/CVSROOT/aclconfig</p>
<p>UseSystemGroups=yes 行首添加&ldquo;#&rdquo;，表示注释掉。</p>
<p>UseCVSGroup=yes 去除行首的&ldquo;#&rdquo;，表示启用此句。</p>
<p>（5） 创建CVS用户及组：</p>
<p>[root@localhost /]# cd /cvstest/CVSROOT</p>
<p>[root@localhost /]# htpasswd &ndash;c passwd yueyx</p>
<p>[root@localhost /]# vi passwd</p>
<p>yueyx:*******:cvsadmin</p>
<p>将passwd文件中的所有cvs用户映射到同一个系统用户cvsadmin上。</p>
<p>[root@localhost /]# vi group</p>
<p>文件格式：</p>
<p>group1:x:1:yueyx,test1</p>
<p>用户之间用 &ldquo;,&rdquo;分割。</p>
<p>注：cvsacl有个bug，必须在组用户最前边添加一个不存在的cvs用户，group文件才会生效。原因不明，但此方法确实管用。</p>
<p>（6） 使用cvsacl细化权限：</p>
<p>[root@localhost /]# cvs -d /cvstest racl yueyx:wcd &ndash;R Project/doc</p>
<p>说明：/cvstest：配置库路径 yueyx：用户 wcd：参见本文&ldquo;CVSACL定义了8级不同的访问权限&rdquo;表格。 Project ：配置库中的Module(模块)，doc：Module(模块)下的目录</p>
<p><br />格式：cvs &ndash;d 配置库位置 racl [用户||组:权限] [-Rl] [-r tag] [模块&hellip;] [文件&hellip;]</p>
<p>- R 进行目录递归</p>
<p>- r rev 设定版本/标签</p>
<p>- l列出已定义的ACLs权限</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/191883#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><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 11 May 2008 09:13:10 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/191883</link>
        <guid>http://sussi.javaeye.com/blog/191883</guid>
      </item>
      <item>
        <title>Lucene：基于Java的全文检索引擎简介</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/174528" style="color:red;">http://sussi.javaeye.com/blog/174528</a>&nbsp;
          发表时间: 2008年03月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Lucene是一个基于Java的全文索引工具包。<br /><br />基于Java的全文索引引擎Lucene简介：关于作者和Lucene的历史 <br />全文检索的实现：Luene全文索引和数据库索引的比较 <br />中文切分词机制简介：基于词库和自动切分词算法的比较 <br />具体的安装和使用简介：系统结构介绍和演示 <br />Hacking Lucene：简化的查询分析器，删除的实现，定制的排序，应用接口的扩展 <br />从Lucene我们还可以学到什么 <br />基于Java的全文索引/检索引擎——Lucene<br /><br />Lucene不是一个完整的全文索引应用，而是是一个用Java写的全文索引引擎工具包，它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。<br /><br />Lucene的作者：Lucene的贡献者Doug Cutting是一位资深全文索引/检索专家，曾经是V-Twin搜索引擎(Apple的Copland操作系统的成就之一)的主要开发者，后在Excite担任高级系统架构设计师，目前从事于一些INTERNET底层架构的研究。他贡献出的Lucene的目标是为各种中小型应用程序加入全文检索功能。<br /><br />Lucene的发展历程：早先发布在作者自己的www.lucene.com，后来发布在SourceForge，2001年年底成为APACHE基金会jakarta的一个子项目：http://jakarta.apache.org/lucene/<br /><br />已经有很多Java项目都使用了Lucene作为其后台的全文索引引擎，比较著名的有：<br /><br />Jive：WEB论坛系统； <br />Eyebrows：邮件列表HTML归档/浏览/查询系统，本文的主要参考文档“TheLucene search engine: Powerful, flexible, and free”作者就是EyeBrows系统的主要开发者之一，而EyeBrows已经成为目前APACHE项目的主要邮件列表归档系统。 <br />Cocoon:基于XML的web发布框架，全文检索部分使用了Lucene <br />Eclipse:基于Java的开放开发平台，帮助部分的全文索引使用了Lucene<br /><br />对于中文用户来说，最关心的问题是其是否支持中文的全文检索。但通过后面对于Lucene的结构的介绍，你会了解到由于Lucene良好架构设计，对中文的支持只需对其语言词法分析接口进行扩展就能实现对中文检索的支持。<br /><br />全文检索的实现机制<br /><br />Lucene的API接口设计的比较通用，输入输出结构都很像数据库的表==>记录==>字段，所以很多传统的应用的文件、数据库等都可以比较方便的映射到Lucene的存储结构/接口中。总体上看：可以先把Lucene当成一个支持全文索引的数据库系统。<br /><br />比较一下Lucene和数据库：<br /><br />Lucene 数据库 <br />索引数据源：doc(field1,field2...) doc(field1,field2...)                  \  indexer /                 _____________                | Lucene Index|                --------------                 / searcher \ 结果输出：Hits(doc(field1,field2) doc(field1...))  索引数据源：record(field1,field2...) record(field1..)              \  SQL: insert/               _____________              | DB  Index   |               -------------              / SQL: select \结果输出：results(record(field1,field2..) record(field1...)) <br />Document：一个需要进行索引的“单元”<br />一个Document由多个字段组成 Record：记录，包含多个字段 <br />Field：字段 Field：字段 <br />Hits：查询结果集，由匹配的Document组成 RecordSet：查询结果集，由多个Record组成 <br /><br />全文检索 ≠ like "%keyword%"<br /><br />通常比较厚的书籍后面常常附关键词索引表（比如：北京：12, 34页，上海：3,77页……），它能够帮助读者比较快地找到相关内容的页码。而数据库索引能够大大提高查询的速度原理也是一样，想像一下通过书后面的索引查找的速度要比一页一页地翻内容高多少倍……而索引之所以效率高，另外一个原因是它是排好序的。对于检索系统来说核心是一个排序问题。<br /><br />由于数据库索引不是为全文索引设计的，因此，使用like "%keyword%"时，数据库索引是不起作用的，在使用like查询时，搜索过程又变成类似于一页页翻书的遍历过程了，所以对于含有模糊查询的数据库服务来说，LIKE对性能的危害是极大的。如果是需要对多个关键词进行模糊匹配：like"%keyword1%" and like "%keyword2%" ...其效率也就可想而知了。<br /><br />所以建立一个高效检索系统的关键是建立一个类似于科技索引一样的反向索引机制，将数据源（比如多篇文章）排序顺序存储的同时，有另外一个排好序的关键词列表，用于存储关键词==>文章映射关系，利用这样的映射关系索引：[关键词==>出现关键词的文章编号，出现次数（甚至包括位置：起始偏移量，结束偏移量），出现频率]，检索过程就是把模糊查询变成多个可以利用索引的精确查询的逻辑组合的过程。从而大大提高了多关键词查询的效率，所以，全文检索问题归结到最后是一个排序问题。<br /><br />由此可以看出模糊查询相对数据库的精确查询是一个非常不确定的问题，这也是大部分数据库对全文检索支持有限的原因。Lucene最核心的特征是通过特殊的索引结构实现了传统数据库不擅长的全文索引机制，并提供了扩展接口，以方便针对不同应用的定制。<br /><br />可以通过一下表格对比一下数据库的模糊查询：<br /><br />　 Lucene全文索引引擎 数据库 <br />索引 将数据源中的数据都通过全文索引一一建立反向索引 对于LIKE查询来说，数据传统的索引是根本用不上的。数据需要逐个便利记录进行GREP式的模糊匹配，比有索引的搜索速度要有多个数量级的下降。 <br />匹配效果 通过词元(term)进行匹配，通过语言分析接口的实现，可以实现对中文等非英语的支持。 使用：like "%net%" 会把netherlands也匹配出来，<br />多个关键词的模糊匹配：使用like "%com%net%"：就不能匹配词序颠倒的xxx.net..xxx.com <br />匹配度 有匹配度算法，将匹配程度（相似度）比较高的结果排在前面。 没有匹配程度的控制：比如有记录中net出现5词和出现1次的，结果是一样的。 <br />结果输出 通过特别的算法，将最匹配度最高的头100条结果输出，结果集是缓冲式的小批量读取的。 返回所有的结果集，在匹配条目非常多的时候（比如上万条）需要大量的内存存放这些临时结果集。 <br />可定制性 通过不同的语言分析接口实现，可以方便的定制出符合应用需要的索引规则（包括对中文的支持） 没有接口或接口复杂，无法定制 <br />结论 高负载的模糊查询应用，需要负责的模糊查询的规则，索引的资料量比较大 使用率低，模糊匹配规则简单或者需要模糊查询的资料量少 <br /><br />全文检索和数据库应用最大的不同在于：让最相关的头100条结果满足98%以上用户的需求<br /><br />Lucene的创新之处：<br /><br />大部分的搜索（数据库）引擎都是用B树结构来维护索引，索引的更新会导致大量的IO操作，Lucene在实现中，对此稍微有所改进：不是维护一个索引文件，而是在扩展索引的时候不断创建新的索引文件，然后定期的把这些新的小索引文件合并到原先的大索引中（针对不同的更新策略，批次的大小可以调整），这样在不影响检索的效率的前提下，提高了索引的效率。<br /><br />Lucene和其他一些全文检索系统/应用的比较：<br /><br />　 Lucene 其他开源全文检索系统 <br />增量索引和批量索引 可以进行增量的索引(Append)，可以对于大量数据进行批量索引，并且接口设计用于优化批量索引和小批量的增量索引。 很多系统只支持批量的索引，有时数据源有一点增加也需要重建索引。 <br />数据源 Lucene没有定义具体的数据源，而是一个文档的结构，因此可以非常灵活的适应各种应用（只要前端有合适的转换器把数据源转换成相应结构）， 很多系统只针对网页，缺乏其他格式文档的灵活性。 <br />索引内容抓取 Lucene的文档是由多个字段组成的，甚至可以控制那些字段需要进行索引，那些字段不需要索引，近一步索引的字段也分为需要分词和不需要分词的类型：<br />   需要进行分词的索引，比如：标题，文章内容字段<br />   不需要进行分词的索引，比如：作者/日期字段 缺乏通用性，往往将文档整个索引了 <br />语言分析 通过语言分析器的不同扩展实现：<br />可以过滤掉不需要的词：an the of 等，<br />西文语法分析：将jumps jumped jumper都归结成jump进行索引/检索<br />非英文支持：对亚洲语言，阿拉伯语言的索引支持 缺乏通用接口实现 <br />查询分析 通过查询分析接口的实现，可以定制自己的查询语法规则：<br />比如： 多个关键词之间的 + - and or关系等 　 <br />并发访问 能够支持多用户的使用 　 <br /><br />　<br /><br />关于亚洲语言的的切分词问题(Word Segment)<br /><br />对于中文来说，全文索引首先还要解决一个语言分析的问题，对于英文来说，语句中单词之间是天然通过空格分开的，但亚洲语言的中日韩文语句中的字是一个字挨一个，所有，首先要把语句中按“词”进行索引的话，这个词如何切分出来就是一个很大的问题。<br /><br />首先，肯定不能用单个字符作(si-gram)为索引单元，否则查“上海”时，不能让含有“海上”也匹配。<br /><br />但一句话：“北京天安门”，计算机如何按照中文的语言习惯进行切分呢？<br />“北京 天安门” 还是“北 京 天安门”？让计算机能够按照语言习惯进行切分，往往需要机器有一个比较丰富的词库才能够比较准确的识别出语句中的单词。<br /><br />另外一个解决的办法是采用自动切分算法：将单词按照2元语法(bigram)方式切分出来，比如：<br />"北京天安门" ==> "北京 京天 天安 安门"。<br /><br />这样，在查询的时候，无论是查询"北京" 还是查询"天安门"，将查询词组按同样的规则进行切分："北京"，"天安安门"，多个关键词之间按与"and"的关系组合，同样能够正确地映射到相应的索引中。这种方式对于其他亚洲语言：韩文，日文都是通用的。<br /><br />基于自动切分的最大优点是没有词表维护成本，实现简单，缺点是索引效率低，但对于中小型应用来说，基于2元语法的切分还是够用的。基于2元切分后的索引一般大小和源文件差不多，而对于英文，索引文件一般只有原文件的30%-40%不同，<br /><br /><br /> 自动切分 词表切分 <br />实现 实现非常简单 实现复杂 <br />查询 增加了查询分析的复杂程度， 适于实现比较复杂的查询语法规则 <br />存储效率 索引冗余大，索引几乎和原文一样大 索引效率高，为原文大小的30％左右 <br />维护成本 无词表维护成本 词表维护成本非常高：中日韩等语言需要分别维护。<br />还需要包括词频统计等内容 <br />适用领域 嵌入式系统：运行环境资源有限<br />分布式系统：无词表同步问题<br />多语言环境：无词表维护成本 对查询和存储效率要求高的专业搜索引擎<br /> <br /><br />目前比较大的搜索引擎的语言分析算法一般是基于以上2个机制的结合。关于中文的语言分析算法，大家可以在Google查关键词"wordsegment search"能找到更多相关的资料。<br /><br />安装和使用<br /><br />下载：http://jakarta.apache.org/lucene/<br /><br />注意：Lucene中的一些比较复杂的词法分析是用JavaCC生成的（JavaCC：JavaCompilerCompiler，纯Java的词法分析生成器），所以如果从源代码编译或需要修改其中的QueryParser、定制自己的词法分析器，还需要从https://javacc.dev.java.net/下载javacc。<br /><br />lucene的组成结构：对于外部应用来说索引模块(index)和检索模块(search)是主要的外部应用入口<br /><br />org.apache.Lucene.search/ 搜索入口 <br />org.apache.Lucene.index/ 索引入口 <br />org.apache.Lucene.analysis/ 语言分析器 <br />org.apache.Lucene.queryParser/ 查询分析器 <br />org.apache.Lucene.document/ 存储结构 <br />org.apache.Lucene.store/  底层IO/存储结构 <br />org.apache.Lucene.util/ 一些公用的数据结构 <br /><br />简单的例子演示一下Lucene的使用方法：<br /><br />索引过程：从命令行读取文件名（多个），将文件分路径(path字段)和内容(body字段)2个字段进行存储，并对内容进行全文索引：索引的单位是Document对象，每个Document对象包含多个字段Field对象，针对不同的字段属性和数据输出的需求，对字段还可以选择不同的索引/存储字段规则，列表如下： 方法 切词 索引 存储 用途 <br />Field.Text(String name, String value) Yes Yes Yes 切分词索引并存储，比如：标题，内容字段 <br />Field.Text(String name, Reader value) Yes Yes No 切分词索引不存储，比如：META信息，<br />不用于返回显示，但需要进行检索内容 <br />Field.Keyword(String name, String value) No Yes Yes 不切分索引并存储，比如：日期字段 <br />Field.UnIndexed(String name, String value) No No Yes 不索引，只存储，比如：文件路径 <br />Field.UnStored(String name, String value) Yes Yes No 只全文索引，不存储 <br /><br />public class IndexFiles {   //使用方法：: IndexFiles [索引输出目录] [索引的文件列表] ...   public static void main(String[] args) throws Exception {    String indexPath = args[0];    IndexWriter writer;    //用指定的语言分析器构造一个新的写索引器（第3个参数表示是否为追加索引）    writer = new IndexWriter(indexPath, new SimpleAnalyzer(), false);    for (int i=1; i&lt;args.length; i++) {      System.out.println("Indexing file " + args[i]);      InputStream is = new FileInputStream(args[i]);      //构造包含2个字段Field的Document对象      //一个是路径path字段，不索引，只存储      //一个是内容body字段，进行全文索引，并存储      Document doc = new Document();      doc.add(Field.UnIndexed("path", args[i]));      doc.add(Field.Text("body", (Reader) new InputStreamReader(is)));      //将文档写入索引      writer.addDocument(doc);      is.close();    };    //关闭写索引器    writer.close();  }}　索引过程中可以看到：<br /><br />语言分析器提供了抽象的接口，因此语言分析(Analyser)是可以定制的，虽然lucene缺省提供了2个比较通用的分析器SimpleAnalyser和StandardAnalyser，这2个分析器缺省都不支持中文，所以要加入对中文语言的切分规则，需要修改这2个分析器。 <br />Lucene并没有规定数据源的格式，而只提供了一个通用的结构（Document对象）来接受索引的输入，因此输入的数据源可以是：数据库，WORD文档，PDF文档，HTML文档……只要能够设计相应的解析转换器将数据源构造成成Docuement对象即可进行索引。 <br />对于大批量的数据索引，还可以通过调整IndexerWrite的文件合并频率属性（mergeFactor）来提高批量索引的效率。 <br />检索过程和结果显示：<br /><br />搜索结果返回的是Hits对象，可以通过它再访问Document==>Field中的内容。<br /><br />假设根据body字段进行全文检索，可以将查询结果的path字段和相应查询的匹配度(score)打印出来，<br /><br />public class Search {   public static void main(String[] args) throws Exception {    String indexPath = args[0], queryString = args[1];    //指向索引目录的搜索器    Searcher searcher = new IndexSearcher(indexPath);    //查询解析器：使用和索引同样的语言分析器    Query query = QueryParser.parse(queryString, "body",                               new SimpleAnalyzer());    //搜索结果使用Hits存储    Hits hits = searcher.search(query);    //通过hits可以访问到相应字段的数据和查询的匹配度    for (int i=0; i&lt;hits.length(); i++) {      System.out.println(hits.doc(i).get("path") + "; Score: " +                          hits.score(i));    };  }}在整个检索过程中，语言分析器，查询分析器，甚至搜索器（Searcher）都是提供了抽象的接口，可以根据需要进行定制。 <br />Hacking Lucene<br /><br />简化的查询分析器<br /><br />个人感觉lucene成为JAKARTA项目后，画在了太多的时间用于调试日趋复杂QueryParser，而其中大部分是大多数用户并不很熟悉的，目前LUCENE支持的语法：<br /><br />Query ::= ( Clause )*<br />Clause ::= ["+", "-"] [&lt;TERM> ":"] ( &lt;TERM> | "(" Query ")")<br /><br />中间的逻辑包括：and or + - &&||等符号，而且还有"短语查询"和针对西文的前缀/模糊查询等，个人感觉对于一般应用来说，这些功能有一些华而不实，其实能够实现目前类似于Google的查询语句分析功能其实对于大多数用户来说已经够了。所以，Lucene早期版本的QueryParser仍是比较好的选择。<br /><br />添加修改删除指定记录（Document）<br /><br />Lucene提供了索引的扩展机制，因此索引的动态扩展应该是没有问题的，而指定记录的修改也似乎只能通过记录的删除，然后重新加入实现。如何删除指定的记录呢？删除的方法也很简单，只是需要在索引时根据数据源中的记录ID专门另建索引，然后利用IndexReader.delete(Termterm)方法通过这个记录ID删除相应的Document。<br /><br />根据某个字段值的排序功能<br /><br />lucene缺省是按照自己的相关度算法（score）进行结果排序的，但能够根据其他字段进行结果排序是一个在LUCENE的开发邮件列表中经常提到的问题，很多原先基于数据库应用都需要除了基于匹配度（score）以外的排序功能。而从全文检索的原理我们可以了解到，任何不基于索引的搜索过程效率都会导致效率非常的低，如果基于其他字段的排序需要在搜索过程中访问存储字段，速度回大大降低，因此非常是不可取的。<br /><br />但这里也有一个折中的解决方法：在搜索过程中能够影响排序结果的只有索引中已经存储的docID和score这2个参数，所以，基于score以外的排序，其实可以通过将数据源预先排好序，然后根据docID进行排序来实现。这样就避免了在LUCENE搜索结果外对结果再次进行排序和在搜索过程中访问不在索引中的某个字段值。<br /><br />这里需要修改的是IndexSearcher中的HitCollector过程：<br /><br />...　scorer.score(new HitCollector() {	private float minScore = 0.0f;	public final void collect(int doc, float score) {	  if (score > 0.0f &&			  // ignore zeroed buckets	      (bits==null || bits.get(doc))) {	  // skip docs not in bits	    totalHits[0]++;	    if (score >= minScore) {              /* 原先：Lucene将docID和相应的匹配度score例入结果命中列表中：	       * hq.put(new ScoreDoc(doc, score));	  // update hit queue               * 如果用doc 或 1/doc 代替 score，就实现了根据docID顺排或逆排               * 假设数据源索引时已经按照某个字段排好了序，而结果根据docID排序也就实现了               * 针对某个字段的排序，甚至可以实现更复杂的score和docID的拟合。               */              hq.put(new ScoreDoc(doc, (float) 1/doc )); 	      if (hq.size() > nDocs) {		  // if hit queue overfull		hq.pop();			  // remove lowest in hit queue		minScore = ((ScoreDoc)hq.top()).score; // reset minScore	      }	    }	  }	}      }, reader.maxDoc());更通用的输入输出接口<br /><br />虽然lucene没有定义一个确定的输入文档格式，但越来越多的人想到使用一个标准的中间格式作为Lucene的数据导入接口，然后其他数据，比如PDF只需要通过解析器转换成标准的中间格式就可以进行数据索引了。这个中间格式主要以XML为主，类似实现已经不下4，5个：<br /><br />数据源: WORD       PDF     HTML    DB       other         \          |       |      |         /                       XML中间格式                            |                     Lucene INDEX目前还没有针对MSWord文档的解析器，因为Word文档和基于ASCII的RTF文档不同，需要使用COM对象机制解析。这个是我在Google上查的相关资料：http://www.intrinsyc.com/products/enterprise_applications.asp<br />另外一个办法就是把Word文档转换成text：http://www.winfield.demon.nl/index.html<br /><br /><br /><br />索引过程优化<br /><br />索引一般分2种情况，一种是小批量的索引扩展，一种是大批量的索引重建。在索引过程中，并不是每次新的DOC加入进去索引都重新进行一次索引文件的写入操作（文件I/O是一件非常消耗资源的事情）。<br /><br />Lucene先在内存中进行索引操作，并根据一定的批量进行文件的写入。这个批次的间隔越大，文件的写入次数越少，但占用内存会很多。反之占用内存少，但文件IO操作频繁，索引速度会很慢。在IndexWriter中有一个MERGE_FACTOR参数可以帮助你在构造索引器后根据应用环境的情况充分利用内存减少文件的操作。根据我的使用经验：缺省Indexer是每20条记录索引后写入一次，每将MERGE_FACTOR增加50倍，索引速度可以提高1倍左右。<br /><br /><br />搜索过程优化<br /><br /><br />lucene支持内存索引：这样的搜索比基于文件的I/O有数量级的速度提升。<br />http://www.onjava.com/lpt/a/3273<br />而尽可能减少IndexSearcher的创建和对搜索结果的前台的缓存也是必要的。<br /><br /><br /><br />Lucene面向全文检索的优化在于首次索引检索后，并不把所有的记录（Document）具体内容读取出来，而起只将所有结果中匹配度最高的头100条结果（TopDocs）的ID放到结果集缓存中并返回，这里可以比较一下数据库检索：如果是一个10,000条的数据库检索结果集，数据库是一定要把所有记录内容都取得以后再开始返回给应用结果集的。所以即使检索匹配总数很多，Lucene的结果集占用的内存空间也不会很多。对于一般的模糊检索应用是用不到这么多的结果的，头100条已经可以满足90%以上的检索需求。<br /><br /><br />如果首批缓存结果数用完后还要读取更后面的结果时Searcher会再次检索并生成一个上次的搜索缓存数大1倍的缓存，并再重新向后抓取。所以如果构造一个Searcher去查1－120条结果，Searcher其实是进行了2次搜索过程：头100条取完后，缓存结果用完，Searcher重新检索再构造一个200条的结果缓存，依此类推，400条缓存，800条缓存。由于每次Searcher对象消失后，这些缓存也访问那不到了，你有可能想将结果记录缓存下来，缓存数尽量保证在100以下以充分利用首次的结果缓存，不让Lucene浪费多次检索，而且可以分级进行结果缓存。<br /><br /><br />Lucene的另外一个特点是在收集结果的过程中将匹配度低的结果自动过滤掉了。这也是和数据库应用需要将搜索的结果全部返回不同之处。<br /><br />我的一些尝试：<br /><br />支持中文的Tokenizer：这里有2个版本，一个是通过JavaCC生成的，对CJK部分按一个字符一个TOKEN索引，另外一个是从SimpleTokenizer改写的，对英文支持数字和字母TOKEN，对中文按迭代索引。 <br />基于XML数据源的索引器：XMLIndexer，因此所有数据源只要能够按照DTD转换成指定的XML，就可以用XMLIndxer进行索引了。 <br />根据某个字段排序：按记录索引顺序排序结果的搜索器：IndexOrderSearcher，因此如果需要让搜索结果根据某个字段排序，可以让数据源先按某个字段排好序（比如：PriceField），这样索引后，然后在利用这个按记录的ID顺序检索的搜索器，结果就是相当于是那个字段排序的结果了。 <br />从Lucene学到更多<br /><br />Luene的确是一个面对对象设计的典范<br /><br />所有的问题都通过一个额外抽象层来方便以后的扩展和重用：你可以通过重新实现来达到自己的目的，而对其他模块而不需要； <br />简单的应用入口Searcher, Indexer，并调用底层一系列组件协同的完成搜索任务； <br />所有的对象的任务都非常专一：比如搜索过程：QueryParser分析将查询语句转换成一系列的精确查询的组合(Query),通过底层的索引读取结构IndexReader进行索引的读取，并用相应的打分器给搜索结果进行打分/排序等。所有的功能模块原子化程度非常高，因此可以通过重新实现而不需要修改其他模块。  <br />除了灵活的应用接口设计，Lucene还提供了一些适合大多数应用的语言分析器实现（SimpleAnalyser,StandardAnalyser），这也是新用户能够很快上手的重要原因之一。 <br />这些优点都是非常值得在以后的开发中学习借鉴的。作为一个通用工具包，Lunece的确给予了需要将全文检索功能嵌入到应用中的开发者很多的便利。<br /><br />此外，通过对Lucene的学习和使用，我也更深刻地理解了为什么很多数据库优化设计中要求，比如：<br /><br />尽可能对字段进行索引来提高查询速度，但过多的索引会对数据库表的更新操作变慢，而对结果过多的排序条件，实际上往往也是性能的杀手之一。 <br />很多商业数据库对大批量的数据插入操作会提供一些优化参数，这个作用和索引器的merge_factor的作用是类似的， <br />20%/80%原则：查的结果多并不等于质量好，尤其对于返回结果集很大，如何优化这头几十条结果的质量往往才是最重要的。 <br />尽可能让应用从数据库中获得比较小的结果集，因为即使对于大型数据库，对结果集的随机访问也是一个非常消耗资源的操作。<br /><br />参考资料：<br /><br />Apache: Lucene Project<br />http://jakarta.apache.org/lucene/<br />Lucene开发/用户邮件列表归档<br />Lucene-dev@jakarta.apache.org<br />Lucene-user@jakarta.apache.org<br /><br />The Lucene search engine: Powerful, flexible, and free<br />http://www.javaworld.com/javaworld/jw-09-2000/jw-0915-Lucene_p.html<br /><br />Lucene Tutorial<br />http://www.darksleep.com/puff/lucene/lucene.html<br /><br />Notes on distributed searching with Lucene<br />http://home.clara.net/markharwood/lucene/<br /><br />中文语言的切分词<br />http://www.google.com/search?sourceid=navclient&hl=zh-CN&q=chinese+word+segment<br /><br />搜索引擎工具介绍<br />http://searchtools.com/<br /><br />Lucene作者Cutting的几篇论文和专利<br />http://lucene.sourceforge.net/publications.html <br /><br />Lucene的.NET实现：dotLucene<br />http://sourceforge.net/projects/dotlucene/<br /><br /><br />Lucene作者Cutting的另外一个项目：基于Java的搜索引擎Nutch<br />http://www.nutch.org/   http://sourceforge.net/projects/nutch/<br /><br /><br />关于基于词表和N-Gram的切分词比较<br />http://china.nikkeibp.co.jp/cgi-bin/china/news/int/int200302100112.html
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/174528#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><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><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 21 Mar 2008 15:41:46 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/174528</link>
        <guid>http://sussi.javaeye.com/blog/174528</guid>
      </item>
      <item>
        <title>AS4 CVS使用配置</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/170787" style="color:red;">http://sussi.javaeye.com/blog/170787</a>&nbsp;
          发表时间: 2008年03月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、CVS服务器的安装<br /><br />首先确认系统中是否安装CVS服务：<br />[root@localhost /]# rpm -qa|grep cvs<br />cvs-1.11.2-cvshome.7x.1<br />如果命令输出类似于上面的输出则说明系统已经安装有cvs，否则就需要从安装光盘中安装cvs的rpm包，或者到http://www.cvshome.org下载。<br /><br />1、建立 CVSROOT <br /><br />目录，因为这里涉及到用户对CVSROOT里的文件读写的权限问题，所以比较简单的方法是建立一个组，然后再建立一个属于该组的帐户，而且以后有读写权限的用户都要属于该组。假设我们建一个组叫cvs，用户名是cvsroot。建组和用户的命令如下<br /><br />#groupadd cvs <br />#useradd -g cvs -G cvs -d /home/cvsroot cvsroot<br /><br />生成的用户宿主目录在/home/cvsroot（根据自己的系统调整）<br /><br />2、建立CVS仓库，用cvsroot 用户登陆，用下面命令：<br /><br />$cvs -d /home/cvsroot init<br /><br />3、仍然是 cvsroot 用户，修改 /home/cvsroot （CVSROOT）的权限，赋与同组人有读写的权限：　 <br /><br />$chmod 775 -R /home/cvsroot<br /><br />4、用root登录，加入cvs服务(我的redhath7.3缺省就有cvs服务,所以不用加)<br /><br />vi /etc/services<br />cvspserver 2401/tcp #pserver cvs service<br />cvspserver 2401/udp #pserver cvs service <br /><br />cvs服务由inted来唤起,因此需要改动inetd提供的服务,如果你的redhat使用的是inetd 方式则在文件/etc/inetd.conf中加入如下的内容:cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver<br /><br />我的redhat7.3使用的是xinetd方式,所以在xinetd.d目录下添加需要启动的服务:<br />cd /etc/xinetd.d<br />vi cvspserver<br />文件内容:<br />service cvspserver<br />{<br />  disable = no<br />  flags = REUSE<br />  socket_type = stream<br />  wait = no<br />  user = cvsroot<br />  server = /usr/bin/cvs<br />  server_args = -f --allow-root=/home/cvsroot pserver<br />  log_on_failure += USERID<br />}<br /><br />重新启动inetd或者xinetd:<br /> /etc/rc.d/init.d/xinetd restart<br /><br />检查cvspserver服务是否已经启动<br />[root@localhost /]# netstat -lnp|grep 2401<br />tcp        0      0 0.0.0.0:2401            0.0.0.0:*               LISTEN      1041/xinetd  <br />则说明cvs服务器已经运行。<br /><br />二、管理CVS服务器<br /><br />服务器可以用了，现在大家最关心的就是如何管理服务器，比如，我想让一些人有读和/或写 CVS 仓库的权限，但是不想给它系统权限怎么办呢？<br /><br />不难，在 cvs 管理员用户（在我这里是 cvsroot 用户）的家目录里有一个 CVSROOT 目录，这个目录里有三个配置文件，passwd, readers, writers，我们可以通过设置这三个文件来配置 CVS 服务器，下面分别介绍这几个文件的作用： <br /><br />passwd：cvs 用户的用户列表文件，它的格式很象 shadow 文件： <br /><br />{cvs 用户名}:[加密的口令]:[等效系统用户名] <br /><br />readers：有 cvs 读权限的用户列表文件。就是一个一维列表。在这个文件中的用户对 cvs只有读权限。 <br /><br />writers：有 cvs 写权限的用户的列表文件。和 readers 一样，是一个一维列表。在这个文件中的用户对 cvs 有写权限。 <br /><br />上面三个文件在缺省安装的时候可能都不存在，需要我们自己创建，好吧，现在还是让我们用一个例子来教学吧。假设我们有下面几个用户需要使用 cvs： <br /><br />laser, gumpwu, henry, betty, anonymous。 <br /><br />其中 laser 和 gumpwu 是系统用户，而 henry, betty, anonymous 我们都不想给系统用户权限，并且 betty 和 anonymous 都是只读用户，而且 anonymous 更是连口令都没有。<br /><br />然后编辑 cvs 管理员家目录里 CVSROOT/passwd 文件（cvsroot用户），加入下面几行： <br /><br />laser:$xxefajfka;faffa33:cvsroot<br />gumpwu:$ajfaal;323r0ofeeanv:cvsroot <br />henry:$fajkdpaieje:cvsroot<br />betty:fjkal;ffjieinfn/:cvsroot <br />anonymous::cvsroot<br /><br />注意：上面的第二个字段（分隔符为 :）是密文口令。 <br /><br />密码可以有以下方法生成<br />vi /home/cvsroot/passwdgen.pl<br />文件内容:<br />#!/usr/bin/perl<br />srand (time());<br />my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";<br />my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);<br />my $plaintext = shift;<br />my $crypttext = crypt ($plaintext, $salt);<br />print "${crypttext}\n";<br /><br />如果需要密码为:some,则敲入:<br />./passwdgen.pl some<br />（注意passwdgen.pl要先设为可执行chmod +x /home/cvsroot/passwdgen.pl）<br />回车即可得到加密密码,用其替换passwd文件中的passwd部分就可以了<br /><br /><br />编辑 readers 文件，加入下面几行： <br />anonymous <br />betty <br /><br />编辑 writers 文件，加入下面几行： <br /><br />laser <br />gumpwu <br />henry <br /><br />注意：writers中的用户不能在readers中，要不然不能上传更新文件。<br /><br /><br />对于使用CVS的用户要修改它的环境变量，例如laser用户的环境变量，打开/home/laser（laser的宿主目录）下的.bash_profile文件，加入<br /><br />CVSROOT=/home/cvsroot<br />export CVSROOT<br /><br />用laser登陆就可以建立CVS项目，如果要root使用，可以修改/etc/profile文件。<br /><br /><br />现在我们各项都设置好了，那么怎么用呢，我在这里写一个最简单的（估计也是最常用的）命令介绍： <br /><br />首先，建立一个新的CVS项目，一般我们都已经有一些项目文件了，这样我们可以用下面步骤生成一个新的CVS项目： <br /><br />进入到你的已有项目的目录，比如叫 cvstest： <br /><br />$cd  cvstest<br />运行命令： <br />$cvs import -m "this is a cvstest project" cvstest     v_0_0_1     start <br /><br />说明：import 是cvs的命令之一，表示向cvs仓库输入项目文件。 -m参数后面的字串是描述文本，随便写些有意义的东西，如果不加 -m 参数，那么cvs会自动运行一个编辑器（一般是vi，但是可以通过修改环境变量EDITOR来改成你喜欢用的编辑器。）让你输入信息，cvstest 是项目名称（实际上是仓库名，在CVS服务器上会存储在以这个名字命名的仓库里。） <br />v_0_0_1是这个分支的总标记。没啥用（或曰不常用。） <br />start 是每次 import 标识文件的输入层次的标记，没啥用。<br />这样我们就建立了一个CVS仓库了。<br /><br />　　建立CVS仓库的文件夹应该是“干净”的文件夹，即只包括源码文件和描述的文件加，而不应该包括编译过的文件代码等！
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/170787#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/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 13 Mar 2008 12:47:27 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/170787</link>
        <guid>http://sussi.javaeye.com/blog/170787</guid>
      </item>
      <item>
        <title>linux AS4+apache+tomcat整合</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/170750" style="color:red;">http://sussi.javaeye.com/blog/170750</a>&nbsp;
          发表时间: 2008年03月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Apache+tomcat配置<br /><br />首先声明一下：本文内容均参考于互联网，经过个人实践而总结，感谢网上前辈的经验，小女子有理了！  ^!^ 希望我能有更多的实践经验和大家一起共享，共同进步<br /><br />RedHat Linux AS4+httpd+apache-tomcat-5.5.17+jakarta-tomcat-connectors-1.2.15-src.tar.gz+Jdk 1_5_0_07<br /><br /> 将软件都准备好，放在/tools下　　<br /><br />2.安装步骤<br /><br />　　A安装JDK<br /><br />　　<br /><br />　　# cd /tools<br /><br />　　<br /><br />　　# chmod +x jdk-1_5_0_04-linux-i586-rpm.bin<br /><br />　　<br /><br />　　# ./jdk-1.5.0_04-linux-i586-rpm.bin  就自动安装到/usr/java下了<br /><br />　　<br /><br /># vi /etc/profile<br /><br />添加如下内容<br /><br /> <br /><br /><br />　　<br /><br />　　B 安装Apache<br /><br />　　我用了redhat linux AS4自带的apache<br /><br />　　# cd /etc/httpd/conf<br /><br />　　先把httpd.conf备份一份 免的修改出错：cp httpd.conf httpd.conf.bak<br /><br />　　# vi ./httpd.conf<br /><br />　　<br /><br />　　将Listen 80 修改为Listen 192.168.0.4:80　(219行）<br /><br />　　<br /><br />　　将ServerName 修改为ServerName LocalHost:80 (291行）<br /><br />　　<br /><br />　　在DirectoryIndex中添加 index.jsp （394行）<br /><br />　　<br /><br />　　#service httpd restart<br /><br />　　<br /><br />　　启动httpd服务，浏览器中访问本机80端口，查看端口是否正常，输入192.168.0.4：80<br /><br />　　<br /><br />　　C安装Tomcat<br /><br />　　#cp /tools/ apache-tomcat-5.5.17.tar.gz /opt/<br /><br />　　# cd /opt<br /><br />　　# tar -zxvf apache-tomcat-5.5.17.tar.gz<br /><br />　　# vi /opt/apache-tomcat-5.5.17/bin/catalina.sh<br /><br />　　<br /><br />　　第46行加入此句<br /><br />    <br /><br /><br />　　<br /><br />　　启动服务后，访问本机8080端口，查看端口是否正常（输入192.168.0.4：8080）<br /><br /># /opt/apache-tomcat-5.5.17/bin/ catalina.sh run或者/opt/apache-tomcat-5.5.17/bin/startup.sh<br /><br />　　<br /><br />　　关闭服务<br /><br />　　# / opt/apache-tomcat-5.5.17/bin/ catalina.sh stop<br /><br />　　<br /><br />　　D 安装JK<br /><br />　　<br /><br /># cp /tools/jakarta-tomcat-connectors-1.2.14-src.tar.gz /opt/<br /><br />#cd /opt<br /><br /># tar xzvf jakarta-tomcat-connectors-1.2.14-src.tar.gz<br /><br />　　# cd jakarta-tomcat-connectors-1.2.14-src/jk/native<br /><br />　　# chmod 755 buildconf.sh<br /><br />　　# ./buildconf.sh<br /><br /># ./configure --with-apxs=/usr/sbin/apxs<br /><br /># make<br /><br />　　# cd /opt/jakarta-tomcat-connectors-jk1.2.14-src/jk/native/apache-2.0/<br /><br />　　<br /><br />　　# cp mod_jk.so /etc/httpd/modules/<br /><br />　　<br /><br />E 系统整合<br /><br />1>.mod_jk的配置<br /><br />cd /opt/jakarta-tomcat-connectors-1.2.15-src/jk/conf/<br /><br />vi workers.properties <br /><br />修改workers.tomcat_home为tomcat的安装目录,workers.java_home为jdk的安装目录.<br /><br />workers.tomcat_home=/opt/apache-tomcat-5.5.17<br /><br />workers.java_home=/usr/java/jdk1.5.0_07<br /><br />worker.list=ajp13<br /><br />worker.ajp13.port=8009<br />worker.ajp13.host=localhost<br />worker.ajp13.type=ajp13<br /><br />2># vi /etc/httpd/conf/httpd.conf　　<br /><br />在文件最末尾加上如下语句<br /><br />#Load mod_jk<br /><br />　  LoadModule jk_module modules/mod_jk.so<br /><br />另外要增加mod_jk的配置文件<br /><br /># Configure mod_jk<br /><br />&lt;IfModule mod_jk.c><br />JkWorkersFile /opt/jakarta-tomcat-connectors-1.2.15-src/jk/conf/workers.properties<br /><br />JkLogFile /var/log/httpd/mod_jk.log<br />JkLogLevel error<br />&lt;/IfModule><br /><br />增加要通过mod_jk匹配的文件类型<br /><br />&lt;IfModule mod_jk.c><br />JkMount /*.jsp ajp13<br />JkMount /*.do ajp13<br />JkMount /servlet/* ajp13<br />&lt;/IfModule><br /><br /> <br /><br />　　<br /><br />　　#vi /usr/local/tomcat/conf/server.xml<br /><br />　　　　<br /><br />　　在119行左右加入如下语句（去注释）<br /><br />　　<br /><br />　　&lt;Engine name="Standalone" defaultHost="localhost" jvmRoute="ajp13">&lt;/Engine><br /><br />　　<br /><br />　　若第二台tomcat，将jvmRoute的修改为其它（当然在workers.properties也要添加上）<br /><br />　　<br /><br />　　系统整合完毕<br /><br />　　<br /><br />　　启动apache和tomcat服务<br /><br />　　<br /><br />　　#service httpd start<br /><br />　　<br /><br />　　# /opt/apache-tomcat-5.5.17/bin/catalina.sh run<br /><br />　　<br /><br />　　将如下内容添加至/etc/rc.d/rc.local文件末尾<br /><br />　　<br /><br />　　以便系统启动后开启tomcat服务<br /><br />　　<br /><br />　　#vi /etc/rc.d/rc.local<br /><br />　　<br /><br />添加<br /><br />/opt/apache-tomcat-5.5.17/bin/catalina.sh run
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/170750#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 13 Mar 2008 10:41:20 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/170750</link>
        <guid>http://sussi.javaeye.com/blog/170750</guid>
      </item>
      <item>
        <title>LINUX初级使用</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/170728" style="color:red;">http://sussi.javaeye.com/blog/170728</a>&nbsp;
          发表时间: 2008年03月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          12-16 <br />RHEL AS4 U盘挂载中文乱码 <br />REDHAT AS4下面本来能够自动挂U盘,在桌面上也出现了U盘图标,但是双击图标后没有任何反映,象死机一样.似乎是As4的一个bug，主要是默认编码使用utf-8， <br />以root身份修改/usr/share/hal/fdi/90defaultpolicy/sorage-policy.fdi文件，找到这一行： <br />&lt;merge key="storage.policy.default.mount_option.exec" type="bool">true&lt;/merge> <br />在其下添加一行 <br />&lt;merge key="storage.policy.default.mount_option.iocharset=utf8" type="bool">true&lt;/merge> <br />存盘退出，在root用户下执行 <br /># /sbin/service haldaemon restart <br /># /sbin/service messagebus restart <br /><br /><br />五笔输入改了文件里的一点内容 <br /><br />为IIIMF添加五笔输入模块. <br />1.下载miniChinput-0.1.9-2.i386.rpm:去http://minichinput.sourceforge.net/ <br />2.解压:cat miniChinput-0.1.9-2.i386.rpm | rpm2cpio | pax -r <br />3.将解压目录下usr/lib/Chinput/im/cce/的nqwb.tab和nqwb.tab.phr复制到/usr/lib/im/locale/zh_CN/chinput/cce nqwb.tab和nqwb.tab.phr改为wb.tab和wb.tab.phr <br />4.将解压目录下usr/lib/Chinput/im/下的cce_hzinput.so改名为wb.so并复制到/usr/lib/im/locale/zh_CN/chinput <br />5.编辑/usr/lib/im/locale/zh_CN/chinput/Chinput.ad,系统默认五笔配置字段是注释掉的(字段前打了!), 先把!全部去掉,再修改五笔那一段配置,将FILE字段改为:cce/wb.tab,MODULE字段为wb.so,其它不变如下: <br />[WB] <br />IMENAME = 五笔字型 <br />IMENAME = ^@&lt;94>N^T{W[&lt;8b>W <br />ENCODING = GB <br />FILE = cce/wb.tab <br />MODULE = wb.so <br />FAVORITE = YES <br /><br />LINUX lumaQQ <br />1.安装JDK1.6，如果你已经配置好java，可以直接跳到第2步 <br /><br />到java.sun.com去下载最新JDK1.6.0.10 for LINUX的rpm. 应该是个jdk-1_6_0_10-linux-i586-rpm.bin的文件 <br />通过chmod ＋x jdk-1_6_0_10-linux-i586-rpm.bin命令使其获得可执行权限 <br />执行./jdk-1_6_0_10-linux-i586-rpm.bin 命令将会把JDK安装到/usr/java下目录为jdk-1_6_0_10 <br /><br />设置环境变量(写入/etc/profile中,在最后添加下面几句话，也可以写在root # ~/.bashrc文件中仅对root用户起效) <br />主意等号 两边不要留空格 <br />#java环境变量配置文件 <br />export PATH=$PATH:/usr/java/jdk1.6.0_10/bin;/usr/java/jdk1.6.0_10/jre/bin <br />export JAVA_HOME=/usr/java/jdk1.6.0_10 <br />export JRE_home=/usr/java/jdk1.6.0_10/jre <br />export CLASSPATH=$JAVA_HOME/jre/lib;$JAVA_HOME/lib/dt.jar <br /><br />然后执行命令 d <br />okay了键入 java -version 如果出现相关JDK版本信息,证明成功. <br />如想证明java可以用可以做以下测试 <br />public class Hello <br />{ <br />public Hello() <br />{ <br />} <br /><br />public static void main(String[] args) <br />{ <br />System.out.println("Hello World!"; <br />} <br /><br />} <br />然后 <br />#javac Hello.java <br />检查当前目录会生成一个Hello.class的文件, 然后运行 <br />#java Hello <br />Hello World! <br />OK,测试成功! <br />2.首先到官方网站下载最新版LumaQQ2006 <br />地址为 http://lumaqq.linuxsir.org/ <br />下载那个LumaQQ 2006 M2 for Linux x86 NO JRE, <br />也可以本站下载 地址为http://ftp.saysay.cn/soft/lumaqq_2006M2-linux_gtk2_x86_no_jre.tar.gz <br />下载以后解压 <br />#tar -xzvf lumaqq_2006M2-linux_gtk2_x86_no_jre.tar.gz <br />得到LumaQQ的目录 因为这是个基于java的QQ登录工具，所以我们无须编译和安装，解压以后就可以直接使用 <br />在这个目录下执行 <br />[root #] ./lumaqq <br />OK QQ的登录框就会出来了 你就可以登上QQ和好友聊天啦 <br />创建一个快捷方式放到桌面 以后就可以直接使用了 <br />没有声音的办法,将lumaqq里面的sound目录和QQWry.dat复制到~/.lumaqq2006/就可以了 <br />Eclipse 3.3.1 使用. <br />为了使用ECLIPSE我差点就把我先前装的JAVA1.6给卸载,上了网上看看知道原来它就有一个JAVA的,所以把它卸了,在 应用程序->系统工具->添加/删除程序->开发工具JAVA-1.4.2-gcj那个 <br />删了,就可以了.再看了下JAVA的环境变量才发现以前是写错了的 <br />export PATH=$PATH:/usr/java/jdk1.6.0_10/bin/java;/usr/java/jdk1.6.0_10/jre/bin <br />把后面的 bin/java 的java去了就可以 <br />export PATH=$PATH:/usr/java/jdk1.6.0_10/bin;/usr/java/jdk1.6.0_10/jre/bin <br />shell>reboot <br />就好了 <br />Mysql5 的安装 <br />在AS4下先把MYSQL4卸了,用rpm -qa|grep Mysql5查看安装Mysqlr的组件都用rpm -evv 卸了,那些提示不能卸载的组件用rptomm -e –nodeps组件名把它卸了,然后就去http://dev.mysql.com/下载相应的组件,在最下面有源代码然后用rpm -ivh组件名半装包就可以了. <br /><br />AS4 TOMCAT6添加TOMCAT到系统开机自动启动 <br />#vi /etc/rc.d/rc.local <br />/usr/local/apache-tomcat-6.0.13/bin/startup.sh <br />在文件最后添加这一句 <br />LINUX 下的tar命令 <br />命令格式： <br />tar -vxmf name.tar <br />参数意义： <br />-v 查看执行过程 <br />-x 解压 <br />-m 还原文件时不改变原文件时间 <br />-f 源文件，后紧跟要解压文件名
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/170728#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><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>Thu, 13 Mar 2008 09:37:44 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/170728</link>
        <guid>http://sussi.javaeye.com/blog/170728</guid>
      </item>
      <item>
        <title>Linux安装：mysql+apache+php</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/170586" style="color:red;">http://sussi.javaeye.com/blog/170586</a>&nbsp;
          发表时间: 2008年03月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          安装步骤： <br /><br />　　1.mysql <br /><br />　　在如下页面下载mysql的for linux rpm包 <br /><br />　　　http://www.mysql.com/downloads/down...3.52-1.i386.rpm ; <br /><br />　　　http://www.mysql.com/downloads/down...3.52-1.i386.rpm ; <br /><br />　　存至/home/tmp目录 <br /><br />　　命令列表：　 <br /><br />　　cd /home/tmp <br /><br />　　rpm -ivh MySQL-3.23.52-1.i386.rpm #安装mysql server <br /><br />　　rpm -ivh MySQL-client-3.23.52-1.i386.rpm #安装mysql client <br /><br />　　/usr/mysql/safe_mysqld & #启动mysql server <br /><br />　　mysql #运行mysql 客户端,并开放root用户的远程访问权限。以便调试 <br /><br />　　use mysql <br /><br />　　update user set host = '%' where user = 'root' and host &lt;> 'localhost'; <br /><br />　　flush privileges; <br /><br />　　quit <br /><br />　　至此mysql安装完成 <br /><br />　　2.apache <br /><br />　　在如下页面下载apache的for linux 的源码包　　 <br /><br />　　http://www.apache.org/dist/httpd/apache_1.3.26.tar.gz ; <br /><br />　　存至/home/tmp目录 <br /><br />　　命令列表：　 <br /><br />　　cd /home/tmp <br /><br />　　tar -zxvf apache_1.3.26.tar.gz <br /><br />　　mv apache_1.3.26.tar.gz apache <br /><br />　　cd apache <br /><br />　　./configure --prefix=/usr/local/apache --enable-module=so <br /><br />　　make <br /><br />　　make install　 <br /><br />　　安装apache至/usr/local/apache 并配置apache支持dso方式 <br /><br />　　3.php <br /><br />　　在如下页面下载php的for linux 的源码包　 <br /><br />　　http://www.php.net/get_download.php?df=php-4.2.3.tar.gz ; <br /><br />　　存至/home/tmp目录 <br /><br />　　命令列表：　　 <br /><br />　　cd /home/tmp <br /><br />　　tar -zxvf php-4.2.3.tar.gz <br /><br />　　mv php-4.2.3.tar.gz php <br /><br />　　cd php <br /><br />　　./configure --prefix=/usr/local/php --with-apxs=/usr/local/apache/bin/apxs --with-config-file-path=/usr/local/lib --enable-track-vars --with-xml --with-mysql <br /><br />　　make <br /><br />　　make install <br /><br />　　cp php.ini-dist /usr/local/lib/php.ini　　 <br /><br />　　以dso方式安装php至/usr/local/php 设置配置文件目录为/usr/local/lib 开启mysql,xml支持
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/170586#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/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Mar 2008 16:53:52 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/170586</link>
        <guid>http://sussi.javaeye.com/blog/170586</guid>
      </item>
      <item>
        <title>在Linux下安装和使用MySQL</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/170496" style="color:red;">http://sussi.javaeye.com/blog/170496</a>&nbsp;
          发表时间: 2008年03月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、引言 <br /><br />　　 想使用Linux已经很长时间了，由于没有硬性任务一直也没有系统学习，近日由于工作需要必须使用Linux下的MySQL。本以为有Windows下使用SQL Server的经验，觉得在Linux下安装MySql应该是易如反掌的事，可在真正安装和使用MySQL时走了很多弯路，遇见很多问题，毕竟Linux和Windows本身就有很大区别。为了让和我一样的初学者在学习的过程中少走弯路，尽快入门，写了此文，希望对您有所帮助。本文的Linux环境是Red Hat 9.0，MySQL是4.0.16。 <br /><br />　　 二、安装Mysql <br /><br />　　 1、下载MySQL的安装文件 <br />　　 安装MySQL需要下面两个文件： <br />　　 MySQL-server-4.0.16-0.i386.rpm　　　 <br />　　 MySQL-client-4.0.16-0.i386.rpm <br />　　 下载地址为：http://www.mysql.com/downloads/mysql-4.0.html， 打开此网页，下拉网页找到“Linux x86 RPM downloads”项，找到“Server”和“Client programs”项，下载需要的上述两个rpm文件。 <br /><br />　　 2、安装MySQL <br />　　 rpm文件是Red Hat公司开发的软件安装包，rpm可让Linux在安装软件包时免除许多复杂的手续。该命令在安装时常用的参数是 –ivh ,其中i表示将安装指定的rmp软件包，V表示安装时的详细信息，h表示在安装期间出现“#”符号来显示目前的安装过程。这个符号将持续到安装完成后才停止。 <br />　　 1）安装服务器端 <br />　　 在有两个rmp文件的目录下运行如下命令： <br />　　 [root@test1 local]# rpm -ivh MySQL-server-4.0.16-0.i386.rpm <br />　　 显示如下信息。 <br />　　　 warning: MySQL-server-4.0.16-0.i386.rpm: V3 DSA signature: NOKEY, key ID 5072e1f5 <br />　　 Preparing...　　　　　　　########################################### [100%] <br />　　 1:MySQL-server　　　　　########################################### [100%] <br />　　　 。。。。。。（省略显示） <br />　　 /usr/bin/mysqladmin -u root password 'new-password' <br />　　 /usr/bin/mysqladmin -u root -h test1 password 'new-password' <br />　　　 。。。。。。（省略显示） <br />　　 Starting mysqld daemon with databases from /var/lib/mysql <br />　　 如出现如上信息，服务端安装完毕。测试是否成功可运行netstat看Mysql端口是否打开，如打开表示服务已经启动，安装成功。Mysql默认的端口是3306。 <br />　　 [root@test1 local]# netstat -nat <br />　　 Active Internet connections (servers and established) <br />　　 Proto Recv-Q Send-Q Local Address　　　　　 Foreign Address　　　　 State　　　 <br />　　 tcp　　0　　0 0.0.0.0:3306　　　　 0.0.0.0:*　　　　　 LISTEN　　　 <br />　　 上面显示可以看出MySQL服务已经启动。 <br />　　 2）安装客户端 <br />　　 运行如下命令： <br />　　 [root@test1 local]# rpm -ivh MySQL-client-4.0.16-0.i386.rpm <br />　　 warning: MySQL-client-4.0.16-0.i386.rpm: V3 DSA signature: NOKEY, key ID 5072e1f5 <br />　　 Preparing...　　　　########################################### [100%] <br />　　 1:MySQL-client　 ########################################### [100%] <br />　　 显示安装完毕。 <br />　　 用下面的命令连接mysql,测试是否成功。 <br />　 三、登录MySQL <br /><br />　　 登录MySQL的命令是mysql， mysql 的使用语法如下： <br />　　 mysql [-u username] [-h host] [-p[password]] [dbname] <br />　　 username 与 password 分别是 MySQL 的用户名与密码，mysql的初始管理帐号是root，没有密码，注意：这个root用户不是Linux的系统用户。MySQL默认用户是root，由于初始没有密码，第一次进时只需键入mysql即可。 <br />　　 [root@test1 local]# mysql <br />　　 Welcome to the MySQL monitor.　Commands end with ; or \g. <br />　　 Your MySQL connection id is 1 to server version: 4.0.16-standard <br />　　 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. <br />　　 mysql> <br />　　 出现了“mysql>”提示符，恭喜你，安装成功！ <br />　　 增加了密码后的登录格式如下： <br />　　 mysql -u root -p <br />　　 Enter password: (输入密码) <br />　　 其中-u后跟的是用户名，-p要求输入密码，回车后在输入密码处输入密码。 <br /><br />　　 注意：这个mysql文件在/usr/bin目录下，与后面讲的启动文件/etc/init.d/mysql不是一个文件。 <br /><br />　　 四、MySQL的几个重要目录 <br /><br />　　 MySQL安装完成后不象SQL Server默认安装在一个目录，它的数据库文件、配置文件和命令文件分别在不同的目录，了解这些目录非常重要，尤其对于Linux的初学者，因为Linux本身的目录结构就比较复杂，如果搞不清楚MySQL的安装目录那就无从谈起深入学习。 <br /><br />　　 下面就介绍一下这几个目录。 <br /><br />　　 1、数据库目录 <br />　　 /var/lib/mysql/ <br /><br />　　 2、配置文件 <br />　　 /usr/share/mysql（mysql.server命令及配置文件） <br /><br />　　 3、相关命令 <br />　　 /usr/bin(mysqladmin mysqldump等命令) <br /><br />　　 4、启动脚本 <br />　　 /etc/rc.d/init.d/（启动脚本文件mysql的目录） <br />　 五、修改登录密码 <br /><br />　　 MySQL默认没有密码，安装完毕增加密码的重要性是不言而喻的。 <br /><br />　　 1、命令 <br />　　 usr/bin/mysqladmin -u root password 'new-password' <br />　　 格式：mysqladmin -u用户名 -p旧密码 password 新密码 <br /><br />　　 2、例子 <br />　　 例1：给root加个密码123456。 <br />　　 键入以下命令 ： <br />　　 [root@test1 local]# /usr/bin/mysqladmin -u root password 123456 <br />　　 注：因为开始时root没有密码，所以-p旧密码一项就可以省略了。 <br /><br />　　 3、测试是否修改成功 <br />　　 1）不用密码登录 <br />　　 [root@test1 local]# mysql <br />　　 ERROR 1045: Access denied for user: 'root@localhost' (Using password: NO) <br />　　 显示错误，说明密码已经修改。 <br />　　 2）用修改后的密码登录 <br />　　 [root@test1 local]# mysql -u root -p <br />　　 Enter password: (输入修改后的密码123456) <br />　　 Welcome to the MySQL monitor.　Commands end with ; or \g. <br />　　 Your MySQL connection id is 4 to server version: 4.0.16-standard <br />　　 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. <br />　　 mysql> <br />　　 成功！ <br />　　 这是通过mysqladmin命令修改口令，也可通过修改库来更改口令。 <br /><br />　　 六、启动与停止 <br /><br />　　 1、启动 <br />　　 MySQL安装完成后启动文件mysql在/etc/init.d目录下，在需要启动时运行下面命令即可。 <br />　　 [root@test1 init.d]# /etc/init.d/mysql start <br /><br />　　 2、停止 <br />　　 /usr/bin/mysqladmin -u root -p shutdown <br /><br />　　 3、自动启动 <br />　　 1）察看mysql是否在自动启动列表中 <br />　　 [root@test1 local]#　/sbin/chkconfig –list <br />　　 2）把MySQL添加到你系统的启动服务组里面去 <br />　　 [root@test1 local]#　/sbin/chkconfig　– add　mysql <br />　　 3）把MySQL从启动服务组里面删除。 <br />　　 [root@test1 local]#　/sbin/chkconfig　– del　mysql <br />七、更改MySQL目录 <br /><br />　　 MySQL默认的数据文件存储目录为/var/lib/mysql。假如要把目录移到/home/data下需要进行下面几步： <br /><br />　　 1、home目录下建立data目录 <br />　　 cd /home <br />　　 mkdir data <br /><br />　　 2、把MySQL服务进程停掉： <br />　　 mysqladmin -u root -p shutdown <br /><br />　　 3、把/var/lib/mysql整个目录移到/home/data <br />　　 mv /var/lib/mysql　/home/data/ <br />　　 这样就把MySQL的数据文件移动到了/home/data/mysql下 <br /><br />　　 4、找到my.cnf配置文件 <br />　　 如果/etc/目录下没有my.cnf配置文件，请到/usr/share/mysql/下找到*.cnf文件，拷贝其中一个到/etc/并改名为my.cnf)中。命令如下： <br />　　 [root@test1 mysql]# cp /usr/share/mysql/my-medium.cnf　/etc/my.cnf <br /><br />　　 5、编辑MySQL的配置文件/etc/my.cnf <br />　　 为保证MySQL能够正常工作，需要指明mysql.sock文件的产生位置。 修改socket=/var/lib/mysql/mysql.sock一行中等号右边的值为：/home/mysql/mysql.sock 。操作如下： <br />　　 vi　 my.cnf　　　 (用vi工具编辑my.cnf文件，找到下列数据修改之) <br />　　 # The MySQL server <br />　　　 [mysqld] <br />　　　 port　　　= 3306 <br />　　　 #socket　 = /var/lib/mysql/mysql.sock（原内容，为了更稳妥用“#”注释此行） <br />　　　 socket　 = /home/data/mysql/mysql.sock　　　（加上此行） <br /><br />　　 6、修改MySQL启动脚本/etc/rc.d/init.d/mysql <br />　　 最后，需要修改MySQL启动脚本/etc/rc.d/init.d/mysql，把其中datadir=/var/lib/mysql一行中，等号右边的路径改成你现在的实际存放路径：home/data/mysql。 <br />　　 [root@test1 etc]# vi　/etc/rc.d/init.d/mysql <br />　　 #datadir=/var/lib/mysql　　　　（注释此行） <br />　　 datadir=/home/data/mysql　　 （加上此行） <br /><br />　　 7、重新启动MySQL服务 <br />　　 /etc/rc.d/init.d/mysql　start <br />　　 或用reboot命令重启Linux <br />　　 如果工作正常移动就成功了，否则对照前面的7步再检查一下。 <br /><br />　　 八、MySQL的常用操作 <br /><br />　　 注意：MySQL中每个命令后都要以分号；结尾。 <br /><br />　　 1、显示数据库 <br />　　 mysql> show databases; <br />　　 +----------+ <br />　　 | Database | <br />　　 +----------+ <br />　　 | mysql　　| <br />　　 | test　　 | <br />　　 +----------+ <br />　　 2 rows in set (0.04 sec) <br />　　 Mysql刚安装完有两个数据库：mysql和test。mysql库非常重要，它里面有MySQL的系统信息，我们改密码和新增用户，实际上就是用这个库中的相关表进行操作。 <br /><br />　　 2、显示数据库中的表 <br />　　 mysql> use mysql; （打开库，对每个库进行操作就要打开此库，类似于foxpro ） <br />　　 Database changed <br /><br />　　 mysql> show tables; <br />　　 +-----------------+ <br />　　 | Tables_in_mysql | <br />　　 +-----------------+ <br />　　 | columns_priv　　| <br />　　 | db　　　　　　　| <br />　　 | func　　　　　　| <br />　　 | host　　　　　　| <br />　　 | tables_priv　　 | <br />　　 | user　　　　　　| <br />　　 +-----------------+ <br />　　 6 rows in set (0.01 sec) <br /><br />　　 3、显示数据表的结构： <br />　　 describe 表名; <br /><br />　　 4、显示表中的记录： <br />　　 select * from 表名; <br />　　 例如：显示mysql库中user表中的纪录。所有能对MySQL用户操作的用户都在此表中。 <br />　　 Select * from user; <br /><br />　　 5、建库： <br />　　 create database 库名; <br />　　 例如：创建一个名字位aaa的库 <br />　　 mysql> create databases aaa; <br />6、建表： <br />　　 use 库名； <br />　　 create table 表名 (字段设定列表)； <br />　　 例如：在刚创建的aaa库中建立表name,表中有id(序号，自动增长)，xm（姓名）,xb（性别）,csny（出身年月）四个字段 <br />　　 use aaa; <br />　　 mysql> create table name (id int(3) auto_increment not null primary key, xm char(8),xb char(2),csny date); <br />　　 可以用describe命令察看刚建立的表结构。 <br />　　 mysql> describe name; <br /><br />　　 +-------+---------+------+-----+---------+----------------+ <br />　　 | Field | Type　　| Null | Key | Default | Extra　　　　　| <br />　　 +-------+---------+------+-----+---------+----------------+ <br />　　 | id　　| int(3)　|　　　| PRI | NULL　　| auto_increment | <br />　　 | xm　　| char(8) | YES　|　　 | NULL　　|　　　　　　　　| <br />　　 | xb　　| char(2) | YES　|　　 | NULL　　|　　　　　　　　| <br />　　 | csny　| date　　| YES　|　　 | NULL　　|　　　　　　　　| <br />　　 +-------+---------+------+-----+---------+----------------+ <br /><br />　　 7、增加记录 <br />　　 例如：增加几条相关纪录。 <br />　　 mysql> insert into name values('','张三','男','1971-10-01'); <br />　　 mysql> insert into name values('','白云','女','1972-05-20'); <br />　　 可用select命令来验证结果。 <br />　　 mysql> select * from name; <br />　　 +----+------+------+------------+ <br />　　 | id | xm　 | xb　 | csny　　　 | <br />　　 +----+------+------+------------+ <br />　　 |　1 | 张三 | 男　 | 1971-10-01 | <br />　　 |　2 | 白云 | 女　 | 1972-05-20 | <br />　　 +----+------+------+------------+ <br /><br />　　 8、修改纪录 <br />　　 例如：将张三的出生年月改为1971-01-10 <br />　　 mysql> update name set csny='1971-01-10' where xm='张三'; <br /><br />　　 9、删除纪录 <br />　　 例如：删除张三的纪录。 <br />　　 mysql> delete from name where xm='张三'; <br /><br />　　 10、删库和删表 <br />　　 drop database 库名; <br />　　 drop table 表名； <br /><br />　　 九、增加MySQL用户 <br /><br />　　 格式：grant select on 数据库.* to 用户名@登录主机 identified by "密码" <br />例1、增加一个用户user_1密码为123，让他可以在任何主机上登录，并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MySQL，然后键入以下命令： <br /><br />　　 mysql> grant select,insert,update,delete on *.* to user_1@"%" Identified by "123"; <br />例1增加的用户是十分危险的，如果知道了user_1的密码，那么他就可以在网上的任何一台电脑上登录你的MySQL数据库并对你的数据为所欲为了，解决办法见例2。 <br /><br />　　 例2、增加一个用户user_2密码为123,让此用户只可以在localhost上登录，并可以对数据库aaa进行查询、插入、修改、删除的操作（localhost指本地主机，即MySQL数据库所在的那台主机），这样用户即使用知道user_2的密码，他也无法从网上直接访问数据库，只能通过MYSQL主机来操作aaa库。 <br /><br />　　 mysql>grant select,insert,update,delete on aaa.* to user_2@localhost identified by "123"; <br /><br />　　 用新增的用户如果登录不了MySQL，在登录时用如下命令： <br /><br />　　 mysql -u user_1 -p　-h 192.168.113.50　（-h后跟的是要登录主机的ip地址） <br /><br />　　 十、备份与恢复 <br /><br />　　 1、备份 <br /><br />　　 例如：将上例创建的aaa库备份到文件back_aaa中 <br /><br />　　 [root@test1 root]# cd　/home/data/mysql　(进入到库目录，本例库已由val/lib/mysql转到/home/data/mysql，见上述第七部分内容) <br />　　 [root@test1 mysql]# mysqldump -u root -p --opt aaa > back_aaa <br /><br />　　 2、恢复 <br /><br />　　 [root@test mysql]# mysql -u root -p ccc &lt; back_aaa
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/170496#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><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Mar 2008 13:12:14 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/170496</link>
        <guid>http://sussi.javaeye.com/blog/170496</guid>
      </item>
      <item>
        <title>判断给定日期是否为当天</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/166387" style="color:red;">http://sussi.javaeye.com/blog/166387</a>&nbsp;
          发表时间: 2008年03月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          此函数可以用于实现对按时间排序的记录进行归类，比如：可以区分当天的记录，一周之内的记录和更早的记录。现在好多邮件系统都实现了此功能。 <br /><br />/** <br />* 判断给定日期是否为当天， <br /><br />*距离当前时间七天之内的日期，和七天之外的日期 <br /><br />* @param dt <br />* @param type 0--当天 1--7天之内的 2--7天之外的 <br />* @return <br />*/ <br />public static boolean getDayDiffFromToday(Date dt,int type){ <br />Date today=new Date(); <br />today.setHours(23); <br />today.setMinutes(59); <br />today.setSeconds(59); <br /><br />long diff = today.getTime() - dt.getTime(); <br />if(diff&lt;0)diff=0; <br />long days = diff/(1000*60*60*24); <br /><br />if(type==0 && days==0)return true; <br />if(type==1 && days>0 && days&lt;=7)return true; <br />if(type==2 && days>7)return true; <br /><br />return false; <br />}
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/166387#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><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 01 Mar 2008 15:49:24 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/166387</link>
        <guid>http://sussi.javaeye.com/blog/166387</guid>
      </item>
      <item>
        <title>MyEclipse的UML设计支持</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/165338" style="color:red;">http://sussi.javaeye.com/blog/165338</a>&nbsp;
          发表时间: 2008年02月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          MyEclipse的UML设计支持<br />本节主要介绍MyEclipse的UML设计支持功能。<br /><br />UML设计简介<br />统一建模语言(Unified Modeling Language，UML)是面向对象软件的标准化建模语言，由于其简单、统一，又能够表达软件设计中的动态和静态信息，目前已经成为可视化建模语言事实上的工业标准。UML提供了9种图，分别是：类图、对象图、用例图、序列图、协作图、状态图、活动图、构件图和部署图等。<br /><br />MyEclipse内置的UML设计支持功能可以满足一般的项目设计需要。本书中的兵马俑网上商城中的一些设计工作就是借助MyEclipse的UML设计支持功能完成的。本节将以常见的类图设计为例，简单介绍MyEclipse的UML设计功能。<br /><br />简单类设计案例<br />本节将设计一个简单的商品类Goods的类图。<br /><br />（1）单击“文件→新建→其他”菜单，弹出如图1 所示对话框。选择MyEclipse项目下子项目UML，再选择子项目UML Model Repository。<br /><br />（2）单击“下一步”按钮，弹出如图2 所示对话框。“UML Model Repository”设为at1test。<br /><br />  <br /><br />         图1   新建UML Model Repository                                 图2   新建UML文件<br /><br />（3）单击“完成”按钮，进入UML可视化编辑设计器。如图3 所示。其中空白区域为UML设计区。<br /><br />（4）借助类图设计工具设计类Goods如图4 所示。<br /><br />     <br /><br />         图3 UML可视化编辑设计器                                    图4 Goods类图<br /><br />生成Java代码<br />Goods类图设计完成后，就可以借助MyEclise的Java代码自动生成功能生成Java代码。<br /><br />（1）单击“UML→Generate Java”菜单，弹出如图5 所示对话框。选择Goods类。<br /><br /><br /><br />图5    生成Java代码<br /><br />（2）单击“完成”按钮。MyEclipse自动将Goods类图转换成以下源代码。<br /><br />代码14-4   文件名：Goods.Java<br /><br />/*<br /><br />*/<br /><br />public class Goods {<br /><br />   public String goods_id;<br /><br />   public int goods_name;<br /><br />   public float price;<br /><br />   public float discount;<br /><br />   public int getGoods_id() {<br /><br />   return 0;<br /><br />   }<br /><br />   public void setGoods_id(void Goods_id) {<br /><br />   }<br /><br />   public String getGoods_name() {<br /><br />   return null;<br /><br />   }<br /><br />   public void setGoods_name(String goods_name) {<br /><br />   }<br /><br />   public float getPrice() {<br /><br />   return 0.0f;<br /><br />   }<br /><br />   public void setPrice(float Price) {<br /><br />   }<br /><br />   public float getDiscount() {<br /><br />   return 0.0f;<br /><br />   }<br /><br />   public void setDiscount(float Discount) {<br /><br />   }<br /><br />}<br /><br />逆向Java代码<br />MyEclise还支持反向工程。例如可以将Java 类代码逆向转换为UML 类图设计。本节以DB_Conn类为例，介绍逆向Java代码功能。<br /><br />（1）将第14章里的DB_Conn.java代码拷贝到src目录。<br /><br />（2）单击“UML→Reverse Engineer UML From Java…”菜单，弹出如图6 所示对话框。选择DB_conn.java文件。<br /><br />（3）单击“下一步”按钮，弹出如图7 所示对话框。将“Hide class/interface details”选项去掉。<br /><br />  <br /><br />    图6   逆向Java代码                                        图7   逆向Java代码功能选项  <br /><br />（4）单击“完成”按钮。MyEclipse自动将DB_Conn.java源代码逆向为DB_Conn类图。如图8 所示。<br /><br /><br /><br />图8   DB_Conn类图
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/165338#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</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>Wed, 27 Feb 2008 09:36:58 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/165338</link>
        <guid>http://sussi.javaeye.com/blog/165338</guid>
      </item>
      <item>
        <title>Eclipse的UML插件</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/165326" style="color:red;">http://sussi.javaeye.com/blog/165326</a>&nbsp;
          发表时间: 2008年02月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          不久我听到有人在谈论Eclipse。开始我以为他们是在谈论日食，后来我才知道是那个IDE。他们谈到版本更新的速度是多么快，有时很难使插件保持最新。对此我深有感触，因为上周我花了很多业余时间试图找到一个支持Eclipse的好的UML建模插件。<br /><br />　　关于UML，我的最大问题就是，在开始编码之后，模型通常会过时，它们不再反映系统的状态。所以我的核心需求是向前/向后设计，即，如果我更改了代码，模型就会更新；反之亦然。我的第二个需求是导出到图像。第三个是成本。能够免费当然是最好不过了，不过如果物有所值，我也愿意付出一点点成本。<br /><br />　　所以我开始寻找支持Eclipse v3.1的UML插件。很快这个需求就淘汰了一些选项，例如Together（除了缺乏支持外，我还不明白它为什么会如此昂贵，Rational产品也一样）和Posiedon（两周之前，我给Posiedon方面发了一封邮件，他们回复说“我们正在解决这个问题”。刚才我查看了他们的网站，他们现在支持3.1了。非常棒！）。我本来还可以使用MagicDraw，但是我不喜欢他们的“插件”方法。对我来说，插件应该是集成的，能为我提供一种新的Eclipse视角。MagicDraw的产品只是基于Eclipse中的一个动作。<br /><br />　　接下来我试了Visual Paradigm。它看起来不错，根据我的调查，它支持我所需要的一切。但是我不喜欢类图等等的可视化表示。然后是Omondo。我以前从未听说过这个建模工具，它的无缝集成给我留下很深的印象。社区版本(community edition)就很不错，但是它少了商业版本的几种功能，但是我一看价格：990欧元！噢，算了吧……<br /><br />　　最后我想到了一个一直很受欢迎的插件，MyEclipse。它的年订费是$29.95。以前的版本（应该是指v4以前的版本吧？）不支持UML建模，我很高兴它现在支持了。我开始绕过它的主要原因是，我知道该产品的许多优势是通过Web Tools Platform项目提供的，我不想与别人挤在一起。最后我试用了一下，发现新版本非常不错，正是我所需要的。它的订费不是很高，而且我可以获得Omondo商业版的大部分功能（比如type4数据库管理）。<br /><br />　　现在我的心情又转好了。我希望我的房间里不会再有成堆的过时了的UML图了。
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/165326#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</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>Wed, 27 Feb 2008 08:57:50 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/165326</link>
        <guid>http://sussi.javaeye.com/blog/165326</guid>
      </item>
      <item>
        <title>could not initialize proxy - Session was closed</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/164219" style="color:red;">http://sussi.javaeye.com/blog/164219</a>&nbsp;
          发表时间: 2008年02月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          可能原因：<br />        当&lt;class>元素或者&lt;set>元素的lazy属性为true时，load() or get() or find()加载这些对象时，Hibernate不会马上产生任何select语句，只是产生一个Obj代理类实例，只有在session没有关闭的情况下运行Obj.getXxx()时才会执行select语句从数据库加载对象，如果没有运行任何Obj.getXxx()方法，而session已经关闭，Obj已成游离状态，此时再运行Obj.getXxx()方法，Hibernate就会抛出"Could not initialize proxy - the owning Session was closeed"的异常，是说Obj代理类实例无法被初始化。然而想在Session关闭之前不调用Obj.getXxx()方法而关闭Session之后又要用，此时只要在Session关闭之前调用Hibernate.initialize(Obj)或者Hibernate.initialize(Obj.getXxx())即可，net.sf.hibernate.Hibernate类的initialize()静态方法用于在Session范围内显示初始化代理类实例。<br /><br />解决方法：<br />        所以，在映射文件中，将lazy属性设为false即可，&lt;class name="cssduty.table.Team" table="team" catalog="duty" lazy="false">
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/164219#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</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, 22 Feb 2008 14:41:01 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/164219</link>
        <guid>http://sussi.javaeye.com/blog/164219</guid>
      </item>
      <item>
        <title>java正则表达式</title>
        <author>sovolee</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sussi.javaeye.com">sovolee</a>&nbsp;
          链接：<a href="http://sussi.javaeye.com/blog/164204" style="color:red;">http://sussi.javaeye.com/blog/164204</a>&nbsp;
          发表时间: 2008年02月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          字符串处理是许多程序中非常重要的一部分,它们可以用于文本显示,数据表示,查找键和很多目的.在Unix下,用户可以使用正则表达式的强健功能实现这些目的,从Java1.4起,Java核心API就引入了java.util.regex程序包,它是一种有价值的基础工具,可以用于很多类型的文本处理, 如匹配,搜索,提取和分析结构化内容.<br /><br />java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类：Pattern和Matcher.<br /><br />Pattern是一个正则表达式经编译后的表现模式。 在java中,通过适当命名的Pattern类可以容易确定String是否匹配某种模式.模式可以象匹配某个特定的String那样简单,也可以很复杂,需要采用分组和字符类,如空白,数字,字母或控制符.因为Java字符串基于统一字符编码(Unicode),正则表达式也适用于国际化的应用程序.<br /><br />Pattern类的方法简述<br /><br />方法 说明 <br />static Pettern compile(String regex,int flag) 编译模式,参数regex表示输入的正则表达式,flag表示模式类型(Pattern.CASE_INSENSITIVE 表示不区分大小写) <br />Matcher match(CharSequence input) 获取匹配器,input时输入的待处理的字符串 <br />static boolean matches(String regex, CharSequence input) 快速的匹配调用,直接根据输入的模式regex匹配input <br />String[] split(CharSequence input,int limit) 分隔字符串input,limit参数可以限制分隔的次数 <br /><br /><br /><br />Matcher 一个Matcher对象是一个状态机器，它依据Pattern对象做为匹配模式对字符串展开匹配检查。首先一个Pattern实例订制了一个所用语法与 PERL的类似的正则表达式经编译后的模式，然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作。<br /><br />Matcher类的方法简述<br /><br />方法 说明 <br />boolean matches() 对整个输入字符串进行模式匹配. <br />boolean lookingAt() 从输入字符串的开始处进行模式匹配 <br />boolean find(int start) 从start处开始匹配模式 <br />int groupCount() 返回匹配后的分组数目 <br />String replaceAll(String replacement) 用给定的replacement全部替代匹配的部分 <br />String repalceFirst(String replacement) 用给定的replacement替代第一次匹配的部分 <br />Matcher appendReplacement(StringBuffer sb,String replacement) 根据模式用replacement替换相应内容,并将匹配的结果添加到sb当前位置之后 <br />StringBuffer appendTail(StringBuffer sb) 将输入序列中匹配之后的末尾字串添加到sb当前位置之后. <br /><br /><br /><br />正则表达式中常见通配符:<br /><br />对于单字符串比较而言,使用正则表达式没有什么优势.Regex的真正强大之处在于体现在包括字符类和量词(*,+,?)的更复杂的模式上.<br /><br />字符类包括:<br /><br />\d 数字<br /><br />\D 非数字<br /><br />\w 单字字符(0-9,A-Z,a-z)<br /><br />\W 非单字字符<br /><br />\s 空白(空格符,换行符,回车符,制表符)<br /><br />\S 非空白<br /><br />[] 由方括号内的一个字符列表创建的自定义字符类<br /><br />. 匹配任何单个字符<br /><br />下面的字符将用于控制将一个子模式应用到匹配次数的过程.<br /><br />? 重复前面的子模式0次到一次<br /><br />* 重复前面的子模式0次或多次<br /><br />+ 重复前面的子模式一次到多次<br /><br />以下是实例部分:<br /><br />实例一:<br /><br />正则式是最简单的能准确匹配一个给定String的模式,模式与要匹配的文本是等价的.静态的Pattern.matches方法用于比较一个String是否匹配一个给定模式.例程如下:<br /><br />String data="java";<br /><br />boolean result=Pattern.matches("java",data);<br /><br />实例二:<br /><br />String[] dataArr = { "moon", "mon", "moon", "mono" };<br /><br />for (String str : dataArr) {<br /><br />String patternStr="m(o+)n";<br /><br /><br />boolean result = Pattern.matches(patternStr, str);<br /><br />if (result) {<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"成功");<br /><br />}<br /><br />else{<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"失败");<br /><br />}<br /><br />}<br /><br />模式是”m(o+)n”,它表示mn中间的o可以重复一次或多次,因此moon,mon,mooon能匹配成功,而mono在n后多了一个o,和模式匹配不上.<br /><br />注:<br /><br />+表示一次或多次;?表示0次或一次;*表示0次或多次.<br /><br />实例三:<br /><br />String[] dataArr = { "ban", "ben", "bin", "bon" ,"bun","byn","baen"};<br /><br />for (String str : dataArr) {<br /><br />String patternStr="b[aeiou]n";<br /><br /><br />boolean result = Pattern.matches(patternStr, str);<br /><br />if (result) {<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"成功");<br /><br />}<br /><br />else{<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"失败");<br /><br />}<br /><br />}<br /><br />注:方括号中只允许的单个字符,模式“b[aeiou]n”指定,只有以b开头,n结尾,中间是a,e,i,o,u中任意一个的才能匹配上,所以数组的前五个可以匹配,后两个元素无法匹配.<br /><br />方括号[]表示只有其中指定的字符才能匹配.<br /><br />实例四:<br /><br />String[] dataArr = { "been", "bean", "boon", "buin" ,"bynn"};<br /><br />for (String str : dataArr) {<br /><br />String patternStr="b(ee|ea|oo)n";<br /><br /><br />boolean result = Pattern.matches(patternStr, str);<br /><br />if (result) {<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"成功");<br /><br />}<br /><br />else{<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"失败");<br /><br />}<br /><br />}<br /><br />如果需要匹配多个字符,那么[]就不能用上了,这里我们可以用()加上|来代替,()表示一组,|表示或的关系,模式b(ee|ea|oo)n就能匹配been,bean,boon等.<br /><br />因此前三个能匹配上,而后两个不能.<br /><br />实例五:<br /><br />String[] dataArr = { "1", "10", "101", "1010" ,"100+"};<br /><br />for (String str : dataArr) {<br /><br />String patternStr="\d+";<br /><br /><br />boolean result = Pattern.matches(patternStr, str);<br /><br />if (result) {<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"成功");<br /><br />}<br /><br />else{<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"失败");<br /><br />}<br /><br />}<br /><br />注:从前面可以知道,\d表示的是数字,而+表示一次或多次,所以模式\d+就表示一位或多位数字.<br /><br />因此前四个能匹配上,最后一个因为+号是非数字字符而匹配不上.<br /><br />实例六:<br /><br />String[] dataArr = { "a100", "b20", "c30", "df10000" ,"gh0t"};<br /><br />for (String str : dataArr) {<br /><br />String patternStr="\w+\d+";<br /><br /><br />boolean result = Pattern.matches(patternStr, str);<br /><br />if (result) {<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"成功");<br /><br />}<br /><br />else{<br /><br />System.out.println("字符串"+str+"匹配模式"+patternStr+"失败");<br /><br />}<br /><br />}<br /><br />模式\w+\d+表示的是以多个单字字符开头,多个数字结尾的字符串,因此前四个能匹配上,最后一个因为数字后还含有单字字符而不能匹配.<br /><br />实例七:<br /><br />String str="薪水,职位 姓名;年龄 性别";<br /><br />String[] dataArr =str.split("[,\s;]");<br /><br />for (String strTmp : dataArr) {<br /><br />System.out.println(strTmp);<br /><br />}<br /><br />String类的split函数支持正则表达式,上例中模式能匹配”,”,单个空格,”;”中的一个,split函数能把它们中任意一个当作分隔符,将一个字符串劈分成字符串数组.<br /><br />实例八:<br /><br />String str="2007年12月11日";<br /><br />Pattern p = Pattern.compile("[年月日]");<br /><br />String[] dataArr =p.split(str);<br /><br />for (String strTmp : dataArr) {<br /><br />System.out.println(strTmp);<br /><br />}<br /><br />Pattern是一个正则表达式经编译后的表现模式 ,它的split方法能有效劈分字符串.<br /><br />注意其和String.split()使用上的不同.<br /><br />实例九:<br /><br />String str="10元 1000人民币 10000元 100000RMB";<br /><br />str=str.replaceAll("(\d+)(元|人民币|RMB)", "￥");<br /><br />System.out.println(str);<br /><br />上例中,模式“(\d+)(元|人民币|RMB)”按括号分成了两组,第一组\d+匹配单个或多个数字,第二组匹配元,人民币,RMB中的任意一个,替换部分表示第一个组匹配的部分不变,其余组替换成￥.<br /><br />替换后的str为￥10 ￥1000 ￥10000 ￥100000<br /><br />实例十:<br /><br />Pattern p = Pattern.compile("m(o+)n",Pattern.CASE_INSENSITIVE);<br /><br />// 用Pattern类的matcher()方法生成一个Matcher对象<br /><br />Matcher m = p.matcher("moon mooon Mon mooooon Mooon");<br /><br />StringBuffer sb = new StringBuffer();<br /><br />// 使用find()方法查找第一个匹配的对象<br /><br />boolean result = m.find();<br /><br />// 使用循环找出模式匹配的内容替换之,再将内容加到sb里<br /><br />while (result) {<br /><br />m.appendReplacement(sb, "moon");<br /><br />result = m.find();<br /><br />}<br /><br />// 最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里；<br /><br />m.appendTail(sb);<br /><br />System.out.println("替换后内容是" + sb.toString());<br /><br />实例十一:<br /><br />除了用+表示一次或多次,*表示0次或多次,?表示0次或一次外,还可以用{}来指定精确指定出现的次数,X{2,5}表示X最少出现2次,最多出现5次;X{2,}表示X最少出现2次,多则不限;X{5}表示X只精确的出现5次.<br /><br />例程:<br /><br />String[] dataArr = { "google", "gooogle", "gooooogle", "goooooogle","ggle"};<br /><br />for (String str : dataArr) {<br /><br />String patternStr = "g(o{2,5})gle";<br /><br />boolean result = Pattern.matches(patternStr, str);<br /><br />if (result) {<br /><br />System.out.println("字符串" + str + "匹配模式" + patternStr + "成功");<br /><br />} else {<br /><br />System.out.println("字符串" + str + "匹配模式" + patternStr + "失败");<br /><br />}<br /><br />}<br /><br />实例十二:<br /><br />-表示从..到…,如[a-e]等同于[abcde]<br /><br />String[] dataArr = { "Tan", "Tbn", "Tcn", "Ton","Twn"};<br /><br />for (String str : dataArr) {<br /><br />String regex = "T[a-c]n";<br /><br />boolean result = Pattern.matches(regex, str);<br /><br />if (result) {<br /><br />System.out.println("字符串" + str + "匹配模式" + regex + "成功");<br /><br />} else {<br /><br />System.out.println("字符串" + str + "匹配模式" + regex + "失败");<br /><br />}<br /><br />}<br /><br />实例十三:不区分大小写匹配.<br /><br />正则表达式默认都是区分大小写的,使用了Pattern.CASE_INSENSITIVE则不对大小写进行区分.<br /><br />String patternStr="ab";<br /><br />Pattern pattern=Pattern.compile(patternStr, Pattern.CASE_INSENSITIVE);<br /><br /><br />String[] dataArr = { "ab", "Ab", "AB"};<br /><br /><br />for (String str : dataArr) {<br /><br />Matcher matcher=pattern.matcher(str);<br /><br /><br />if(matcher.find()){<br /><br />System.out.println("字符串" + str + "匹配模式" + patternStr + "成功");<br /><br />}<br /><br />}<br /><br />实例十四:使用正则表达式劈分字符串.<br /><br />注意这里要把复杂的模式写在前面,否则简单模式会先匹配上.<br /><br />String input="职务=GM 薪水=50000 , 姓名=职业经理人 ; 性别=男 年龄=45 ";<br /><br />String patternStr="(\s*,\s*)|(\s*;\s*)|(\s+)";<br /><br />Pattern pattern=Pattern.compile(patternStr);<br /><br /><br />String[] dataArr=pattern.split(input);<br /><br /><br />for (String str : dataArr) {<br /><br />System.out.println(str);<br /><br />}<br /><br />实例十五:解析正则表达式中的文字,\1对应第一个小括号括起来的group1.<br /><br />String regex="&lt;(\w+)>(\w+)&lt;/\1>";<br /><br />Pattern pattern=Pattern.compile(regex);<br /><br /><br />String input="&lt;name>Bill&lt;/name>&lt;salary>50000&lt;/salary>&lt;title>GM&lt;/title>";<br /><br /><br />Matcher matcher=pattern.matcher(input);<br /><br /><br />while(matcher.find()){<br /><br />System.out.println(matcher.group(2));<br /><br />}<br /><br />实例十六:将单词数字混合的字符串的单词部分大写.<br /><br />String regex="([a-zA-Z]+[0-9]+)";<br /><br />Pattern pattern=Pattern.compile(regex);<br /><br /><br />String input="age45 salary500000 50000 title";<br /><br /><br />Matcher matcher=pattern.matcher(input);<br /><br /><br />StringBuffer sb=new StringBuffer();<br /><br /><br />while(matcher.find()){<br /><br />String replacement=matcher.group(1).toUpperCase();<br /><br />matcher.appendReplacement(sb, replacement);<br /><br />}<br /><br />matcher.appendTail(sb);<br /><br /><br />System.out.println("替换完的字串为"+sb.toString());
          <br/>
          <span style="color:red;">
            <a href="http://sussi.javaeye.com/blog/164204#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/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Feb 2008 13:59:25 +0800</pubDate>
        <link>http://sussi.javaeye.com/blog/164204</link>
        <guid>http://sussi.javaeye.com/blog/164204</guid>
      </item>
  </channel>
</rss>