HTTP 状态代码什么意思?

如果某项请求发送到您的服务器要求显示您网站上的某个网页,服务器将会返回 HTTP 状态码响应请求。

下面提供 HTTP 状态代码的完整列表,您也可以访问 HTTP 状态代码上的 W3C 页获取更多信息(英文)

1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码。
代码 说明
100(继续) 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
101(切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。

2xx (成功)表示成功处理了请求的状态代码。
代码 说明
200(成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 如果针对您的 robots.txt 文件显示此状态代码,则表示 Googlebot 已成功检索到该文件。
201(已创建) 请求成功并且服务器创建了新的资源。
202(已接受) 服务器已接受请求,但尚未处理。
203(非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204(无内容) 服务器成功处理了请求,但没有返回任何内容。
205(重置内容) 服务器成功处理了请求,但没有返回任何内容。 与 204 响应不同,此响应要求请求者重置文档视图(例如,清除表单内容以输入新内容)。
206(部分内容) 服务器成功处理了部分 GET 请求。

3xx (重定向)要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
代码 说明
300(多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301(永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。 您应使用此代码告诉 Googlebot 某个网页或网站已永久移动到新位置。
302(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303(查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。 对于除 HEAD 之外的所有请求,服务器会自动转到其他位置。
304(未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305(使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307(临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

4xx(请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
代码 说明
400(错误请求) 服务器不理解请求的语法。
401(未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403(禁止) 服务器拒绝请求。
404(未找到) 服务器找不到请求的网页。 例如,对于服务器上不存在的网页经常会返回此代码。
405(方法禁用) 禁用请求中指定的方法。
406(不接受) 无法使用请求的内容特性响应请求的网页。
407(需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。 如果服务器返回此响应,还会指明请求者应当使用的代理。
408(请求超时) 服务器等候请求时发生超时。
409(冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 服务器在响应与前一个请求相冲突的 PUT 请求时可能会返回此代码,同时会附上两个请求的差异列表。
410(已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411(需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412(未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413(请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414(请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415(不支持的媒体类型) 请求的格式不受请求页面的支持。
416(请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417(未满足期望值) 服务器未满足”期望”请求标头字段的要求。

5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
代码 说明
500(服务器内部错误) 服务器遇到错误,无法完成请求。
501(尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502(错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503(服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505(HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

Linux、Ubuntu和Suse的正确发音

今天看了一段央视《东方时空》的视频,视频内容主要是讲解的网络上议论纷纷的“番茄花园”事件,在这段视频的后半段提到了Windows的“替代品 ”:Linux。本来介绍开源和自由的Linux是一件好事,可是视频中的红旗公司的那位大侠居然连指望吃饭的“Linux”都念错,而且记者也是发音错 误,他们也倒是蛮统一的,都把Linux念做lei niu ke si,看完视频以后巨汗。

据我所知,或者我上高中的时候就记得Linux的发音是“li na ke si”,到网上进行求证后更验证我的记忆,呵呵~再此,告诉大家Linux的正确发音是 “li na ke si”或者“哩呐克斯”,音标是 ['li:nэks],还是不够形象生动的话,这里还有段录音供您试听,下载地址:Linux正确发音

顺便提一下Linux的一个发行版: Ubuntun。Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音,大多数的美国人读 ubuntu 时,将 u 作为元音发音,类似单词 who 或者 boo ,重音在第二个音节即 u’buntu ,oo-boon-too,如果您喜欢撒哈拉大沙漠,喜欢它令人窒息的温柔、梦幻般的寂寥还有张扬恣肆的旷远,您大可在第一个 u,后面带些嗡嗡声: oom-boon-too,总结下来,Ubuntu的中文发音大约为: 乌班图。

还有美轮美奂的Suse,Suse发音通常是/suzi/,正确应为/zuzə/,Suse是德国的一个Linux发行 版。Suse是”S.u.S.E.”的简写,意思为”Software- und System-Entwicklung”,那是一句德文,英文为”Software and system development”,Suse的正确发音试听下载:Suse的正确发音

在windows环境下,让Tomcat 6.0支持PHP 5

系统:Windows XP Pro SP2
Tomcat:apache-tomcat-6.0.14
PHP:php-5.2.5-Win32
(Tomact和PHP均使用ZIP压缩包)

1. 解压缩Tomcat至"D:\apache-tomcat-6.0.14";解压缩PHP至"D:\php-5.2.5-Win32"。
2.下载 PECL 5.2.5 Win32 binaries,解压缩至任意路径。(PHP和PECL版本须一致,本例中均为5.2.5)
3.将"D:\php-5.2.5-Win32"中的"php.ini-dist"改名为"php.ini"。
4.在"php.ini"中找到"Dynamic Extensions"部分,添加"extension=php_java.dll"。
5.将"PECL 5.2.5 Win32 binaries"压缩包中的" php5servlet.dll"解压缩至"D:\php-5.2.5-Win32"。
6.将"PECL 5.2.5 Win32 binaries"压缩包中的"php_java.dll"解压缩至"D:\php-5.2.5-Win32\ext"。
7.在"D:\apache-tomcat-6.0.14\webapps"中建立应用程序目录。(例如PHPTest)
8.将"PECL 5.2.5 Win32 binaries"压缩包中的" phpsrvlt.jar"解压缩至"D:\apache-tomcat-6.0.14\webapps\PHPTest\WEB-INF\lib"。
9. 解压缩"phpsrvlt.jar"(jar xfv phpsrvlt.jar),将"net\php\reflect.properties"以及"net\php \servlet.properties"文件内容修改为"library=php5servlet"。(内容保持为一行,且任何位置不可有空格或其他符号)
10.重新建立"phpsrvlt.jar"压缩包(jar cvf phpsrvlt.jar net/php/*.*)。
11.在"D:\apache-tomcat-6.0.14\webapps\PHPTest\WEB-INF"目录建立"web.xml"描述文件:
---------------------------------------------------web.xml------------------------------------------------------------------
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance "
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd ">

php
net.php.servlet


php-formatter
net.php.formatter


php
*.php


php-formatter
*.phps

---------------------------------------------------web.xml------------------------------------------------------------------
12.将"D:\php-5.2.5-Win32"添加至系统变量"PATH"。
13.在"D:\apache-tomcat-6.0.14\webapps\PHPTest"目录建立"phpinfo.php":
---------------------------------------------------phpinfo.php-------------------------------------------------------------

---------------------------------------------------phpinfo.php-------------------------------------------------------------
14.启动Tomcat。(D:\apache-tomcat-6.0.14\bin\startup.bat)
15.使用阅览器访问"http://localhost:8080/PHPTest/phpinfo.php"。

参考文档: Running php 5.x on windows using tomcat 4.x or 5.x

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数-ecoding GBK或-ecoding gb2312编译;对于JSP,在文件头加上<%@ page contentType="text/html;charset=GBK"%>或<%@ page contentType="text/html;charset=gb2312"%>基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序 byte->char
从java程序到页面显示 char—>byte

从数据库到java程序 byte—>char
从java程序到数据库 char—>byte

从文件到java程序 byte->char
从java程序到文件 char->byte

从流到java程序 byte->char
从java程序到流 char->byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码
JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding("GBK")或request.setCharacterEncoding("gb2312")。
如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType("text/html;charset=GBK")或response.setContentType("text/html;charset=gb2312")解决。
如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:
web.xml:


CharacterEncodingFilter
net.vschool.web.CharacterEncodingFilter

encoding
GBK



CharacterEncodingFilter
/*


CharacterEncodingFilter.java:

public class CharacterEncodingFilter implements Filter
{

protected String encoding = null;

public void init(FilterConfig filterConfig) throws ServletException
{
this.encoding = filterConfig.getInitParameter("encoding");
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
chain.doFilter(request, response);
}

}


2、Java与数据库之间的乱码
大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。

3、Java与文件/流之间的乱码
Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中 FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的 FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。

4、其他
上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1 );
改成了
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1, charset );
终于解决了这个乱码问题。

Web 3.0

Web 3.0的最大价值不是提供信息,而是提供基于不同需求的过滤器,每一种过滤器都是基于一个市场需求。如果说Web 2.0解决了个性解放的问题,那么Web 3.0就是解决信息社会机制的问题,也就是最优化信息聚合的问题。

《纽约时报》商业栏目记者John Markoff曾在一篇文章中写道:“人们对Web 3.0或者说是语义网的商业兴趣正在凸现。”这句话虽未对Web 3.0给出明确定义,但不管怎样,语义网这一概念在《New York Times》商业栏目中的出现,我们也看到了未来的发展趋势。

语义网(Semantic Web)之路

简单地说,语义网是一种能理解人类语言的智能网络,它不但能够理解人类的语言,而且还可以使人与电脑之间的交流变得像人与人之间交流一样轻松。

语义网将使人类从搜索相关网页的繁重劳动中解放出来。因为网中的计算机能利用自己的智能软件,在搜索数以万计的网页时,通过“智能代理”从中筛选出相关的有用信息。而不像现在的万维网,只给你罗列出数以万计的无用搜索结果。

目前,在RDF(Resource Description Framework,资源描述框架)和OWL(Web Ontology Language,网络实体语言)的支持下,语义网已经成为能够牢牢嵌入现有网页并且能完善RDF知识储备的新科技,而其理念雏形可追溯至10年之前。

1998年,Tim Berners-Lee就提出了语义网的理念。一些人认为它是关于AI(人工智能)的,另一部分人认为它更多是关于语言学的,还有一些人则认为它是关于数 据注释的。而维基百科对语义网给出了这样的定义:一种使用可以被电脑理解的方式描述事物的网络。其实,作为AI的一部分,语义网涉及的范围应该是围绕着对 自我的理解和对与我们相关数据的理解。所以,人们可以在开发Web或研究AI的过程中不断地学习和理解语义网。

在Web上,我们已经看到了一些成功的商业模式,如Netscape建成的一个资源互享环境,Amazon和eBay的市场优势,以及Yahoo和 Google的网站广告模式。资源共享带给我们前所未有的改变,不过这种分享精神也可能导致所谓的长尾现象。举个买书的例子,在各大网站显要位置推荐的都 不会是最好卖的书籍,但过段时间,这些书的销量就会直线飙升,甚至远远超过一些畅销书籍。在这一过程中,链接是真正让搜索引擎工作的发动机,AI应用程序 必须与其他事物联系起来才能为我们创造财富。如果仅将其视为一种工具,将很难得到用户青睐。因此,对AI来说,智能设备具有划时代意义,而如何使用这些工 具将变得更加重要。

也许很多人认为Web 2.0已乏善可陈,但Web 2.0的动向曲线中还是可见不少有趣现象。总的来说,Web 2.0是网络科技的社会进化,它去掉了网络上合作性质的信息发布,加入了Tagging(标签)和Microformats(微缩过程)的技术,使得信息 的产生和选择升级至一个新阶段,这是Web 2.0的本质。可以预见,在未来几年中,Web 2.0将完成向Web 3.0,即语义网的转变。

web3.0带来新体验

在过去一年中,语义网概念更加深入人心,这得益于RDF语言和能够支持RDF语言的科技的成熟。

与传统结构的数据库相比,RDF数据库拥有诸多优势。针对这些优势,微软于2006年12月在其连接服务框架(Connected Services Framework 3.0)开发者指导中指出,RDF数据库让用户能够灵活地在计划图表中存储当初设计图表时没有考虑到的数据。不仅如此,RDF还可以帮助开发者拉近Web 与数据之间的距离,而这些都是传统的关系数据库做不到的。随着人们对RDF更多的认可,RDF自然成为了最重要的标准查询语言。

在所有服务中最重要的无疑就是信息搜索服务,作为对RSS高度整合的Web 3.0,搜索也被高度整合。人们只需要输入自己的需求,就可以迅速得到所需信息,甚至一套完整的解决方案。例如,在计算机中输入:“我想带我11岁的孩子 去一个温暖的地方度假,我的预算为3000美元。”计算机能自动给出一套完整方案,这一方案可能包括度假路线图、适合选择的航班、价格适宜的酒店等。可以 预见,承接Web 2.0的以人为本理念,Web 3.0模式中将会出现各种高度细分领域的平民专家。

即将到来的时代

中国互联网自进入Web 2.0时代后,在近3年内获得了高速发展,这种发展呈现出两种趋势,第一种趋势是基于用户的一个需求点,力图在一个平台上整合所有互联网服务。如博客中国 向综合门户阵营的靠拢,腾讯转型为综合门户。但这些转变更多的只是为了增加流量和提高用户黏性。

第二种趋势是在用户个别的需求点上进行深度挖掘,纵深发展。如淘宝、奇虎和Donews等。这类公司目前仅仅是业务领域的细分,并没有根据人群进行 细分,因此为了提升关注度,他们同样在做综合门户所做的事情,于是纷纷被打上Web 2.0标签,但信息依然散乱,用户依然海量而缺乏细分,而广告主依然因不知该在哪里投放广告而大伤脑筋。可以说,即便借助Web 3.0,这些公司的运作模式依然还是2.0思维。

真正的Web 3.0不仅止于根据用户需求提供综合化服务,创建综合化服务平台,关键在于提供基于用户偏好的个性化聚合服务。在Web 3.0时代,同一模式化的综合门户将不复存在,如人们看到的新浪新闻首页将是个人感兴趣的新闻,而那些他不感兴趣的新闻将不会显示。当然,这种个性化的聚 合必须依赖强大的智能化识别系统,以及长期对于一个用户互联网行为规律的分析和锁定,它将颠覆传统的综合门户,使得Web 3.0时代的互联网评价标准不再是流量和点击率,而是到达率和用户价值。

因此,Web 3.0时代能够赢得用户青睐的公司,一定是基于用户行为、习惯和信息的聚合而构建的,人性化、友好界面、简单易用一定是其核心元素,基于用户需求的信息聚合才是互联网的趋势和未来。

在网页的HEAD部分中包含有许多内置标签,规范填写这些标签,非常有助于网站的推广。

meta标签是内嵌在你网页中的特殊html标签,包含着你有关于你网页的一些隐藏信息。Meat标签的作用是向搜索引擎解释你的网页是有关哪方面 信息的。对于高级的搜索引擎来说,html 的meta 标签并不是什么新奇的东西。但是无论如何它是一个优秀网页不可缺少的。下面我们就它进行一些讲解吧。

当你计划搜索引擎优化策略是meta标签是非常重要的。尽管如此,一般的加入meta 并不能帮助你在搜索引擎中获得更好的排名。有好几种meta标签,但重要的有以下几个:description标签,keywords标签,title标 签(严格来说title不算是一个标签)。当你不时刷新标签时这几个标签显得特别的重要。如果你希望搜索引擎对你的网站进行索引时就会用到html标签的 重定向(redirect)标签与robots标签。

注意:调查表只有20%的网页用到“关键字”与“描述”标签(即keyword,description)

多个关键字用英文逗号分开。

title 标签

title 标签可能是你网页中最重要的标签,它是你网页中最先看到的部分。把它放在description 与 keyword前。在这个标签中最好是加上你网站的关键字,title标签在搜索引擎的搜索中占有非常重要的地位。最好是把它放在其他meta标签前,这 更有利于你网站的排名。(注意:有些搜索引擎会按title标签的字母的优先权进行排名,尽量在你的title中使用开始的字母)title标签是人们在 搜索引擎中第一个看到有关你网站的描述,所以尽量把它弄得简单、明了。让人一看就知道你的网站是关于什么的。

Description标签

Description标签就在title后面,该标签可以是一小段(一个或者两个句子)。用于描述你网站。与title标签一样,这也是人们在搜 索引擎列表中链接到你网站的点击。这些描述将鼓动人们去浏览你的网站而不是你竞争对手的。(描述不能太夸张。不然,当访问者到你网站发现内容根本不是你说 的那个样子,那么他很快就会退出去。)很多搜索引擎允许描述的字数在150个左右,所以你要保证你的描述在150以下,否则搜索引擎会自动把多余的部分剪 去从而造成你网站的描述的不完整。搜索引擎认为描述里的关键字远比网页中的内容要重要(好像现在这种情况不是那么明显了)。真如上所述,这里提供了非常重 要的信息:确定你的描述能正确的反映你网站的主题,尽量在描述中加入你主要的关键字,越靠meta的关键字意义越大。这样会突显你的关键字。

现在大多的搜索引擎(google除外)都会支持descriptin标签。如果你不使用的话你将会失去排名靠前的可能。

keyword 标签

相比于description与title标签,keyword标签显得并不是那么重要了。有些搜索引擎把它完全地忽略,但是使用下正确的keyword标签对提高排名仍然有效。

除了搜索引擎外,一般情况下人们是看不到的。keyword标签是一个隐藏的标签,向搜索引擎提供了一组与你的页面有关的的关键字或关键短语列表。 你可以用相应的工具找出一系列适用于你网站的关键字。(注意:关键字标签中只能包括与你本页内容相关的关键字列表。所有在这里的关键字必须与页面的内容相 联系。)

提示:在你每一个页面中组织相关的关键字,每个页面必须专注于不同的产品或者内容。在标签中列满关键字对于提高你网站的排名并没有好处。多个关键字 间用逗号用隔,逗号表示是逻辑“或”的意思。空格表示逻辑“与”。这是正式在keyword标签中描述关键字必须的。尽管如此,很多搜索引擎也会把关键字 间以空格分开以达到能搜索出更相关的结果的目的。这样做的意义是,搜索引擎会把空格分开的关键字根据一定的方式自由组合。可以尝试用两种方法,看哪一种更 加适合你。

关键字不宜以同一形式重复3-6次,一般这已经认为是最大的关键字重复数(好像现在又发生了变化)。所以,尽量避免把你的关键字一次又一次地不断重 复。这对于每一个搜索引擎来说是SPAM(关键字垃圾),你会因此而受到惩罚。大多数的搜索引擎会允许你在keyword标签中使用最多1000个字符。 通常,对每一个页面使用相关连的关键字会提高你网站的排名。一个很重要的因素是你关键字冗余度,如果你一个关键字是一个字符,而你的keyword标签中 有100个字符,那么你关键字的冗余度就为1%。搜索引擎将会利用相关的算法对你的关键字冗余度进行统计你网页中的每一个重要的词或短语。去除多余的关键 字有利于提高你网站的排名。

远程维护linux就必须用到ssh,客户端选择什么呢?
如果你使用的是Linux客户端,可以直接使用命令行下的SSH客户端,如果用Windows,则推荐免费版本的Putty,Putty已经开发多年,支持大多数常用功能,支持公钥认证(PublicKey),许多功能请查看http://www.chiark.greenend.org.uk/~sgtatham/putty/。 有了ssh,文件传输如何解决呢?命令行虽然简单可行,可图形界面还是更直观一些,比较好的选择是WinSCP,可以和Putty结合使用,效果感觉很不错。
Putty 还有个同胞兄弟portaputty,Host Key是存储在文件中而不是注册表,这样你可以把整套客户端都放在U盘里,走哪儿带到哪儿,非常方便,portaputty基于putty源码修改,不过目前在其网站上看到的是2006年最后更新,目前putty最新版本是2007年4月29日更新的0.60版本。

另外几种选择:
Axessh: http://www.labf.com/nfsaxe/index.html,该公司提供的另外几个产品也挺不错,nfsAxe有windows平台下的nfs server以及client,tftp,ftp client等
Tunnelier:http://www.bitvise.com 自带sftp功能,个人可以免费使用,不过登录ssh是直接使用的dos窗口方式,不太喜欢。
SecureCRT:个人感觉最好用,不过注册费用也不低,同时销售SecureFX(sftp客户端)
其他还有一些就不一一列举了,http://www.freedownloadscenter.com/Best/free-ssh-gui.html 有较详细的列表。

目前,不少大学都通过教育网接入Internet。出于费用方面的考虑,学校一般都不会开放访问国际网的功能,因此,深受大家喜爱的MSN聊 天软件也就无法使用了。最近,微软给出了MSN的官方教育网代理地址:202.194.15.124:8080,可以帮助以上无法访问国际网的用户开通 MSN。因为这是微软所提供的官方代理地址,速度和时效性方面应该有保证。打开MSN,点击"工具"菜单下的"选项",再选择"连接"标签,在"我使用代 理服务器"前打上勾,在"类型"中选"HTTP代理服务器","服务器"一栏中填入202.194.15.124,"端口"中填入8080(图1)。填完 后点击[确定]按钮使之生效。现在,你就可以在教育网内轻松地使用MSN和各路好友神聊上一番了。

图1

在IE浏览器中单击"工具→Internet选项→连接→局域网设置",勾选"使用代理服务器",并在"地址"和"端口"中分别输入上述代理服务器 地址和端口号。经过这样的设置后,你就可以在教育网内访问到诸如微软公司(http://www.microsoft.com)、微软开发者(http: //msdn.microsoft.com/)、ASP.net社区(http://www.asp.net)等很多国际网站,甚至还能进行 Windows升级。具体可参考http://mscenter.edu.cn/msdoor

小提示:在http://mscenter.edu.cn/msdoor页面中,点击"我要开始旅程"按钮,该网站的脚本程序会自动帮您设置好代理服务器(图2),十分方便。



随着宽带的普及,很多用户都喜欢使用ADSL路由器几个人一起共享上网。因为这样不仅上网的费用降低了,还可以和别人分享自己电脑上的各种资源。但 是,许多宽带用户的ADSL路由器都没有修改默认的密码,使得黑客很容易就盗取到ADSL拨号的帐号密码用并来消费,给用户带来很大的损失。

   例如,TP-LINK路由器的默认密码一般是"admin",黑客可以使用它登陆到没有修改默认密码的TP-LINK路由器上,盗取用户的ADSL帐户 和密码,然后到互连星空进行买Q币、看收费电影等消费。为此,不少用户都把这种情况投诉到了宽带运营商,而一些拨号接入宽带运营商为了避免这种情况的发 生,从2004年开始逐渐在接入服务路由器上封闭互联网访问接入线路的80端口,作为解决问题的方法。

  众所周知,Web服务是用80端 口来通讯的。HTTP端口被封闭后,对于一般的上网用户是不会体现出来的,因为封锁的方向对于用户层面是IN,而用户通过浏览器打开网站进行访问的方向为 OUT。可是,有不少的个人或公司采用在接入线路加上一台普通的兼容PC的方式来搭建互联网服务器,例如把公司的各种产品介绍做成一个Web站点,或建立 个人的生活BLOG、相册等,以达到节省成本以及获得更高的性价比的目的。当宽带接入商封闭了IN方向的80端口后,互联网就访问不到用户服务器中的 Web服务了。宽带运营商此举因此受到了互联网用户多方面的抨击:到底封闭HTTP IN端口是为了避免粗心大意的用户造成损失,还是要大力推动服务器托管市场的发展呢?答案也只有宽带接入商自己才知道。

  作为普通用户,Web IN方向端口被封闭后,我们只能改用其它端口向互联网提供Web服务。但问题随之而来了:更改WEB服务端口后,外网用户在访问该域名时,得必须在域名后加上端口号才能连接到WEB服务器,例如http://www.cicp.net:8080。 这样使得网站地址不仅难记,别人访问起来也很不方便。难道没有解决的办法吗?答案当然是否定的。其实,使用Oray服务所提供的URL转发功能加上著名的 花生壳动态域名解析服务,通过普通的PC加上普通的公网接入线路,就可以轻松地绕过宽带运营商的Web端口限制建立Web服务器。在互联网用户访问您的网 站时,把域名后面的"尾巴"剪掉。

一.下载安装花生壳

  1)我们登陆到http://www.oray.net下载最新的花生壳客户端。安装完成后运行"花生壳",我们点击"注册花生护照",根据弹出注册护照窗口提示进行注册花生护照。注册完成后,使用所注册的护照名称和密码填入花生壳软件中进行登陆。

  2).点击"花生壳"中的域名管理,右击"顶级域名"注册一个顶级域名或右击免费域名注册一个免费域名,建议第一次使用时最好先注册免费域名测试当前的IP地址是否具备向互联网提供服务的条件再进行注册顶级域名使用。另外这里要注意以下两点:

     1>.免费域名是Oray向所有用户提供的三级域名,可以实现免费把动态IP地址绑定到域名上,在未付费前不能实现避开宽带运营商对HTTP 服务IN方向的封锁,不过可以购买免费域名增值服务实现。PS:给大家一个建议,目前免费域名增值服务价格是50元,注册一个顶级域名是100元,顶级域 名的应用以及功能会比免费域名强大得多。

    2>.顶级域名除了实现避开宽带运营商对HTTP服务IN方向的封锁。还支持离线跳 转。离线跳转的概念是:服务器关闭或所在的接入线路断开后,自动将域名跳转到指定的网址。在我们的本次示范中采用CICP.NET顶级域名实现普通 ADSL绕过宽带运营商80端口封锁向互联网提供WEB服务。申请顶级域名时会有很多的友好的提示,过程我们这里就省略不说了。

  3). 根据提示注册test.cicp.net三级域名(这个域名是用于指向到我们的动态IP服务器),然后激活它的"花生壳"服务。这样我们所申请的域名已经绑定到当前的公网IP地址,互联网可通过所申请的域名直接访问到当前的公网IP,

  4).根据提示注册www.cicp.net三级域名,这个域名很重要,是绕过宽带运营商的Web端口封锁关键。注意这里不需要激活该域名,否则是不会进行URL跳转的。最后,在服务器上重新登陆"花生壳"程序。最终的结果如下图所示。

...............
www.pchome.net

net 命令

用NET START命令监测服务,一动便知

很多朋友通过手动关闭不需要的服务来优化系统。不过,由于对被关闭的服务不熟悉,手动优化系统后却出现一些莫名其妙的故障。比如,一个朋友电脑执行 系统优化后,发现系统内原来正常使用的诺基亚手机浏览服务无法使用。怎么才知道自己该关闭哪些服务呢?现在借助NET START命令可以快速发现变化的服务,该命令可以查找出当前系统已开启的服务,并支持重定向输出信息到文件。

1.在执行系统优化前(或者系统正常情况下),启动命令提示符输入“net start >d:\services.txt”。这样可以把当前系统开启的服务输出到d:\services.txt中,我们可以把这个作为系统服务正常状态的参照。

2.如果对系统服务进行调整后发生故障,同上,再次执行“net start >d:\services1.txt”,将优化后的服务状态输出。

3.继续在命令提示符下输入“fc d:\services.txt d:\services1.txt”,使用FC命令比较两个文件不同。我们很快就知道优化前后,一个名为“ServiceLayer”的服务发生变化(如图1)。

4.现在单击“开始→运行”,输入“services.msc”打开系统服务管理窗口。按提示把ServiceLayer服务设置为“自动”并启动该服务顺利解决故障。

小提示:除了NET START命令,我们还可以借助sc query(列出当前服务详细信息)、sc query state= all(列出所有服务,包括硬件驱动服务),用类似于上面介绍的方法对服务进行更详尽的监测。

在sun主页上有java文档注释的编写格式

How to Write Doc Comments for the Javadoc Tool

http://java.sun.com/j2se/javadoc/writingdoccomments/

不过是英文的

@author LEI

@version 1.10 2005-09-01
1 注释文档的格式

注释文档将用来生成HTML格式的代码报告,所以注释文档必须书写在类、域、构造函数、方法、定义之前。注释文档由两部分组成——描述、块标记。

例如:

/**

* The doGet method of the servlet.

* This method is called when a form has its tag value method equals to get.

*

* @param request

* the request send by the client to the server

* @param response

* the response send by the server to the client

* @throws ServletException

* if an error occurred

* @throws IOException

* if an error occurred

*/

public void doGet (HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

前两行为描述,描述完毕后,由@符号起头为块标记注视。
2 注释的种类
2.1 文件头注释

文件头注释以 /*开始,以*/结束,需要注明该文件创建时间,文件名,命名空间信息。

例如:

/*

* Created on 2005-7-2

* /
2.2 类、接口注释

类、接口的注释采用 /** … */,描述部分用来书写该类的作用或者相关信息,块标记部分必须注明作者和版本。

例如:

/**Title: XXXX DRIVER 3.0
*Description: XXXX DRIVER 3.0
*Copyright: Copyright (c) 2003
*Company:XXXX有限公司
*
* @author Java Development Group
* @version 3.0
*/

例如:

/**
* A class representing a window on the screen.
* For example:
*
* Window win = new Window(parent);
* win.show();
*
*
* @author Sami Shaio
* @version %I%, %G%
* @see java.awt.BaseWindow
* @see java.awt.Button
*/

class Window extends BaseWindow {

...

}
2.3 构造函数注释

构造函数注释采用 /** … */,描述部分注明构造函数的作用,不一定有块标记部分。

例如:

/**

* 默认构造函数

*/

有例如:

/**

* 带参数构造函数,初始化模式名,名称和数据源类型

*

* @param schema

* Ref 模式名

* @param name

* Ref 名称

* @param type

* byVal 数据源类型

*/
2.4 域注释

域注释可以出现在注释文档里面,也可以不出现在注释文档里面。用/** … */的域注释将会被认为是注释文档热出现在最终生成的HTML报告里面,而使用/* … */的注释会被忽略。

例如:

/* 由于triger和表用一个DMSource,所以要区分和表的迁移成功标记 */

boolean isTrigerSuccess = false;

又例如:

/** 由于triger和表用一个DMSource,所以要区分和表的迁移成功标记 */

boolean isTrigerSuccess = false;

再例如:

/**

* The X-coordinate of the component.

*

* @see #getLocation()

*/

int x = 1263732;
2.5 方法注释

方法注释采用 /** … */,描述部分注明方法的功能,块标记部分注明方法的参数,返回值,异常等信息。例如:

/**

* 设置是否有外码约束

*

* @param conn

* Connection 与数据库的连接

*/
2.6 定义注释

规则同域注释。
3 注释块标记
3.1 标记的顺序

块标记将采用如下顺序:



*

* @param (classes, interfaces, methods and constructors only)

* @return (methods only)

* @exception (@throws is a synonym added in Javadoc 1.2)

* @author (classes and interfaces only, required)

* @version (classes and interfaces only, required. See footnote 1)

* @see

* @since

* @serial (or @serialField or @serialData)

* @deprecated (see How and When To Deprecate APIs)

* …

一个块标记可以根据需要重复出现多次,多次出现的标记按照如下顺序:

@author 按照时间先后顺序(chronological)

@param 按照参数定义顺序(declaration)

@throws 按照异常名字的字母顺序(alphabetically)

@see 按照如下顺序:

@see #field

@see #Constructor(Type, Type...)

@see #Constructor(Type id, Type id...)

@see #method(Type, Type,...)

@see #method(Type id, Type, id...)

@see Class

@see Class#field

@see Class#Constructor(Type, Type...)

@see Class#Constructor(Type id, Type id)

@see Class#method(Type, Type,...)

@see Class#method(Type id, Type id,...)

@see package.Class

@see package.Class#field

@see package.Class#Constructor(Type, Type...)

@see package.Class#Constructor(Type id, Type id)

@see package.Class#method(Type, Type,...)

@see package.Class#method(Type id, Type, id)

@see package
3.2 标记介绍
3.2.1 @param标记

@param后面空格后跟着参数的变量名字(不是类型),空格后跟着对该参数的描述。

在描述中第一个名字为该变量的数据类型,表示数据类型的名次前面可以有一个冠词如:a,an,the。如果是int类型的参数则不需要注明数据类型。例如:



* @param ch the char 用用来……

* @param _image the image 用来……

* @param _num 一个数字……



对于参数的描述如果只是一短语,最好不要首字母大写,结尾也不要句号。

对于参数的描述是一个句子,最好不要首字母大写,如果出现了句号这说明你的描述不止一句话。如果非要首字母大写的话,必须用句号来结束句子。(英文的句号)

公司内部添加ByRef和ByVal两个标记,例如:

* @param _image the image ByRef 用来……

说明该参数是引用传递(指针),ByVal可以省略,表示是值传递。
3.2.2 @return标记

返回为空(void)的构造函数或者函数,@return可以省略。

如果返回值就是输入参数,必须用与输入参数的@param相同的描述信息。

必要的时候注明特殊条件写的返回值。
3.2.3 @throws 标记

@throws以前使用的是@exception。

@throws的内容必须在函数的throws部分定义。
3.2.4 @author标记

类注释标记。

函数注释里面可以不出现@author。
3.2.5 @version

类注释标记。

函数注释里面可以不出现@version
3.2.6 @since

类注释标记。

标明该类可以运行的JDK版本

例如:

@since JDK1.2
3.2.7 @deprecated

由于某种原因而被宣布将要被废弃的方法。

/**

* @deprecated As of JDK 1.1, replaced by

* setBounds

* @see #setBounds(int,int,int,int)

*/
3.2.8 @link标记

语法:{@link package.class#member label}

Label为链接文字。

package.class#member将被自动转换成指向package.class的member文件的URL。
4 HTML代码的使用

在注释描述部分可以使用HTML代码。

表示段落

表示自动标号
5 注释示例

/**

* Graphics is the abstract base class for all graphics contexts

* which allow an application to draw onto components realized on

* various devices or onto off-screen images.

* A Graphics object encapsulates the state information needed

* for the various rendering operations that Java supports. This

* state information includes:

*

*

*

*

*

*

*

*

* (see setXORMode)

*

*

* Coordinates are infinitely thin and lie between the pixels of the

* output device.

* Operations which draw the outline of a figure operate by traversing

* along the infinitely thin path with a pixel-sized pen that hangs

* down and to the right of the anchor point on the path.

* Operations which fill a figure operate by filling the interior

* of the infinitely thin path.

* Operations which render horizontal text render the ascending

* portion of the characters entirely above the baseline coordinate.

*

* Some important points to consider are that drawing a figure that

* covers a given rectangle will occupy one extra row of pixels on

* the right and bottom edges compared to filling a figure that is

* bounded by that same rectangle.

* Also, drawing a horizontal line along the same y coordinate as

* the baseline of a line of text will draw the line entirely below

* the text except for any descenders.

* Both of these properties are due to the pen hanging down and to

* the right from the path that it traverses.

*

* All coordinates which appear as arguments to the methods of this

* Graphics object are considered relative to the translation origin

* of this Graphics object prior to the invocation of the method.

* All rendering operations modify only pixels which lie within the

* area bounded by both the current clip of the graphics context

* and the extents of the Component used to create the Graphics object.

*

* @author Sami Shaio

* @author Arthur van Hoff

* @version %I%, %G%

* @since 1.0

*/

public abstract class Graphics {

/**

* Draws as much of the specified image as is currently available

* with its northwest corner at the specified coordinate (x, y).

* This method will return immediately in all cases, even if the

* entire image has not yet been scaled, dithered and converted

* for the current output device.

*

* If the current output representation is not yet complete then

* the method will return false and the indicated

* {@link ImageObserver} object will be notified as the

* conversion process progresses.

*

* @param img the image to be drawn

* @param x the x-coordinate of the northwest corner

* of the destination rectangle in pixels

* @param y the y-coordinate of the northwest corner

* of the destination rectangle in pixels

* @param observer the image observer to be notified as more

* of the image is converted. May be

* null

* @return true if the image is completely

* loaded and was painted successfully;

* false otherwise.

* @see Image

* @see ImageObserver

* @since 1.0

*/

public abstract boolean drawImage(Image img, int x, int y,

ImageObserver observer);

/**

* Dispose of the system resources used by this graphics context.

* The Graphics context cannot be used after being disposed of.

* While the finalization process of the garbage collector will

* also dispose of the same system resources, due to the number

* of Graphics objects that can be created in short time frames

* it is preferable to manually free the associated resources

* using this method rather than to rely on a finalization

* process which may not happen for a long period of time.

*

* Graphics objects which are provided as arguments to the paint

* and update methods of Components are automatically disposed

* by the system when those methods return. Programmers should,

* for efficiency, call the dispose method when finished using

* a Graphics object only if it was created directly from a

* Component or another Graphics object.

*

* @see #create(int, int, int, int)

* @see #finalize()

* @see Component#getGraphics()

* @see Component#paint(Graphics)

* @see Component#update(Graphics)

* @since 1.0

*/

public abstract void dispose();

/**

* Disposes of this graphics context once it is no longer

* referenced.

*

* @see #dispose()

* @since 1.0

*/

public void finalize() {

dispose();

}

}
# The Component to draw on
# A translation origin for rendering and clipping coordinates
# The current clip
# The current color
# The current font
# The current logical pixel operation function (XOR or Paint)
# The current XOR alternation color

* ….

Hibernate 一对一外键单向关联
事实上,单向1-1N-1的实质是相同的,1-1N-1的特例,单向1-1N-1的映射配置也非常相似。只需要将原来的many-to-one元素增加unique="true"属性,用于表示N的一端也必须是唯一的,在N的一端增加了唯一的约束,即成为单向1-1。基于外键的单向1-1的配置将与无连接表N-1关联的many-to-one增加unique="true"属性即可。
一、模型介绍
一个人(Person)对应一个地址(Address)。
二、实体(省略gettersetter方法)
public class Person11fk {
private int personid;
private String name;
private int age;
private Address11fk address11fk;
public class Address11fk {
private int addressid;
private String addressdetail;
三、表模型
mysql> desc address_11fk;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| addressid | int(11) | NO | PRI | NULL | auto_increment |
| addressdetail | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
mysql> desc person_11fk;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| personid | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| addressId | int(11) | YES | UNI | NULL | |
+-----------+--------------+------+-----+---------+----------------+
四、生成的SQL脚本
CREATE TABLE `address_11fk` (
`addressid` int(11) NOT NULL auto_increment,
`addressdetail` varchar(255) default NULL,
PRIMARY KEY (`addressid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gbk;
CREATE TABLE `person_11fk` (
`personid` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`age` int(11) default NULL,
`addressId` int(11) default NULL,
PRIMARY KEY (`personid`),
KEY `FK68A8818F3F45AA77` (`addressId`),
CONSTRAINT `FK68A8818F3F45AA77` FOREIGN KEY (`addressId`) REFERENCES `address_11fk` (`addressid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gbk;
五、映射方法:
Person中添加Address属性,映射配置为:
六、测试方法
public class Test_11fk {
public static void main(String[] args){
Person11fk p1=new Person11fk();
p1.setAge(21);
p1.setName("p1");
Address11fk add1=new Address11fk();
add1.setAddressdetail("郑州市经三路");
p1.setAddress11fk(add1);
Session session= HibernateUtil.getCurrentSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(p1);
tx.commit();
HibernateUtil.closeSession();
}
}
七、测试结果
1) :正常保存. 推荐这么干!
session.save(add1);
session.save(p1);
Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)
Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)
2) :正常保存.
session.save(p1);
session.save(add1);
Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)
Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)
Hibernate: update PERSON_11fk set name=?, age=?, addressId=? where personid=?
3) :正常保存.
// session.save(p1);
session.save(add1);
Hibernate: insert into ADDRESS_11fk (addressdetail) values (?)
4) : 发生异常,不能保存.
session.save(p1);
// session.save(add1);
Hibernate: insert into PERSON_11fk (name, age, addressId) values (?, ?, ?)
Exception in thread "main" org.hibernate.TransientObjectException: com.lavasoft.dx._1_1_fk.Address11fk

(Hibernate)cascade

在我前面的笔记中已经写过关联关系的使用,但主要是演示,在这篇中,我将再细分析!
利用关联关系操作对象:
数据对象之间的关联关系有一对一,一对多及多对多三种。在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难。例如,当删除一个班级的信息时,还要删除该班级的所有学生的基本信息。如果直接使用JDBC执行这种级联操作,会非常繁锁。Hibernate通过把实体对象之间的关联关系及级联关系在映射文件中声明,比较简单地解决了这类级联操作问题。
一对一关联关系的使用
一对一关联关系在实际生活中是比较觉的,例如学生与学生证的关系,通过学生证可以找到学生。一对一关联关系在Hibernate中的实现有两种方式,分别是主键关联和外键关联。
主键关联
主键关联的重点是,关联两个实体共享一个主键值。例如student与card是一对一关系,它们在数据库中对应的表分别是t_student和t_card。它们共用一个主键值ID,这个主键可由t_student或t_card表生成。问题是如何让另一张表引用已经生成的主键值呢?例如,t_student表未老先衰了ID的值,t_card表如何引用它?这需要在Hibernate的映射文件中使用主键的foreign生成机制!

为了表示Student与Card之间的一对一的关联关系,我们需要在它们各自的映射文件 中都要使用标记!
一对一关系我在前面已经写过例子程序了,在这里仅给出两个映射文件。如下:
学生PO映射信息:

xml version="1.0" encoding="GBK"?>
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>
<class name="hibernate.PO.TStudent" table="t_student" lazy="true">
<id name="id" type="java.lang.Integer">
<column name="id"/>
<generator class="increment" />
id>
<property name="userName" type="java.lang.String">
<column name="userName" length="20" />
property>
<property name="cardId" type="java.lang.String">
<column name="card_id" length="20" />
property>
<property name="sex" type="java.lang.String">
<column name="sex" length="2" />
property>
<property name="age" type="java.lang.Integer">
<column name="age" />
property>
<one-to-one name="card" class="hibernate.PO.TCard" fetch="join" cascade="all" />
class>
hibernate-mapping>


学生证PO映射信息:

xml version="1.0" encoding="GBK"?>
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>
<class name="hibernate.PO.TCard" table="t_card" lazy="true">
<id name="id" type="java.lang.Integer">
<column name="id"/>
<generator class="foreign">
<param name="property">studentparam>
generator>
id>

<property name="name" type="java.lang.String">
<column name="name" length="20" />
property>


<one-to-one name="student" class="hibernate.PO.TStudent" constrained="true" />

class>
hibernate-mapping>

外键关联
外键关联的要点是:两个实体各自有不同的主键,但其中一个实体有一个外键引用另一个实体的主键。例如,假设,Student和Card是外键关联的一对一关系们在数据库中相应的表分别如下:t_student表有一个主键ID,t_card表有一个主键ID和一个外键student_id,此外键对应t_student表的主键ID,那么student的映射信息如上面一样不做改动,而Card的映射文件要做相应的改动。如下:
<hibernate-mapping>
<class name="hibernate.PO.TCard" table="t_card" lazy="true">
<id name="id" type="java.lang.Integer">
<column name="id"/>
<generator class="increment"/>
id>

<property name="name" type="java.lang.String">
<column name="name" length="20" />
property>

<many-to-one name="student" column="student_id" class="hibernate.PO.TStudent" unique="true"/>



class>
hibernate-mapping>

一对多关联关系的使用
一对多关系很觉,例如班级与学生的关系就是典型的一对多的关系。在实际编写程序时,一对多关系有两种实现方式:单向关联和双向关联。单向的一对多关系只需要在一方进行映射配置,而双向的一对多需要在关联的双方进行映射配置。下面以Group(班级)和Student(学生)为例讲解如何配置一对多的关系。
单向关联
单向的一对多关系只需要在一方进行映射配置,所以我们只配置Group的映射文件:
<hibernate-mapping>
<class name="hibernate.PO.Group" table="t_group" lazy="true">
<id name="id" type="java.lang.Integer">
<column name="id"/>
<generator class="increment"/>
id>

<property name="name" type="java.lang.String" update="true" insert="true">
<column name="name" length="20" />
property>


<set name="students"
table
="t_student"
lazy
="true"
inverse
="false"
cascade
="all"
sort
="unsorted">
<key column="ID"/>
<one-to-many class="hibernate.PO.TStudent"/>
set>
class>
hibernate-mapping>
双向关联
如果要设置一对多双向关联关系,那么还需要在“多”方的映射文件中使用标记。例如,在Group与Student一对多的双向关联中,除了Group的映射文件外还需要在Student的映射文件中加入如下代码:
<many-to-one name="group"
class
="Group"
cascade
="none"
outer-join
="auto"
update
="true"
insert
="true"
column
="ID" />

inert和update设定是否对column属性指定的关联字段进行insert和update操作。
此外将Group.hbm.xml中元素的inverse设置为true.

多对多关联关系的使用
Student(学生)和Course(课程)的关系就是多对多关系。在映射多对多关系时需要另外使用一个连接表(如Student_Course)。Student_Course表包含二个字段:courseID和studentID。此处它们的映射文件中使用标记,在Student的映射文件中加入以下描述信息:

<set name="courses"
table
="student_course"
lazy
="false"
inverse
="false"
cascade
="save-update">
<key column="studentID" />
<many-to-many class="Course" column="CourseID"/>
set>
相应的Course的映射文件中加入以下:
<set name="students"
table
="student_course"
lazy
="false"
inverse
="true"
cascade
="save-update">
<key column="CourseID" />
<many-to-many class="Student" column="StudentID"/>
set>
添加关联关系
首先编写一个程序来看看一个名为Bill的学生选择了什么课程:
//获取代表Bill的Student对象
Student stu = (Student)session.createQuery("from Student s where s.name='Bill'").uniqueResult();
List list
= new ArrayList(stu.getCourses());
for(int i = 0 ; i < list.size(); i++)
{
Course course
= (Course)list.get(i);//取得Course对象
System.out.println(course.getName());//打印出Bill所选课程的清单
}
现在Bill还想chemistry课程,这对于程序员来说只是为Bill添加一个到chemistry的关联,也就是说在student_course表中新增加一条记录,而T_student和T_Course表都不用变更。
//获取代表Bill的Student对象
Student stu = (Student)session.createQuery("from Student s where s.name='Bill'").uniqueResult();
Course course
= (Course)session.createQuery("from Course c where c.name='chemistry'").uniqueResult();
//设置stu与course的关联关系
stu.getCourses().add(course);
course.getStudents().add(stu);
删除关联关系
删除关联关系比较简单,直接调用对象集合的remove()方法删除不要的对象就可。例如:要从学生Bill的选课清单中删除politics和chemistry两门课,程序代码如下:
//获取代表Bill的Student对象
Student stu = (Student)session.createQuery("from Student s where s.name='Bill'").uniqueResult();
Course course1
= (Course)session.createQuery("from Course c where c.name='politics'").uniqueResult();
Course course2
= (Course)session.createQuery("from Course c where c.name='chemistry'").uniqueResult();
stu.getCourse().remove(course1);
//删除politics课程
stu.getCourse().remove(course2);//删除chemistry课程
运行以上程序将从student_course表中删除这两条记录,但T_student和T_course表没有任何变化

 
Copyright 2005-2007. Hello Wiki designed by Fen, Blogger Templates by Blogcrowds.