﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-风吹玉门前----雁北飞-随笔分类-J2EE网海拾贝</title><link>http://www.blogjava.net/realnicky/category/6373.html</link><description>自古多情伤离别，雁已北飞，冷若清湖水，今宵梦醒何处，杨柳岸小风婵月…</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 03:24:38 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 03:24:38 GMT</pubDate><ttl>60</ttl><item><title>Hibernate入门 - 基础配置</title><link>http://www.blogjava.net/realnicky/archive/2006/01/13/27871.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Fri, 13 Jan 2006 02:48:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2006/01/13/27871.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/27871.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2006/01/13/27871.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/27871.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/27871.html</trackback:ping><description><![CDATA[Hibernate配置文件可以有两种格式，一种是 hibernate.properties ，另一种是 hibernate.cfg.xml  

后者稍微方便一些，当增加hbm映射文件的时候，可以直接在 hibernate.cfg.xml 里面增加，不必像 hibernate.properties 必须在初始化代码中加入。 

但不管怎么说，两种的配置项都是一样的，下面详细介绍： 

在Hibernate的src目录下有一个 hibernate.properties 模板，我们不必自己从头写，修改模板就可以了:) 


hibernate.query.substitutions true 1, false 0, yes 'Y', no 'N' 

这个配置意思是当你在Hibernate里面输入true的时候，Hibernate会转化为1插入数据库，当你在Hibernate里面输入false的时候，Hibernate会转化为0插入数据库，后面的Y，N同理。 

对于某些数据库，例如Oracle来说，没有boolean数据类型，就是采用1代表true，0代表false，因此使用这个配置在Hibernate里面直接用true/false会非常直观。 


hibernate.dialect net.sf.hibernate.dialect.MySQLDialect 
hibernate.connection.driver_class com.mysql.jdbc.Driver 
hibernate.connection.url jdbc:mysql:///test 
hibernate.connection.username root 
hibernate.connection.password  

这是一个连接MySQL数据库的例子，很直观，不必解释，不同的数据库的连接参数模板中全部给出了。 


hibernate.connection.pool_size 1 
hibernate.statement_cache.size 25 

这是Hibernate自带的连接池的配置参数，在默认情况下将采用。意义很直观，不多解释。 

只是提醒一点，Hibernate这个连接池是非常原始非常简单的连接池，如果你在项目中用Hibernate的话，建议你首选App Server的连接池，次选Hibernate带的DBCP连接池。自带的连接池应该做为末选。 

如果你采用DBCP连接池，除了要配置DBCP连接池以外，还需要取消掉下行的注释： 

hibernate.connection.provider_class net.sf.hibernate.connection.DBCPConnectionProvider 

其它的连接池同理。 

如果采用App Server的连接池，假设App Server连接池的DataSource的JNDI名称为"mypool"的话，配置应该如下： 

hibernate.dialect net.sf.hibernate.dialect.MySQLDialect 
hibernate.connection.datasource mypool 
hibernate.connection.provider_class net.sf.hibernate.connection.DatasourceConnectionProvider 

其它参数就不必写了，因为已经在App Server配置连接池的时候指定好了。 

如果你不是在App Server环境中使用Hibernate，例如远程客户端程序，但是你又想用App Server的数据库连接池，那么你还需要配置JNDI的参数，例如Hibernate连接远程Weblogic上的数据库连接池： 

hibernate.dialect net.sf.hibernate.dialect.MySQLDialect 
hibernate.connection.datasource mypool 
hibernate.connection.provider_class net.sf.hibernate.connection.DatasourceConnectionProvider 
hibernate.jndi.class weblogic.jndi.WLInitialContextFactory 
hibernate.jndi.url t3://servername:7001/ 


最后，如果你需要在EJB或者JTA中使用Hibernate，需要取消下行的注释： 

hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory 

杂项配置： 


hibernate.show_sql false 

是否将Hibernate发送给数据库的sql显示出来，这是一个非常非常有用处的功能。当你在调试Hibernate的时候，让Hibernate打印sql语句，可以帮助你迅速解决问题。 


#hibernate.connection.isolation 4 

指定数据库的隔离级别，往往不同的数据库有自己定义的隔离级别，未必是Hibernate的设置所能更改的，所以也不必去管它了。 


hibernate.jdbc.fetch_size 50 
hibernate.jdbc.batch_size 25 

这两个选项非常非常非常重要！！！将严重影响Hibernate的CRUD性能! 

C = create, R = read, U = update, D = delete 

Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数。 

例如一次查询1万条记录，对于Oracle的JDBC驱动来说，是不会1次性把1万条取出来的，而只会取出Fetch Size条数，当纪录集遍历完了这些记录以后，再去数据库取Fetch Size条数据。 

因此大大节省了无谓的内存消耗。当然Fetch Size设的越大，读数据库的次数越少，速度越快；Fetch Size越小，读数据库的次数越多，速度越慢。 

这有点像平时我们写程序写硬盘文件一样，设立一个Buffer，每次写入Buffer，等Buffer满了以后，一次写入硬盘，道理相同。 

Oracle数据库的JDBC驱动默认的Fetch Size=10，是一个非常保守的设定，根据我的测试，当Fetch Size=50的时候，性能会提升1倍之多，当Fetch Size=100，性能还能继续提升20%，Fetch Size继续增大，性能提升的就不显著了。 

因此我建议使用Oracle的一定要将Fetch Size设到50。 

不过并不是所有的数据库都支持Fetch Size特性，例如MySQL就不支持。 

MySQL就像我上面说的那种最坏的情况，他总是一下就把1万条记录完全取出来，内存消耗会非常非常惊人！这个情况就没有什么好办法了 :( 

Batch Size是设定对数据库进行批量删除，批量更新和批量插入的时候的批次大小，有点相当于设置Buffer缓冲区大小的意思。 

Batch Size越大，批量操作的向数据库发送sql的次数越少，速度就越快。我做的一个测试结果是当Batch Size=0的时候，使用Hibernate对Oracle数据库删除1万条记录需要25秒，Batch Size = 50的时候，删除仅仅需要5秒！！！ 

可见有多么大的性能提升！很多人做Hibernate和JDBC的插入性能测试会奇怪的发现Hibernate速度至少是JDBC的两倍，就是因为Hibernate使用了Batch Insert，而他们写的JDBC没有使用Batch的缘故。 

以我的经验来看，Oracle数据库 Batch Size = 30 的时候比较合适，50也不错，性能会继续提升，50以上，性能提升的非常微弱，反而消耗内存更加多，就没有必要了。 


#hibernate.jdbc.use_scrollable_resultset true 

设定是否可以使用JDBC2.0规范的可滚动结果集，这对Hibernate的分页显示有一定的作用，默认就好了。 


#hibernate.cglib.use_reflection_optimizer false 

默认打开，启用cglib反射优化。cglib是用来在Hibernate中动态生成PO字节码的，打开优化可以加快字节码构造的速度。 

不过，当你在调试程序过程中，特别是和proxy，lazy loading相关的应用中，代码出错，但是出错提示信息有语焉不详，那么你可以把cglib优化关掉，这样Hibernate会输出比较详细的调试信息，帮助你debug。 
在保留http://www.javajia.com原出处的情况下，欢迎转载!

<img src ="http://www.blogjava.net/realnicky/aggbug/27871.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2006-01-13 10:48 <a href="http://www.blogjava.net/realnicky/archive/2006/01/13/27871.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate入门 - 包作用详解</title><link>http://www.blogjava.net/realnicky/archive/2006/01/13/27863.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Fri, 13 Jan 2006 02:45:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2006/01/13/27863.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/27863.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2006/01/13/27863.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/27863.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/27863.html</trackback:ping><description><![CDATA[Hibernate一共包括了23个jar包，令人眼花缭乱。本文将详细讲解Hibernate每个jar包的作用，便于你在应用中根据自己的需要进行取舍。 

　　下载Hibernate，例如2.0.3稳定版本，解压缩，可以看到一个hibernate2.jar和lib目录下有22个jar包： 

　　hibernate2.jar: 
　　Hibernate的库，没有什么可说的，必须使用的jar包 

　　cglib-asm.jar: 
　　CGLIB库，Hibernate用它来实现PO字节码的动态生成，非常核心的库，必须使用的jar包 

　　dom4j.jar: 
　　dom4j是一个Java的XML API，类似于jdom，用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API，具有性能优异、功能强大和极端易用使用的特点，同时它也是一个开放源代码的软件，可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章，对主流的Java XML API进行的性能、功能和易用性的评测，dom4j无论在那个方面都是非常出色的。我早在将近两年之前就开始使用dom4j，直到现在。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML，特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar包，Hibernate用它来读写配置文件。 

　　odmg.jar: 
　　ODMG是一个ORM的规范，Hibernate实现了ODMG规范，这是一个核心的库，必须使用的jar包。 

　　commons-collections.jar： 
　　Apache Commons包中的一个，包含了一些Apache开发的集合类，功能比java.util.*强大。必须使用的jar包。 

　　commons-beanutils.jar： 
　　Apache Commons包中的一个，包含了一些Bean工具类类。必须使用的jar包。 

　　commons-lang.jar: 
　　Apache Commons包中的一个，包含了一些数据类型工具类，是java.lang.*的扩展。必须使用的jar包。 

　　commons-logging.jar: 
　　Apache Commons包中的一个，包含了日志功能，必须使用的jar包。这个包本身包含了一个Simple Logger，但是功能很弱。在运行的时候它会先在CLASSPATH找log4j，如果有，就使用log4j，如果没有，就找JDK1.4带的java.util.logging，如果也找不到就用Simple Logger。commons-logging.jar的出现是一个历史的的遗留的遗憾，当初Apache极力游说Sun把log4j加入JDK1.4，然而JDK1.4项目小组已经接近发布JDK1.4产品的时间了，因此拒绝了Apache的要求，使用自己的java.util.logging，这个包的功能比log4j差的很远，性能也一般。

　　后来Apache就开发出来了commons-logging.jar用来兼容两个logger。因此用commons-logging.jar写的log程序，底层的Logger是可以切换的，你可以选择log4j，java.util.logging或者它自带的Simple Logger。不过我仍然强烈建议使用log4j，因为log4j性能很高，log输出信息时间几乎等于System.out，而处理一条log平均只需要5us。你可以在Hibernate的src目录下找到Hibernate已经为你准备好了的log4j的配置文件，你只需要到Apache 网站去下载log4j就可以了。commons-logging.jar也是必须的jar包。 

　　使用Hibernate必须的jar包就是以上的这几个，剩下的都是可选的。 

　　ant.jar: 
　　Ant编译工具的jar包，用来编译Hibernate源代码的。如果你不准备修改和编译Hibernate源代码，那么就没有什么用，可选的jar包 

　　optional.jar： 
　　Ant的一个辅助包。 

　　c3p0.jar： 
　　C3PO是一个数据库连接池，Hibernate可以配置为使用C3PO连接池。如果你准备用这个连接池，就需要这个jar包。 

　　proxool.jar： 
　　也是一个连接池，同上。 

　　commons-pool.jar, commons-dbcp.jar: 
　　DBCP数据库连接池，Apache的Jakarta组织开发的，Tomcat4的连接池也是DBCP。 

　　实际上Hibernate自己也实现了一个非常非常简单的数据库连接池，加上上面3个，你实际上可以在Hibernate上选择4种不同的数据库连接池，选择哪一个看个人的偏好，不过DBCP可能更通用一些。另外强调一点，如果在EJB中使用Hibernate，一定要用App Server的连接池，不要用以上4种连接池，否则容器管理事务不起作用。 

　　connector.jar: 
　　JCA 规范，如果你在App Server上把Hibernate配置为Connector的话，就需要这个jar。不过实际上一般App Server肯定会带上这个包，所以实际上是多余的包。 

　　jaas.jar: 
　　JAAS是用来进行权限验证的，已经包含在JDK1.4里面了。所以实际上是多余的包。 

　　jcs.jar： 
　　如果你准备在Hibernate中使用JCS的话，那么必须包括它，否则就不用。 

　　jdbc2_0-stdext.jar: 
　　JDBC2.0的扩展包，一般来说数据库连接池会用上它。不过App Server都会带上，所以也是多余的。 

　　jta.jar： 
　　JTA规范，当Hibernate使用JTA的时候需要，不过App Server都会带上，所以也是多余的。 

　　junit.jar: 
　　Junit包，当你运行Hibernate自带的测试代码的时候需要，否则就不用。 

　　xalan.jar, xerces.jar, xml-apis.jar: 
　　Xerces是XML解析器，Xalan是格式化器，xml-apis实际上是JAXP。一般App Server都会带上，JDK1.4也包含了解析器，不过不是Xerces，是Crimson，效率比较差，不过Hibernate用XML只不过是读取配置文件，性能没什么紧要的，所以也是多余的。

在保留http://www.javajia.com原出处的情况下，欢迎转载!

<img src ="http://www.blogjava.net/realnicky/aggbug/27863.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2006-01-13 10:45 <a href="http://www.blogjava.net/realnicky/archive/2006/01/13/27863.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>菜鸟学用middlegen </title><link>http://www.blogjava.net/realnicky/archive/2006/01/06/26844.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Fri, 06 Jan 2006 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2006/01/06/26844.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/26844.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2006/01/06/26844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/26844.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/26844.html</trackback:ping><description><![CDATA[俺是java和hibernate和ant的绝对的三料菜鸟。hibernate似乎很好用，但是写表对应的类和.hbm.xml文件实在头大。所以俺想找一款可以自动生成这些文件的工具。

俺找到了middlegen。它的主页地址是http://boss.bekk.no/boss/middlegen/index.html。我google了一些中文网页，提供的地址没有一个不失效的。-_-。光有middlegen还不够，因为它使用ant来配置它的build。它的一个bulid生成的东西就是一堆的你可以用的.java,.hbm.xml,.class,.war文件。真是够贴心的。可是俺觉得它的配置可是一点都不贴心。

你要是没有ant，请先下载ant。俺一直打不开官方的地址，所以从pchome下载http://dlfjgwbn.pchome.net:8080/development/java/apacheant161.zip。解压文件后就可以用了，但等等，你需要安装了jdk，设置了CLASSPATH，JAVA_HOME。然后把ant的目录下的bin文件夹添加到path环境变量，设置ANT_HOME。
我的机器上的设置：
CLASSPATH .;D:\jdk150\lib\tools.jar;D:\jdk150\jre\lib\rt.jar
JAVA_HOME D:\jdk150
Path  D:\apache-ant-1.6.1\bin;
ANT_HOME D:\apache-ant-1.6.1
 
然后下载并解压middlegen。我解压到了D:\hibernate-3.0\middlegen-2.1。好了，现在可以开始build hibernate需要的文件了，有个D:\hibernate-3.0\middlegen-2.1samples的文件夹，它存放了一个build的例子，我决定修改这个例子然后使用。
 
但是再等等。middlegen需要你提供一些必要的配置。它需要连接到你的数据库，所以你需要给它提供数据库的连接信息和驱动库。各种数据库的配置信息在目录D:\hibernate-3.0\middlegen-2.1\samples\config\database 下面。俺的数据库是mssql，所以俺打开了mssql.xml文件，配置了信息如下：
   <property name="database.script.file"           value=""/>
   <property name="database.driver.file"           value="${lib.dir}/mssqlserver.jar"/>
   <property name="database.driver"                value="com.microsoft.jdbc.sqlserver.SQLServerDriver"/>
   <property name="database.url"                   value="jdbc:microsoft:sqlserver://localhost:1433"/>
   <property name="database.userid"                value="sa"/>
   <property name="database.password"              value="haha"/>
   <property name="database.schema"                value="dbo"/>
   <property name="database.catalog"               value="aljoin_info"/>
   <property name="jboss.datasource.mapping"       value="MS SQLSERVER"/>
aljoin_info是俺的数据库名称。并把msbase.jar，mssqlserver.jar，msutil.jar拷贝到D:\hibernate-3.0\middlegen-2.1\samples\lib目录。
然后编辑D:\hibernate-3.0\middlegen-2.1\samples\build.xml文件，将"ENTITY database SYSTEM"的值改成"file:./config/database/mssql.xml"
 
更改这个build的其它属性。build.xml中更改project的属性:
<project name="Middlegen aljoni_info" default="hbm2java" basedir=".">
 ...
 <property name="name"                           value="com.aljoin.gas"/>

删除D:\hibernate-3.0\middlegen-2.1\samples\build下的所有文件。然后打开命令行，
cd D:\hibernate-3.0\middlegen-2.1\samples
ant
这时候ant会自动读build.xml文件，找到project，运行名为"hbm2java"及其依赖的target.因为俺是菜鸟,什么ejb,jbo俺通通用不到.如果你不是菜鸟,可以设置成default="all",而且如果您的系统没有安装jboss之类的会出错,但我想如果您不是菜鸟应该也不会看到这里了hoho :p
 
在跳出的程序界面上按generate。等待结束，然后关闭程序界面。在命令行窗口看到正在生成.java文件的信息。
查看D:\hibernate-3.0\middlegen-2.1\samples\build目录。上帝保佑你会看到一些你需要的文件。
 
到写完这篇烂文，一个早上已经过去，俺又把青春贡献给了党-_-||
转自:为了遗忘的记忆 http://www.cnitblog.com/Raistlin/archive/2005/09/14/2653.html<img src ="http://www.blogjava.net/realnicky/aggbug/26844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2006-01-06 10:33 <a href="http://www.blogjava.net/realnicky/archive/2006/01/06/26844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle/PLSQL: To_Date Function</title><link>http://www.blogjava.net/realnicky/archive/2006/01/05/26733.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Thu, 05 Jan 2006 08:37:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2006/01/05/26733.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/26733.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2006/01/05/26733.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/26733.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/26733.html</trackback:ping><description><![CDATA[Oracle/PLSQL: To_Date Function

--------------------------------------------------------------------------------

In Oracle/PLSQL, the to_date function converts a string to a date.

The syntax for the to_date function is:

to_date( string1, [ format_mask ], [ nls_language ] )

string1 is the string that will be converted to a date.

format_mask is optional. This is the format that will be used to convert string1 to a date.

nls_language is optional. This is the nls language used to convert string1 to a date.



The following is a list of options for the format_mask parameter. These parameters can be used in many combinations.

Parameter Explanation 
YEAR Year, spelled out 
YYYY 4-digit year 
YYY
YY
Y Last 3, 2, or 1 digit(s) of year. 
IYY
IY
I Last 3, 2, or 1 digit(s) of ISO year. 
IYYY 4-digit year based on the ISO standard 
RRRR Accepts a 2-digit year and returns a 4-digit year.
A value between 0-49 will return a 20xx year.
A value between 50-99 will return a 19xx year. 
Q Quarter of year (1, 2, 3, 4; JAN-MAR = 1). 
MM Month (01-12; JAN = 01). 
MON Abbreviated name of month. 
MONTH Name of month, padded with blanks to length of 9 characters. 
RM Roman numeral month (I-XII; JAN = I). 
WW Week of year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year. 
W Week of month (1-5) where week 1 starts on the first day of the month and ends on the seventh. 
IW Week of year (1-52 or 1-53) based on the ISO standard. 
D Day of week (1-7). 
DAY Name of day. 
DD Day of month (1-31). 
DDD Day of year (1-366). 
DY Abbreviated name of day. 
J Julian day; the number of days since January 1, 4712 BC. 
HH Hour of day (1-12). 
HH12 Hour of day (1-12). 
HH24 Hour of day (0-23). 
MI Minute (0-59). 
SS Second (0-59). 
SSSSS Seconds past midnight (0-86399). 
FF Fractional seconds. Use a value from 1 to 9 after FF to indicate the number of digits in the fractional seconds. For example, 'FF4'. 
AM, A.M., PM, or P.M. Meridian indicator 
AD or A.D AD indicator 
BC or B.C. BC indicator 
TZD Daylight savings information. For example, 'PST' 
TZH Time zone hour. 
TZM Time zone minute. 
TZR Time zone region. 



For example:

to_date('2003/07/09', 'yyyy/mm/dd') would return a date value of July 9, 2003. 
to_date('070903', 'MMDDYY') would return a date value of July 9, 2003. 
to_date('20020315', 'yyyymmdd') would return a date value of Mar 15, 2002. 
<img src ="http://www.blogjava.net/realnicky/aggbug/26733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2006-01-05 16:37 <a href="http://www.blogjava.net/realnicky/archive/2006/01/05/26733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring的声明式事务管理</title><link>http://www.blogjava.net/realnicky/archive/2005/12/30/26012.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Fri, 30 Dec 2005 02:28:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2005/12/30/26012.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/26012.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2005/12/30/26012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/26012.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/26012.html</trackback:ping><description><![CDATA[Spring提供了声明式事务管理。这是通过Spring AOP实现的。

Spring 中进行事务管理的通常方式是利用AOP（面向切片编程）的方式，为普通java类封装事务控制，它是通过动态代理实现的，由于接口是延迟实例化的， spring在这段时间内通过拦截器，加载事务切片。原理就是这样，具体细节请参考jdk中有关动态代理的文档。本文主要讲解如何在spring中进行事务控制。
动态代理的一个重要特征是，它是针对接口的，所以我们的dao要通过动态代理来让spring接管事务，就必须在dao前面抽象出一个接口，当然如果没有这样的接口，那么spring会使用CGLIB来解决问题，但这不是spring推荐的方式，所以不做讨论.

大多数Spring用户选择声明式事务管理。这是最少影响应用代码的选择， 因而这是和非侵入性的轻量级容器的观念是一致的。 

从考虑EJB CMT和Spring声明式事务管理的相似以及不同之处出发是很有益的。 它们的基本方法是相似的：都可以指定事务管理到单独的方法；如果需要可以在事务上 下文调用setRollbackOnly()方法。不同之处如下：

不象EJB CMT绑定在JTA上，Spring声明式事务管理可以在任何环境下使用。 只需更改配置文件，它就可以和JDBC、JDO、Hibernate或其他的事务机制一起工作 

Spring可以使声明式事务管理应用到普通Java对象，不仅仅是特殊的类，如EJB

Spring提供声明式回滚规则：EJB没有对应的特性， 我们将在下面讨论这个特性。回滚可以声明式控制，不仅仅是编程式的 

Spring允许你通过AOP定制事务行为。例如，如果需要，你可以在事务 回滚中插入定制的行为。你也可以增加任意的通知，就象事务通知一样。使用 EJB CMT，除了使用setRollbackOnly()，你没有办法能 够影响容器的事务管理

Spring不提供高端应用服务器提供的跨越远程调用的事务上下文传播。如 果你需要这些特性，我们推荐你使用EJB。然而，不要轻易使用这些特性。通常我 们并不希望事务跨越远程调用

回滚规则的概念是很重要的：它们使得我们可以指定哪些异常应该发起自 动回滚。我们在配置文件中，而不是Java代码中，以声明的方式指定。因此，虽然我们仍 然可以编程调用TransactionStatus对象的 setRollbackOnly()方法来回滚当前事务，多数时候我们可以 指定规则，如MyApplicationException应该导致回滚。 这有显著的优点，业务对象不需要依赖事务基础设施。例如，它们通常不需要引 入任何Spring API，事务或其他任何东西。

EJB的默认行为是遇到系统异常（通常是运行时异常）， EJB容器自动回滚事务。EJB CMT遇到应用程序异常 （除了java.rmi.RemoteException外的checked异常）时不 会自动回滚事务。虽然Spring声明式事务管理沿用EJB的约定（遇到unchecked 异常自动回滚事务），但是这是可以定制的。

按照我们的测试，Spring声明式事务管理的性能要胜过EJB CMT。

通常通过TransactionProxyFactoryBean设置Spring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryBean时，必须提供一个相关的 PlatformTransactionManager的引用和事务属性。 事务属性含有上面描述的事务定义。

<bean id="petStore"     class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">    <property name="transactionManager"><ref bean="transactionManager"/></property>    <property name="target"><ref bean="petStoreTarget"/></property>    <property name="transactionAttributes">        <props>            <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>            <prop key="update*">PROPAGATION_REQUIRED</prop>            <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>        </props>    </property></bean>
事务代理会实现目标对象的接口：这里是id为petStoreTarget的bean。（使用 CGLIB也可以实现具体类的代理。只要设置proxyTargetClass属性为true就可以。如果目标对象没有实现任何接口，这将自动设置该属性为true。通常，我们希望面向接口而不是类编程。）使用proxyInterfaces属性来限定事务代理来代 理指定接口也是可以的（一般来说是个好想法）。也可以通过从 org.springframework.aop.framework.ProxyConfig继承或所有AOP代理工厂共享 的属性来定制TransactionProxyFactoryBean的行为。 

这里的transactionAttributes属性定义在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 中的属性格式来设置。这个包括通配符的方法名称映射是很直观的。注意 insert*的映射的值包括回滚规则。添加的-MyCheckedException 指定如果方法抛出MyCheckedException或它的子类，事务将 会自动回滚。可以用逗号分隔定义多个回滚规则。-前缀强制回滚，+前缀指定提交（这允许即使抛出unchecked异常时也可以提交事务，当然你自己要明白自己 在做什么）。

TransactionProxyFactoryBean允许你通过 “preInterceptors”和“postInterceptors”属性设置“前”或“后”通知来提供额外的 拦截行为。可以设置任意数量的“前”和“后”通知，它们的类型可以是 Advisor（可以包含一个切入点）， MethodInterceptor或被当前Spring配置支持的通知类型 （例如ThrowAdvice， AfterReturningtAdvice或BeforeAdvice， 这些都是默认支持的）。这些通知必须支持实例共享模式。如果你需要高级AOP特 性来使用事务，如有状态的maxin，那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean， 而不是TransactionProxyFactoryBean实用代理创建者。

也可以设置自动代理：配置AOP框架，不需要单独的代理定义类就可以生成类的 代理。

附两个spring的事务配置例子：
<prop key="add">
     PROPAGATION_REQUIRES_NEW, -MyException 
</prop>
注：上面的意思是add方法将独占一个事务，当事务处理过程中产生MyException异常或者该异常的子类将回滚该事务。

<prop key="loadAll">
    PROPAGATION_SUPPORTS, ISOLATION_READ_COMMITED, Readonly
</prop>
注：表示loadAll方法支持事务，而且不会读取没有提交事务的数据。它的数据为只读（这样有助于提高读取的性能）

附A Spring中的所有事务策略

PROPAGATION_MANDATORY
PROPAGATION_NESTED 
PROPAGATION_NEVER 
PROPAGATION_NOT_SUPPORTED
PROPAGATION_REQUIRED
PROPAGATION_REQUIRED_NEW
PROPAGATION_SUPPORTS

附B Spring中所有的隔离策略：

ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITED
ISOLATION_COMMITED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE <img src ="http://www.blogjava.net/realnicky/aggbug/26012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2005-12-30 10:28 <a href="http://www.blogjava.net/realnicky/archive/2005/12/30/26012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中static、this、super、final用法简谈(三)</title><link>http://www.blogjava.net/realnicky/archive/2005/12/29/25840.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Thu, 29 Dec 2005 02:21:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2005/12/29/25840.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/25840.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2005/12/29/25840.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/25840.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/25840.html</trackback:ping><description><![CDATA[三、final

final在Java中并不常用，然而它却为我们提供了诸如在C语言中定义常量的功能，不仅如此，final还可以让你控制你的成员、方法或者是一个类是否可被覆写或继承等功能，这些特点使final在Java中拥有了一个不可或缺的地位，也是学习Java时必须要知道和掌握的关键字之一。
final成员
当你在类中定义变量时，在其前面加上final关键字，那便是说，这个变量一旦被初始化便不可改变，这里不可改变的意思对基本类型来说是其值不可变，而对于对象变量来说其引用不可再变。其初始化可以在两个地方，一是其定义处，也就是说在final变量定义时直接给其赋值，二是在构造函数中。这两个地方只能选其一，要么在定义时给值，要么在构造函数中给值，不能同时既在定义时给了值，又在构造函数中给另外的值。下面这段代码演示了这一点：

import java.util.List; 
import java.util.ArrayList; 
import java.util.LinkedList; 
public class Bat{ 
    final PI=3.14;          //在定义时便给址值 
    final int i;            //因为要在构造函数中进行初始化，所以此处便不可再给值 
    final List list;        //此变量也与上面的一样 
    Bat(){ 
        i=100; 
        list=new LinkedList(); 
    } 
    Bat(int ii,List l){ 
        i=ii; 
        list=l; 
    } 
    public static void main(String[] args){ 
        Bat b=new Bat(); 
        b.list.add(new Bat()); 
        //b.i=25; 
        //b.list=new ArrayList(); 
        System.out.println("I="+b.i+" List Type:"+b.list.getClass()); 
        b=new Bat(23,new ArrayList()); 
        b.list.add(new Bat()); 
        System.out.println("I="+b.i+" List Type:"+b.list.getClass()); 
    } 
} 

此程序很简单的演示了final的常规用法。在这里使用在构造函数中进行初始化的方法，这使你有了一点灵活性。如Bat的两个重载构造函数所示，第一个缺省构造函数会为你提供默认的值，重载的那个构造函数会根据你所提供的值或类型为final变量初始化。然而有时你并不需要这种灵活性，你只需要在定义时便给定其值并永不变化，这时就不要再用这种方法。在main方法中有两行语句注释掉了，如果你去掉注释，程序便无法通过编译，这便是说，不论是i的值或是list的类型，一旦初始化，确实无法再更改。然而b可以通过重新初始化来指定i的值或list的类型，输出结果中显示了这一点：
I=100 List Type:class java.util.LinkedList
I=23 List Type:class java.util.ArrayList
还有一种用法是定义方法中的参数为final，对于基本类型的变量，这样做并没有什么实际意义，因为基本类型的变量在调用方法时是传值的，也就是说你可以在方法中更改这个参数变量而不会影响到调用语句，然而对于对象变量，却显得很实用，因为对象变量在传递时是传递其引用，这样你在方法中对对象变量的修改也会影响到调用语句中的对象变量，当你在方法中不需要改变作为参数的对象变量时，明确使用final进行声明，会防止你无意的修改而影响到调用方法。
另外方法中的内部类在用到方法中的参变量时，此参变也必须声明为final才可使用，如下代码所示：

public class INClass{ 
   void innerClass(final String str){ 
        class IClass{ 
            IClass(){ 
                System.out.println(str); 
            } 
        } 
        IClass ic=new IClass(); 
    } 
  public static void main(String[] args){ 
      INClass inc=new INClass(); 
      inc.innerClass("Hello"); 
  } 
} 

final方法
将方法声明为final，那就说明你已经知道这个方法提供的功能已经满足你要求，不需要进行扩展，并且也不允许任何从此类继承的类来覆写这个方法，但是继承仍然可以继承这个方法，也就是说可以直接使用。另外有一种被称为inline的机制，它会使你在调用final方法时，直接将方法主体插入到调用处，而不是进行例行的方法调用，例如保存断点，压栈等，这样可能会使你的程序效率有所提高，然而当你的方法主体非常庞大时，或你在多处调用此方法，那么你的调用主体代码便会迅速膨胀，可能反而会影响效率，所以你要慎用final进行方法定义。

final类
当你将final用于类身上时，你就需要仔细考虑，因为一个final类是无法被任何人继承的，那也就意味着此类在一个继承树中是一个叶子类，并且此类的设计已被认为很完美而不需要进行修改或扩展。对于final类中的成员，你可以定义其为final，也可以不是final。而对于方法，由于所属类为final的关系，自然也就成了final型的。你也可以明确的给final类中的方法加上一个final，但这显然没有意义。
下面的程序演示了final方法和final类的用法：

final class final{ 
    final String str="final Data"; 
    public String str1="non final data"; 
    final public void print(){ 
        System.out.println("final method."); 
    } 
    public void what(){ 
        System.out.println(str+"\n"+str1); 
    } 
} 
public class FinalDemo {   //extends final 无法继承  
    public static void main(String[] args){ 
        final f=new final(); 
        f.what(); 
        f.print(); 
    } 
} 

从程序中可以看出，final类与普通类的使用几乎没有差别，只是它失去了被继承的特性。final方法与非final方法的区别也很难从程序行看出，只是记住慎用。
final在设计模式中的应用
在设计模式中有一种模式叫做不变模式，在Java中通过final关键字可以很容易的实现这个模式，在讲解final成员时用到的程序Bat.java就是一个不变模式的例子。如果你对此感兴趣，可以参考阎宏博士编写的《Java与模式》一书中的讲解。

到此为止，this,static,supert和final的使用已经说完了，如果你对这四个关键字已经能够大致说出它们的区别与用法，那便说明你基本已经掌握。然而，世界上的任何东西都不是完美无缺的，Java提供这四个关键字，给程序员的编程带来了很大的便利，但并不是说要让你到处使用，一旦达到滥用的程序，便适得其反，所以在使用时请一定要认真考虑。 
<img src ="http://www.blogjava.net/realnicky/aggbug/25840.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2005-12-29 10:21 <a href="http://www.blogjava.net/realnicky/archive/2005/12/29/25840.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中static、this、super、final用法简谈(一)</title><link>http://www.blogjava.net/realnicky/archive/2005/12/29/25836.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Thu, 29 Dec 2005 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2005/12/29/25836.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/25836.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2005/12/29/25836.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/25836.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/25836.html</trackback:ping><description><![CDATA[本篇旨在帮助准备学习Java以及刚接触Java的朋友认识、掌握和使用static、this、super、final这几个关键字的使用。Java博大精深，我也是一位正在学习和使用Java的爱好者，文中难免有不妥之处，欢迎指正。

一、static
    请先看下面这段程序：

  public class Hello{ 
    public static void main(String[] args){ //(1) 
      System.out.println("Hello,world!");   //(2) 
    } 
  } 

看过这段程序，对于大多数学过Java 的从来说，都不陌生。即使没有学过Java，而学过其它的高级语言，例如C，那你也应该能看懂这段代码的意思。它只是简单的输出“Hello,world”，一点别的用处都没有，然而，它却展示了static关键字的主要用法。 
在1处，我们定义了一个静态的方法名为main，这就意味着告诉Java编译器，我这个方法不需要创建一个此类的对象即可使用。你还得你是怎么运行这个程序吗？一般，我们都是在命令行下，打入如下的命令(加下划线为手动输入)：
javac Hello.java
java Hello
Hello,world!
这就是你运行的过程，第一行用来编译Hello.java这个文件，执行完后，如果你查看当前，会发现多了一个Hello.class文件，那就是第一行产生的Java二进制字节码。第二行就是执行一个Java程序的最普遍做法。执行结果如你所料。在2中，你可能会想，为什么要这样才能输出。好，我们来分解一下这条语句。（如果没有安装Java文档，请到Sun的官方网站浏览J2SE API）首先，System是位于java.lang包中的一个核心类，如果你查看它的定义，你会发现有这样一行：public static final PrintStream out;接着在进一步，点击PrintStream这个超链接，在METHOD页面，你会看到大量定义的方法，查找println，会有这样一行：
public void println(String x)。好了，现在你应该明白为什么我们要那样调用了，out是System的一个静态变量，所以可以直接使用，而out所属的类有一个println方法。

静态方法
通常，在一个类中定义一个方法为static，那就是说，无需本类的对象即可调用此方法。如下所示：

class Simple{ 
   static void go(){ 
     System.out.println("Go..."); 
   } 
} 
public class Cal{ 
  public static void main(String[] args){ 
    Simple.go(); 
  } 
} 

调用一个静态方法就是“类名.方法名”,静态方法的使用很简单如上所示。一般来说，静态方法常常为应用程序中的其它类提供一些实用工具所用，在Java的类库中大量的静态方法正是出于此目的而定义的。
静态变量
静态变量与静态方法类似。所有此类实例共享此静态变量，也就是说在类装载时，只分配一块存储空间，所有此类的对象都可以操控此块存储空间，当然对于final则另当别论了。看下面这段代码：
class Value{ 
  static int c=0; 
  static void inc(){ 
    c++; 
  } 
} 
class Count{ 
  public static void prt(String s){ 
    System.out.println(s); 
  } 
  public static void main(String[] args){ 
    Value v1,v2; 
    v1=new Value(); 
    v2=new Value(); 
    prt("v1.c="+v1.c+"  v2.c="+v2.c); 
    v1.inc(); 
    prt("v1.c="+v1.c+"  v2.c="+v2.c);   
  } 
} 
结果如下：
v1.c=0  v2.c=0
v1.c=1  v2.c=1
由此可以证明它们共享一块存储区。static变量有点类似于C中的全局变量的概念。值得探讨的是静态变量的初始化问题。我们修改上面的程序：
class Value{ 
  static int c=0; 
  Value(){ 
    c=15; 
  } 
  Value(int i){ 
    c=i; 
  } 
  static void inc(){ 
    c++; 
  } 
} 
class Count{ 
  public static void prt(String s){ 
    System.out.println(s); 
  } 
    Value v=new Value(10); 
    static Value v1,v2; 
    static{ 
      prt("v1.c="+v1.c+"  v2.c="+v2.c); 
      v1=new Value(27); 
      prt("v1.c="+v1.c+"  v2.c="+v2.c); 
      v2=new Value(15); 
      prt("v1.c="+v1.c+"  v2.c="+v2.c); 
    } 

  public static void main(String[] args){ 
    Count ct=new Count(); 
    prt("ct.c="+ct.v.c); 
    prt("v1.c="+v1.c+"  v2.c="+v2.c); 
    v1.inc(); 
    prt("v1.c="+v1.c+"  v2.c="+v2.c); 
    prt("ct.c="+ct.v.c); 
  } 
} 

运行结果如下：
v1.c=0  v2.c=0
v1.c=27  v2.c=27
v1.c=15  v2.c=15
ct.c=10
v1.c=10  v2.c=10
v1.c=11  v2.c=11
ct.c=11
这个程序展示了静态初始化的各种特性。如果你初次接触Java，结果可能令你吃惊。可能会对static后加大括号感到困惑。首先要告诉你的是，static定义的变量会优先于任何其它非static变量，不论其出现的顺序如何。正如在程序中所表现的，虽然v出现在v1和v2的前面，但是结果却是v1和v2的初始化在v的前面。在static{后面跟着一段代码，这是用来进行显式的静态变量初始化，这段代码只会初始化一次，且在类被第一次装载时。如果你能读懂并理解这段代码，会帮助你对static关键字的认识。在涉及到继承的时候，会先初始化父类的static变量，然后是子类的，依次类推。非静态变量不是本文的主题，在此不做详细讨论，请参考Think in Java中的讲解。
静态类
通常一个普通类不允许声明为静态的，只有一个内部类才可以。这时这个声明为静态的内部类可以直接作为一个普通类来使用，而不需实例一个外部类。如下代码所示：

public class StaticCls{ 
  public static void main(String[] args){ 
    OuterCls.InnerCls oi=new OuterCls.InnerCls(); 
  } 
} 
class OuterCls{ 
  public static class InnerCls{ 
    InnerCls(){ 
      System.out.println("InnerCls"); 
    } 
   } 
} 

输出结果会如你所料：
InnerCls
和普通类一样。内部类的其它用法请参阅Think in Java中的相关章节，此处不作详解。
关于另三篇文章（this,super,final）会陆续发表，敬请关注。 
<img src ="http://www.blogjava.net/realnicky/aggbug/25836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2005-12-29 10:06 <a href="http://www.blogjava.net/realnicky/archive/2005/12/29/25836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>appfuse - 怎么样开始学习 springframework</title><link>http://www.blogjava.net/realnicky/archive/2005/12/27/25590.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Tue, 27 Dec 2005 08:09:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2005/12/27/25590.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/25590.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2005/12/27/25590.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/25590.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/25590.html</trackback:ping><description><![CDATA[先推荐 eclipse 3.0M9 ，界面上又是漂亮了许多，功能细节方面也有很大的改进，比如之前只有 IDEA 里才有的 fold 现在 eclipse 也有了，真是开心啊。
eclipse 官方 3.0M9 的 news 有详细地介绍到这个新版本新增或者改进的功能，我前天晚上看到深夜呢，真过瘾。

tomcat 也出新版本了， 5.0.25 ，最明显的改变就是图形界面的启动、设置比 5.0.19 改动了不少。感觉是越来越方便了。

这里重点推介 AppFuse ，它的目标是作为一个 webapp 的模板、起点，简化你的 webapp 开发基础工作。它集成了目前最流行的几个开源轻量级框架或者工具 Spring / Hibernate / ibatis / Struts / XDoclet / junit 等等一长串。还有 ant task 都写得非常全面。而且 AppFuse 的网站 都有文章教写每一个模块。具体更多的信息请参考 AppFuse 网站 。说实话我都准备通过这个集成框架来学习 spring / hibernate 等新的东西。

还要推荐的是，昨天 AppFuse 的作者 Matt Raible 在他的blog Spring Live 上写了一些关于学习 Spring 的建议，我觉得值得花点时间翻译一下，推荐给更多的人....

如果你认为 Spring 太大太复杂，我来给你一些建议。学习 Spring 是无法抗拒的，你应该阅读什么文章、练习什么教程呢？ 首先我建议看 Rod Johnson's 发表在 TheServerSide.com 上的文章：Introducing the Spring Framework 。教程方面有 Developing a Spring Framework MVC application step-by-step ，这个教程不错，但它没有谈到 hibernate ，也只是一个简单的例子。

如果你想用 spring + hibernate 开发一个实际的 webapp ，那我建议你看看 AppFuse ，它是为了简化开发 Java Webapp 的开始过程而设计的。它有预定义好的目录结构、基类、很多用来创建数据库、配置Tomcat、测试部署应用的 Ant 任务。 AppFuse 贯穿 Spring ，包括 hibernate , IoC container , 申明式事务以及 MVC 层。它也信奉 TDD ，使用 junit 来测试所有的层，甚至测试 jsp 输出的 w/o 错误。如果你不想使用 Spring 自带的 MVC ，你可以用 Struts 来代替。最棒的是，关于 AppFuse 有许多的文档，包括怎么样创建DAO、商业代理与不同的MVC组件 。
我昨天刚刚发布了新的版本 AppFuse 1.5 。如果你有兴趣，你可以下载 Spring MVC 版本与 Struts 版本 。我希望你喜欢这些教程，如果这样我会非常高兴。基于 Spring MVC 框架工作与它的生命周期方法是个非常愉快的经历。另外，AppFuse 使得通过在 POLOs 上加 XDoclet 标签来使得实现验证更加容易。这是个 DEMO ，如果你想更加直观地看看 AppFuse 的效果的话。

转于http://www.matrix.org.cn/blog/javen/archives/000413.html<img src ="http://www.blogjava.net/realnicky/aggbug/25590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2005-12-27 16:09 <a href="http://www.blogjava.net/realnicky/archive/2005/12/27/25590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA基础笔试题</title><link>http://www.blogjava.net/realnicky/archive/2005/12/27/25586.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Tue, 27 Dec 2005 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2005/12/27/25586.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/25586.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2005/12/27/25586.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/25586.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/25586.html</trackback:ping><description><![CDATA[如有疑问,欢迎与我交流!

Java基础方面: 
1、作用域public,private,protected,以及不写时的区别 
答：区别如下： 
作用域 当前类 同一package 子孙类 其他package 
public √ √ √ √ 
protected √ √ √ × 
friendly √ √ × × 
private √ × × × 
不写时默认为friendly 

2、ArrayList和Vector的区别,HashMap和Hashtable的区别 
答：就ArrayList与Vector主要从二方面来说. 
一.同步性:Vector是线程安全的，也就是说是同步的，而ArrayList是线程序不安全的，不是同步的 
二.数据增长:当需要增长时,Vector默认增长为原来一培，而ArrayList却是原来的一半 
就HashMap与HashTable主要从三方面来说。 
一.历史原因:Hashtable是基于陈旧的Dictionary类的，HashMap是Java 1.2引进的Map接口的一个实现 
二.同步性:Hashtable是线程安全的，也就是说是同步的，而HashMap是线程序不安全的，不是同步的 
三.值：只有HashMap可以让你将空值作为一个表的条目的key或value 

3、char型变量中能不能存贮一个中文汉字?为什么? 
答：是能够定义成为一个中文的，因为java中以unicode编码，一个char占16个字节，所以放一个中文是没问题的 

4、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么? 
答：多线程有两种实现方法，分别是继承Thread类与实现Runnable接口 
同步的实现方面有两种，分别是synchronized,wait与notify 

5、继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么? 
答:父类： 
package test; 
public class FatherClass 
{ 
public FatherClass() 
{ 
System.out.println("FatherClass Create"); 
} 
} 
子类: 
package test; 
import test.FatherClass; 
public class ChildClass extends FatherClass 
{ 
public ChildClass() 
{ 
System.out.println("ChildClass Create"); 
} 
public static void main(String[] args) 
{ 
FatherClass fc = new FatherClass(); 
ChildClass cc = new ChildClass(); 
} 
} 
输出结果： 
C:>java test.ChildClass 
FatherClass Create 
FatherClass Create 
ChildClass Create 

6、内部类的实现方式? 
答：示例代码如下： 
package test; 
public class OuterClass 
{ 
private class InterClass 
{ 
public InterClass() 
{ 
System.out.println("InterClass Create"); 
} 
} 
public OuterClass() 
{ 
InterClass ic = new InterClass(); 
System.out.println("OuterClass Create"); 
} 
public static void main(String[] args) 
{ 
OuterClass oc = new OuterClass(); 
} 
} 
输出结果: 
C:>java test/OuterClass 
InterClass Create 
OuterClass Create 
再一个例题： 
public class OuterClass { 
private double d1 = 1.0; 
//insert code here 
} 
You need to insert an inner class declaration at line 3. Which two inner class declarations are 

valid?(Choose two.) 
A. class InnerOne{ 
public static double methoda() {return d1;} 
} 
B. public class InnerOne{ 
static double methoda() {return d1;} 
} 
C. private class InnerOne{ 
double methoda() {return d1;} 
} 
D. static class InnerOne{ 
protected double methoda() {return d1;} 
} 
E. abstract class InnerOne{ 
public abstract double methoda(); 
} 
说明如下： 
一.静态内部类可以有静态成员，而非静态内部类则不能有静态成员。 故 A、B 错 
二.静态内部类的非静态成员可以访问外部类的静态变量，而不可访问外部类的非静态变量；return d1 出错。 

故 D 错 
三.非静态内部类的非静态成员可以访问外部类的非静态变量。 故 C 正确 
四.答案为C、E 

7、垃圾回收机制,如何优化程序? 
希望大家补上，谢谢 

8、float型float f=3.4是否正确? 
答:不正确。精度不准确,应该用强制类型转换，如下所示：float f=(float)3.4 

9、介绍JAVA中的Collection FrameWork(包括如何写自己的数据结构)? 
答：Collection FrameWork如下： 
Collection 
├List 
│├LinkedList 
│├ArrayList 
│└Vector 
│　└Stack 
└Set 
Map 
├Hashtable 
├HashMap 
└WeakHashMap 
Collection是最基本的集合接口，一个Collection代表一组Object，即Collection的元素（Elements） 
Map提供key到value的映射 

10、Java中异常处理机制，事件机制？ 

11、JAVA中的多形与继承？ 
希望大家补上，谢谢 

12、抽象类与接口？ 
答：抽象类与接口都用于抽象，但是抽象类(JAVA中)可以有自己的部分实现，而接口则完全是一个标识(同时有多重继承的功能)。 

13、Java 的通信编程，编程题(或问答)，用JAVA SOCKET编程，读服务器几个字符，再写入本地显示？ 
答:Server端程序: 
package test; 
import java.net.*; 
import java.io.*; 

public class Server 
{ 
private ServerSocket ss; 
private Socket socket; 
private BufferedReader in; 
private PrintWriter out; 
public Server() 
{ 
try 
{ 
ss=new ServerSocket(10000); 
while(true) 
{ 
socket = ss.accept(); 
String RemoteIP = socket.getInetAddress().getHostAddress(); 
String RemotePort = ":"+socket.getLocalPort(); 
System.out.println("A client come in!IP:"+RemoteIP+RemotePort); 
in = new BufferedReader(new 

InputStreamReader(socket.getInputStream())); 
String line = in.readLine(); 
System.out.println("Cleint send is :" + line); 
out = new PrintWriter(socket.getOutputStream(),true); 
out.println("Your Message Received!"); 
out.close(); 
in.close(); 
socket.close(); 
} 
}catch (IOException e) 
{ 
out.println("wrong"); 
} 
} 
public static void main(String[] args) 
{ 
new Server(); 
} 
}; 
Client端程序: 
package test; 
import java.io.*; 
import java.net.*; 

public class Client 
{ 
Socket socket; 
BufferedReader in; 
PrintWriter out; 
public Client() 
{ 
try 
{ 
System.out.println("Try to Connect to 127.0.0.1:10000"); 
socket = new Socket("127.0.0.1",10000); 
System.out.println("The Server Connected!"); 
System.out.println("Please enter some Character:"); 
BufferedReader line = new BufferedReader(new 

InputStreamReader(System.in)); 
out = new PrintWriter(socket.getOutputStream(),true); 
out.println(line.readLine()); 
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
System.out.println(in.readLine()); 
out.close(); 
in.close(); 
socket.close(); 
}catch(IOException e) 
{ 
out.println("Wrong"); 
} 
} 
public static void main(String[] args) 
{ 
new Client(); 
} 
}; 

14、用JAVA实现一种排序，JAVA类实现序列化的方法(二种)？ 如在COLLECTION框架中，实现比较要实现什么样的接口？ 
答:用插入法进行排序代码如下 
package test; 
import java.util.*; 
class InsertSort 
{ 
ArrayList al; 
public InsertSort(int num,int mod) 
{ 
al = new ArrayList(num); 
Random rand = new Random(); 
System.out.println("The ArrayList Sort Before:"); 
for (int i=0;i<num ;i++ ) 
{ 
al.add(new Integer(Math.abs(rand.nextInt()) % mod + 1)); 
System.out.println("al["+i+"]="+al.get(i)); 
} 
} 
public void SortIt() 
{ 
Integer tempInt; 
int MaxSize=1; 
for(int i=1;i<al.size();i++) 
{ 
tempInt = (Integer)al.remove(i); 
if(tempInt.intValue()>=((Integer)al.get(MaxSize-1)).intValue()) 
{ 
al.add(MaxSize,tempInt); 
MaxSize++; 
System.out.println(al.toString()); 
} else { 
for (int j=0;j<MaxSize ;j++ ) 
{ 
if 

(((Integer)al.get(j)).intValue()>=tempInt.intValue()) 
{ 
al.add(j,tempInt); 
MaxSize++; 
System.out.println(al.toString()); 
break; 
} 
} 
} 
} 
System.out.println("The ArrayList Sort After:"); 
for(int i=0;i<al.size();i++) 
{ 
System.out.println("al["+i+"]="+al.get(i)); 
} 
} 
public static void main(String[] args) 
{ 
InsertSort is = new InsertSort(10,100); 
is.SortIt(); 
} 
} 
JAVA类实现序例化的方法是实现java.io.Serializable接口 
Collection框架中实现比较要实现Comparable 接口和 Comparator 接口 

15、编程：编写一个截取字符串的函数，输入为一个字符串和字节数，输出为按字节截取的字符串。 但是要保证汉字不被截半个，如“我ABC”4，应该截为“我AB”，输入“我ABC汉DEF”，6，应该输出为“我ABC”而不是“我ABC+汉的半个”。 
答：代码如下： 
package test; 

class SplitString 
{ 
String SplitStr; 
int SplitByte; 
public SplitString(String str,int bytes) 
{ 
SplitStr=str; 
SplitByte=bytes; 
System.out.println("The String is:′"+SplitStr+"′;SplitBytes="+SplitByte); 
} 
public void SplitIt() 
{ 
int loopCount; 


loopCount=(SplitStr.length()%SplitByte==0)?(SplitStr.length()/SplitByte):(SplitStr.length()/Split 

Byte+1); 
System.out.println("Will Split into "+loopCount); 
for (int i=1;i<=loopCount ;i++ ) 
{ 
if (i==loopCount){ 


System.out.println(SplitStr.substring((i-1)*SplitByte,SplitStr.length())); 
} else { 


System.out.println(SplitStr.substring((i-1)*SplitByte,(i*SplitByte))); 
} 
} 
} 
public static void main(String[] args) 
{ 
SplitString ss = new SplitString("test中dd文dsaf中男大3443n中国43中国人 

0ewldfls=103",4); 
ss.SplitIt(); 
} 
} 

16、JAVA多线程编程。 用JAVA写一个多线程程序，如写四个线程，二个加1，二个对一个变量减一，输出。 
希望大家补上，谢谢 

17、STRING与STRINGBUFFER的区别。 
答：STRING的长度是不可变的，STRINGBUFFER的长度是可变的。如果你对字符串中的内容经常进行操作，特别是内容要修改时，那么使用StringBuffer，如果最后需要String，那么使用StringBuffer的toString()方法 

Jsp方面 

1、jsp有哪些内置对象?作用分别是什么? 
答:JSP共有以下9种基本内置组件（可与ASP的6种内部组件相对应）： 
　request 用户端请求，此请求会包含来自GET/POST请求的参数 
response 网页传回用户端的回应 
pageContext 网页的属性是在这里管理 
session 与请求有关的会话期 
application servlet 正在执行的内容 
out 用来传送回应的输出 
config servlet的构架部件 
page JSP网页本身 
exception 针对错误网页，未捕捉的例外 

2、jsp有哪些动作?作用分别是什么? 
答:JSP共有以下6种基本动作 
jsp:include：在页面被请求的时候引入一个文件。 
jsp:useBean：寻找或者实例化一个JavaBean。 
jsp:setProperty：设置JavaBean的属性。 
jsp:getProperty：输出某个JavaBean的属性。 
jsp:forward：把请求转到一个新的页面。 
jsp:plugin：根据浏览器类型为Java插件生成OBJECT或EMBED标记 

3、JSP中动态INCLUDE与静态INCLUDE的区别？ 
答：动态INCLUDE用jsp:include动作实现 
<jsp:include page="included.jsp" flush="true" />它总是会检查所含文件中的变化，适合用于包含动态页面，并且可以带参数 
静态INCLUDE用include伪码实现,定不会检查所含文件的变化，适用于包含静态页面 
<%@ include file="included.htm" %> 

4、两种跳转方式分别是什么?有什么区别? 
答：有两种，分别为： 
<jsp:include page="included.jsp" flush="true"> 
<jsp:forward page= "nextpage.jsp"/> 
前者页面不会转向include所指的页面，只是显示该页的结果，主页面还是原来的页面。执行完后还会回来，相当于函数调用。并且可以带参数.后者完全转向新页面，不会再回来。相当于go to 语句。 

Servlet方面 

1、说一说Servlet的生命周期? 
答:servlet有良好的生存期的定义，包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。 

2、Servlet版本间(忘了问的是哪两个版本了)的不同? 
希望大家补上，谢谢 

3、JAVA SERVLET API中forward() 与redirect()的区别？ 
答:前者仅是容器中控制权的转向，在客户端浏览器地址栏中不会显示出转向后的地址；后者则是完全的跳转，浏览器将会得到跳转的地址，并重新发送请求链接。这样，从浏览器的地址栏中可以看到跳转后的链接地址。所以，前者更加高效，在前者可以满足需要时，尽量使用forward()方法，并且，这样也有助于隐藏实际的链接。在有些情况下，比如，需要跳转到一个其它服务器上的资源，则必须使用sendRedirect()方法。 

4、Servlet的基本架构 
public class ServletName extends HttpServlet { 
public void doPost(HttpServletRequest request, HttpServletResponse response) throws 
ServletException, IOException { 
} 
public void doGet(HttpServletRequest request, HttpServletResponse response) throws 
ServletException, IOException { 
} 
} 

Jdbc、Jdo方面 

1、可能会让你写一段Jdbc连Oracle的程序,并实现数据查询. 
答:程序如下： 
package hello.ant; 
import java.sql.*; 
public class jdbc 
{ 
String dbUrl="jdbc:oracle:thin:@127.0.0.1:1521:orcl"; 
String theUser="admin"; 
String thePw="manager"; 
Connection c=null; 
Statement conn; 
ResultSet rs=null; 
public jdbc() 
{ 
try{ 
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); 
c = DriverManager.getConnection(dbUrl,theUser,thePw); 
conn=c.createStatement(); 
}catch(Exception e){ 
e.printStackTrace(); 
} 
} 
public boolean executeUpdate(String sql) 
{ 
try 
{ 
conn.executeUpdate(sql); 
return true; 
} 
catch (SQLException e) 
{ 
e.printStackTrace(); 
return false; 
} 
} 
public ResultSet executeQuery(String sql) 
{ 
rs=null; 
try 
{ 
rs=conn.executeQuery(sql); 
} 
catch (SQLException e) 
{ 
e.printStackTrace(); 
} 
return rs; 
} 
public void close() 
{ 
try 
{ 
conn.close(); 
c.close(); 
} 
catch (Exception e) 
{ 
e.printStackTrace(); 
} 
} 
public static void main(String[] args) 
{ 
ResultSet rs; 
jdbc conn = new jdbc(); 
rs=conn.executeQuery("select * from test"); 
try{ 
while (rs.next()) 
{ 
System.out.println(rs.getString("id")); 
System.out.println(rs.getString("name")); 
} 
}catch(Exception e) 
{ 
e.printStackTrace(); 
} 
} 
} 

2、Class.forName的作用?为什么要用? 
答：调用该访问返回一个以字符串指定类名的类的对象。 

3、Jdo是什么? 
答:JDO是Java对象持久化的新的规范，为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储，因此对开发人员来说，存储数据对象完全不需要额外的代码（如JDBC API的使用）。这些繁琐的例行工作已经转移到JDO产品提供商身上，使开发人员解脱出来，从而集中时间和精力在业务逻辑上。另外，JDO很灵活，因为它可以在任何数据底层上运行。JDBC只是面向关系数据库（RDBMS)JDO更通用，提供到任何数据底层的存储功能，比如关系数据库、文件、XML以及对象数据库（ODBMS）等等，使得应用可移植性更强。 

4、在ORACLE大数据量下的分页解决方法。一般用截取ID方法，还有是三层嵌套方法。 
答:一种分页方法 
<% 
int i=1; 
int numPages=14; 
String pages = request.getParameter("page") ; 
int currentPage = 1; 
currentPage=(pages==null)?(1):{Integer.parseInt(pages)} 
sql = "select count(*) from tables"; 
ResultSet rs = DBLink.executeQuery(sql) ; 
while(rs.next()) i = rs.getInt(1) ; 
int intPageCount=1; 
intPageCount=(i%numPages==0)?(i/numPages):(i/numPages+1); 
int nextPage ; 
int upPage; 
nextPage = currentPage+1; 
if (nextPage>=intPageCount) nextPage=intPageCount; 
upPage = currentPage-1; 
if (upPage<=1) upPage=1; 
rs.close(); 
sql="select * from tables"; 
rs=DBLink.executeQuery(sql); 
i=0; 
while((i<numPages*(currentPage-1))&&rs.next()){i++;} 
%> 
//输出内容 
//输出翻页连接 
合计:<%=currentPage%>/<%=intPageCount%><a href="/List.jsp?page=1">第一页</a><a 

href="List.jsp?page=<%=upPage%>">上一页</a> 
<% 
for(int j=1;j<=intPageCount;j++){ 
if(currentPage!=j){ 
%> 
<a href="list.jsp?page=<%=j%>">[<%=j%>]</a> 
<% 
}else{ 
out.println(j); 
} 
} 
%> 
<a href="List.jsp?page=<%=nextPage%>">下一页</a><a href="List.jsp?page=<%=intPageCount%>">最后页 

</a> 


Xml方面 

1、xml有哪些解析技术?区别是什么? 
答:有DOM,SAX,STAX等 
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的，这种结构占用的内存较多，而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件，不需要一次全部装载整个文件。当遇到像文件开头，文档结束，或者标签开头与标签结束时，它会触发一个事件，用户通过在其回调事件中写入处理代码来处理XML文件，适合对XML的顺序访问 
STAX:Streaming API for XML (StAX) 

2、你在项目中用到了xml技术的哪些方面?如何实现的? 
答:用到了数据存贮，信息配置两方面。在做数据交换平台时，将不能数据源的数据组装成XML文件，然后将XML文件压缩打包加密后通过网络传送给接收者，接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时，利用XML可以很方便的进行，软件的各种配置参数都存贮在XML文件中。 

3、用jdom解析xml文件时如何解决中文问题?如何解析? 
答:看如下代码,用编码方式加以解决 
package test; 
import java.io.*; 
public class DOMTest 
{ 
private String inFile = "c:\people.xml"; 
private String outFile = "c:\people.xml"; 
public static void main(String args[]) 
{ 
new DOMTest(); 
} 
public DOMTest() 
{ 
try 
{ 
javax.xml.parsers.DocumentBuilder builder = 


javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
org.w3c.dom.Document doc = builder.newDocument(); 
org.w3c.dom.Element root = doc.createElement("老师"); 
org.w3c.dom.Element wang = doc.createElement("王"); 
org.w3c.dom.Element liu = doc.createElement("刘"); 
wang.appendChild(doc.createTextNode("我是王老师")); 
root.appendChild(wang); 
doc.appendChild(root); 
javax.xml.transform.Transformer transformer = 
javax.xml.transform.TransformerFactory.newInstance().newTransformer(); 
transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, "gb2312"); 
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes"); 


transformer.transform(new javax.xml.transform.dom.DOMSource(doc), 
new 

javax.xml.transform.stream.StreamResult(outFile)); 
} 
catch (Exception e) 
{ 
System.out.println (e.getMessage()); 
} 
} 
} 

4、编程用JAVA解析XML的方式. 
答:用SAX方式解析XML，XML文件如下： 
<?xml version="1.0" encoding="gb2312"?> 
<person> 
<name>王小明</name> 
<college>信息学院</college> 
<telephone>6258113</telephone> 
<notes>男,1955年生,博士，95年调入海南大学</notes> 
</person> 
事件回调类SAXHandler.java 
import java.io.*; 
import java.util.Hashtable; 
import org.xml.sax.*; 
public class SAXHandler extends HandlerBase 
{ 
private Hashtable table = new Hashtable(); 
private String currentElement = null; 
private String currentValue = null; 
public void setTable(Hashtable table) 
{ 
this.table = table; 
} 
public Hashtable getTable() 
{ 
return table; 
} 
public void startElement(String tag, AttributeList attrs) 
throws SAXException 
{ 
currentElement = tag; 
} 
public void characters(char[] ch, int start, int length) 
throws SAXException 
{ 
currentValue = new String(ch, start, length); 
} 
public void endElement(String name) throws SAXException 
{ 
if (currentElement.equals(name)) 
table.put(currentElement, currentValue); 
} 
} 
JSP内容显示源码,SaxXml.jsp: 
<HTML> 
<HEAD> 
<TITLE>剖析XML文件people.xml</TITLE> 
</HEAD> 
<BODY> 
<%@ page errorPage="ErrPage.jsp" 
contentType="text/html;charset=GB2312" %> 
<%@ page import="java.io.*" %> 
<%@ page import="java.util.Hashtable" %> 
<%@ page import="org.w3c.dom.*" %> 
<%@ page import="org.xml.sax.*" %> 
<%@ page import="javax.xml.parsers.SAXParserFactory" %> 
<%@ page import="javax.xml.parsers.SAXParser" %> 
<%@ page import="SAXHandler" %> 
<% 
File file = new File("c:\people.xml"); 
FileReader reader = new FileReader(file); 
Parser parser; 
SAXParserFactory spf = SAXParserFactory.newInstance(); 
SAXParser sp = spf.newSAXParser(); 
SAXHandler handler = new SAXHandler(); 
sp.parse(new InputSource(reader), handler); 
Hashtable hashTable = handler.getTable(); 
out.println("<TABLE BORDER=2><CAPTION>教师信息表</CAPTION>"); 
out.println("<TR><TD>姓名</TD>" + "<TD>" + 
(String)hashTable.get(new String("name")) + "</TD></TR>"); 
out.println("<TR><TD>学院</TD>" + "<TD>" + 
(String)hashTable.get(new String("college"))+"</TD></TR>"); 
out.println("<TR><TD>电话</TD>" + "<TD>" + 
(String)hashTable.get(new String("telephone")) + "</TD></TR>"); 
out.println("<TR><TD>备注</TD>" + "<TD>" + 
(String)hashTable.get(new String("notes")) + "</TD></TR>"); 
out.println("</TABLE>"); 
%> 
</BODY> 
</HTML> 

EJB方面 

1、EJB2.0有哪些内容?分别用在什么场合? EJB2.0和EJB1.1的区别? 
答：规范内容包括Bean提供者，应用程序装配者，EJB容器，EJB配置工具，EJB服务提供者，系统管理员。这里面，EJB容器是EJB之所以能够运行的核心。EJB容器管理着EJB的创建，撤消，激活，去活，与数据库的连接等等重要的核心工作。JSP,Servlet,EJB,JNDI,JDBC,JMS..... 

2、EJB与JAVA BEAN的区别？ 
答:Java Bean 是可复用的组件，对Java Bean并没有严格的规范，理论上讲，任何一个Java类都可以是一个Bean。但通常情况下，由于Java Bean是被容器所创建（如Tomcat)的，所以Java Bean应具有一个无参的构造器，另外，通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地进程内COM组件，它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM，即分布式组件。它是基于Java的远程方法调用（RMI）技术的，所以EJB可以被远程访问（跨进程、跨计算机）。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中，EJB客户从不直接访问真正的EJB组件，而是通过其容器访问。EJB容器是EJB组件的代理，EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 

3、EJB的基本架构 
答:一个EJB包括三个部分: 
Remote Interface 接口的代码 
package Beans; 
import javax.ejb.EJBObject; 
import java.rmi.RemoteException; 
public interface Add extends EJBObject 
{ 
//some method declare 
} 
Home Interface 接口的代码 
package Beans; 
import java.rmi.RemoteException; 
import jaax.ejb.CreateException; 
import javax.ejb.EJBHome; 
public interface AddHome extends EJBHome 
{ 
//some method declare 
} 
EJB类的代码 
package Beans; 
import java.rmi.RemoteException; 
import javax.ejb.SessionBean; 
import javx.ejb.SessionContext; 
public class AddBean Implements SessionBean 
{ 
//some method declare 
} 

J2EE,MVC方面 

1、MVC的各个部分都有那些技术来实现?如何实现? 
答:MVC是Model－View－Controller的简写。"Model" 代表的是应用的业务逻辑（通过JavaBean，EJB组件实现）， "View" 是应用的表示面（由JSP页面产生），"Controller" 是提供应用的处理过程控制（一般是一个Servlet），通过这种设计模型把应用逻辑，处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。 

2、应用服务器与WEB SERVER的区别？ 
希望大家补上，谢谢 


3、J2EE是什么？ 
答:Je22是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese application model).在这样的一个应用系统中，可按照功能划分为不同的组件，这些组件又可在不同计算机上，并且处于相应的层次(tier)中。所属层次包括客户层(clietn tier)组件,web层和组件,Business层和组件,企业信息系统(EIS)层。 

4、WEB SERVICE名词解释。JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。 
答：Web Service描述语言WSDL 
SOAP即简单对象访问协议(Simple Object Access Protocol)，它是用于交换XML编码信息的轻量级协议。 
UDDI 的目的是为电子商务建立标准；UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范，同时也包含一组使企业能将自身提供的Web Service注册，以使别的企业能够发现的访问协议的实现标准。 


5、BS与CS的联系与区别。 
希望大家补上，谢谢 

6、STRUTS的应用(如STRUTS架构) 
答：Struts是采用Java Servlet/JavaServer Pages技术，开发Web应用程序的开放源码的framework。 采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。 Struts有如下的主要功能： 
一.包含一个controller servlet，能将用户的请求发送到相应的Action对象。 
二.JSP自由tag库，并且在controller servlet中提供关联支持，帮助开发员创建交互式表单应用。 
三.提供了一系列实用对象：XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。 

设计模式方面 

1、开发中都用到了那些设计模式?用在什么场合? 
答：每个模式都描述了一个在我们的环境中不断出现的问题，然后描述了该问题的解决方案的核心。通过这种方式，你可以无数次地使用那些已有的解决方案，无需在重复相同的工作。主要用到了MVC的设计模式。用来开发JSP/Servlet或者J2EE的相关应用。简单工厂模式等。 


2、UML方面 
答：标准建模语言UML。用例图,静态图(包括类图、对象图和包图),行为图,交互图(顺序图,合作图),实现图, 

JavaScript方面 

1、如何校验数字型? 
var re=/^d{1,8}$|.d{1,2}$/; 
var str=document.form1.all(i).value; 
var r=str.match(re); 
if (r==null) 
{ 
sign=-4; 
break; 
} 
else{ 
document.form1.all(i).value=parseFloat(str); 
} 


CORBA方面 

1、CORBA是什么?用途是什么? 
答：CORBA 标准是公共对象请求代理结构(Common Object Request Broker Architecture)，由对象管理组织 (Object Management Group，缩写为 OMG)标准化。它的组成是接口定义语言(IDL), 语言绑定(binding:也译为联编)和允许应用程序间互操作的协议。 其目的为： 
用不同的程序设计语言书写 
在不同的进程中运行 
为不同的操作系统开发 


LINUX方面 

1、LINUX下线程，GDI类的解释。 
答：LINUX实现的就是基于核心轻量级进程的"一对一"线程模型，一个线程实体对应一个核心轻量级进程，而线程之间的管理在核外函数库中实现。 
GDI类为图像设备编程接口类库。
<img src ="http://www.blogjava.net/realnicky/aggbug/25586.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2005-12-27 15:56 <a href="http://www.blogjava.net/realnicky/archive/2005/12/27/25586.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>略说Java之util类(转贴)</title><link>http://www.blogjava.net/realnicky/archive/2005/12/27/realnicky.html</link><dc:creator>风吹玉门前----雁北飞</dc:creator><author>风吹玉门前----雁北飞</author><pubDate>Tue, 27 Dec 2005 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/realnicky/archive/2005/12/27/realnicky.html</guid><wfw:comment>http://www.blogjava.net/realnicky/comments/25583.html</wfw:comment><comments>http://www.blogjava.net/realnicky/archive/2005/12/27/realnicky.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/realnicky/comments/commentRss/25583.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/realnicky/services/trackbacks/25583.html</trackback:ping><description><![CDATA[线性表，链表，哈希表是常用的数据结构，在进行Java开发时，JDK已经为我们提供了一系列相应的类来实现基本的数据结构。这些类均在java.util包中。本文试图通过简单的描述，向读者阐述各个类的作用以及如何正确使用这些类。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│　└Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口 
　　Collection是最基本的集合接口，一个Collection代表一组Object，即Collection的元素（Elements）。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类，Java SDK提供的类都是继承自Collection的“子接口”如List和Set。 
　　所有实现Collection接口的类都必须提供两个标准的构造函数：无参数的构造函数用于创建一个空的Collection，有一个Collection参数的构造函数用于创建一个新的Collection，这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。 
　　如何遍历Collection中的每一个元素？不论Collection的实际类型如何，它都支持一个iterator()的方法，该方法返回一个迭代子，使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下： 
　　　　Iterator it = collection.iterator(); // 获得一个迭代子 
　　　　while(it.hasNext()) { 
　　　　　　Object obj = it.next(); // 得到下一个元素 
　　　　} 
　　由Collection接口派生的两个接口是List和Set。 


List接口 
List是有序的Collection，使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引（元素在List中的位置，类似于数组下标）来访问List中的元素，这类似于Java的数组。 
和下面要提到的Set不同，List允许有相同的元素。 
　　除了具有Collection接口必备的iterator()方法外，List还提供一个listIterator()方法，返回一个ListIterator接口，和标准的Iterator接口相比，ListIterator多了一些add()之类的方法，允许添加，删除，设定元素，还能向前或向后遍历。 
　　实现List接口的常用类有LinkedList，ArrayList，Vector和Stack。 


LinkedList类 
　　LinkedList实现了List接口，允许null元素。此外LinkedList提供额外的get，remove，insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈（stack），队列（queue）或双向队列（deque）。 
　　注意LinkedList没有同步方法。如果多个线程同时访问一个List，则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List： 
　　　　List list = Collections.synchronizedList(new LinkedList(...)); 


ArrayList类 
　　ArrayList实现了可变大小的数组。它允许所有元素，包括null。ArrayList没有同步。size，isEmpty，get，set方法运行时间为常数。但是add方法开销为分摊的常数，添加n个元素需要O(n)的时间。其他的方法运行时间为线性。 
　　每个ArrayList实例都有一个容量（Capacity），即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加，但是增长算法并没有定义。当需要插入大量元素时，在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。 
　　和LinkedList一样，ArrayList也是非同步的（unsynchronized）。 

Vector类 
　　Vector非常类似ArrayList，但是Vector是同步的。由Vector创建的Iterator，虽然和ArrayList创建的Iterator是同一接口，但是，因为Vector是同步的，当一个Iterator被创建而且正在被使用，另一个线程改变了Vector的状态（例如，添加或删除了一些元素），这时调用Iterator的方法时将抛出ConcurrentModificationException，因此必须捕获该异常。 

Stack 类 
　　Stack继承自Vector，实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法，还有peek方法得到栈顶的元素，empty方法测试堆栈是否为空，search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。 

Set接口 
　　Set是一种不包含重复的元素的Collection，即任意的两个元素e1和e2都有e1.equals(e2)=false，Set最多有一个null元素。 
　　很明显，Set的构造函数有一个约束条件，传入的Collection参数不能包含重复的元素。 
请注意：必须小心操作可变对象（Mutable Object）。如果一个Set中的可变元素改变了自身状态 导致Object.equals(Object)=true将导致一些问题。 

Map接口 
　　请注意，Map没有继承Collection接口，Map提供key到value的映射。一个Map中不能包含相同的key，每个key只能映射一个value。Map接口提供3种集合的视图，Map的内容可以被当作一组key集合，一组value集合，或者一组key-value映射。 

Hashtable类 
　　Hashtable继承Map接口，实现一个key-value映射的哈希表。任何非空（non-null）的对象都可作为key或者value。 
　　添加数据使用put(key, value)，取出数据使用get(key)，这两个基本操作的时间开销为常数。 
　　Hashtable通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大，这会影响像get和put这样的操作。 
使用Hashtable的简单示例如下，将1，2，3放到Hashtable中，他们的key分别是”one”，”two”，”three”： 
　　　　Hashtable numbers = new Hashtable(); 
　　　　numbers.put(“one”, new Integer(1)); 
　　　　numbers.put(“two”, new Integer(2)); 
　　　　numbers.put(“three”, new Integer(3)); 
　　要取出一个数，比如2，用相应的key： 
　　　　Integer n = (Integer)numbers.get(“two”); 
　　　　System.out.println(“two = ” + n); 
　　由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置，因此任何作为key的对象都必须实现hashCode和equals方法。hashCode和equals方法继承自根类Object，如果你用自定义的类当作key的话，要相当小心，按照散列函数的定义，如果两个对象相同，即obj1.equals(obj2)=true，则它们的hashCode必须相同，但如果两个对象不同，则它们的hashCode不一定不同，如果两个不同对象的hashCode相同，这种现象称为冲突，冲突会导致操作哈希表的时间开销增大，所以尽量定义好的hashCode()方法，能加快哈希表的操作。 
　　如果相同的对象有不同的hashCode，对哈希表的操作会出现意想不到的结果（期待的get方法返回null），要避免这种问题，只需要牢记一条：要同时复写equals方法和hashCode方法，而不要只写其中一个。 
　　Hashtable是同步的。 

HashMap类 
　　HashMap和Hashtable类似，不同之处在于HashMap是非同步的，并且允许null，即null value和null key。，但是将HashMap视为Collection时（values()方法可返回Collection），其迭代子操作时间开销和HashMap的容量成比例。因此，如果迭代操作的性能相当重要的话，不要将HashMap的初始化容量设得过高，或者load factor过低。 

WeakHashMap类 
　　WeakHashMap是一种改进的HashMap，它对key实行“弱引用”，如果一个key不再被外部所引用，那么该key可以被GC回收。 
总结 
　　如果涉及到堆栈，队列等操作，应该考虑用List，对于需要快速插入，删除元素，应该使用LinkedList，如果需要快速随机访问元素，应该使用ArrayList。 
　　如果程序在单线程环境中，或者访问仅仅在一个线程中进行，考虑非同步的类，其效率较高，如果多个线程可能同时操作一个类，应该使用同步的类。 
　　要特别注意对哈希表的操作，作为key的对象要正确复写equals和hashCode方法。 
　　尽量返回接口而非实际的类型，如返回List而非ArrayList，这样如果以后需要将ArrayList换成LinkedList时，客户端代码不用改变。这就是针对抽象编程。

Iterator接口
Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来，从而避免向客户端暴露集合的内部结构。
Iterator模式总是用同一种逻辑来遍历集合： 

　　for(Iterator it = c.iterater(); it.hasNext(); ) { ... } 

　　奥秘在于客户端自身不维护遍历集合的"指针"，所有的内部状态（如当前元素位置，是否有下一个元素）都由Iterator来维护，而这个Iterator由集合类通过工厂方法生成，因此，它知道如何遍历整个集合。 

　　客户端从不直接和集合类打交道，它总是控制Iterator，向它发送"向前"，"向后"，"取当前元素"的命令，就可以间接遍历整个集合。 

　　首先看看java.util.Iterator接口的定义： 

　　public interface Iterator { 
　　boolean hasNext(); 
　　Object next(); 
　　void remove(); 
　　}
依赖前两个方法就能完成遍历，典型的代码如下： 

　　for(Iterator it = c.iterator(); it.hasNext(); ) { 
　　Object o = it.next(); 
　　// 对o的操作... 
　　} 

　　在JDK1.5中，还对上面的代码在语法上作了简化： 

　　// Type是具体的类型，如String。 
　　for(Type t : c) { 
　　// 对t的操作... 
　　} 
　　每一种集合类返回的Iterator具体类型可能不同，Array可能返回ArrayIterator，Set可能返回SetIterator，Tree可能返回TreeIterator，但是它们都实现了Iterator接口，因此，客户端不关心到底是哪种Iterator，它只需要获得这个Iterator接口即可，这就是面向对象的威力。
要确保遍历过程顺利完成，必须保证遍历过程中不更改集合的内容（Iterator的remove()方法除外），因此，确保遍历可靠的原则是只在一个线程中使用这个集合，或者在多线程中对遍历代码进行同步。 

　　最后给个完整的示例： 

　　Collection c = new ArrayList(); 
　　c.add("abc"); 
　　c.add("xyz"); 
　　for(Iterator it = c.iterator(); it.hasNext(); ) { 
　　String s = (String)it.next(); 
　　System.out.println(s); 
　　} 

　　如果你把第一行代码的ArrayList换成LinkedList或Vector，剩下的代码不用改动一行就能编译，而且功能不变，这就是针对抽象编程的原则：对具体类的依赖性最小。

<img src ="http://www.blogjava.net/realnicky/aggbug/25583.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/realnicky/" target="_blank">风吹玉门前----雁北飞</a> 2005-12-27 15:44 <a href="http://www.blogjava.net/realnicky/archive/2005/12/27/realnicky.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>