风雨无阻

2008年3月11日

Jvm工作原理学习笔记

class loader 加载 class file 到内存
jvm内存包括: method area(存放class name, class path , 类修饰符等信息), java stack(每一个线程单独有个stack),java heap(存放对象的数据,数组数据等,被所有线程共享的), pc寄存器(每一个线程单独有个pc寄存器,用于存放下一步指令),本地方法栈。

java 堆 可 分为三部分:Perm,Tenured,Yong区。可以通过参数来配置空间大小:

-Xms :指定了JVM初始启动以后初始化内存

-Xmx:指定JVM堆得最大内存,在JVM启动以后,会分配-Xmx参数指定大小的内存给JVM,但是不一定全部使用,JVM会根据-Xms参数来调节真正用于JVM的内存

 Perm Generation

-XX:PermSize=16M -XX:MaxPermSize=64M

posted @ 2014-02-10 18:01 秋枫故事 阅读(241) | 评论 (0)编辑 收藏

Ajax Post提交

jQuery.post( url, [data], [callback], [type] ) :使用POST方式来进行异步请求


参数:

url (String) : 发送请求的URL地址.

data (Map) : (可选) 要发送给服务器的数据,以 Key/value 的键值对形式表示。

callback (Function) : (可选) 载入成功时回调函数(只有当Response的返回状态是success才是调用该方法)。

type (String) : (可选)官方的说明是:Type of data to be sent。其实应该为客户端请求的类型(JSON,XML,等等)

这是一个简单的 POST 请求功能以取代复杂 $.ajax 。请求成功时可调用回调函数。如果需要在出错时执行函数,请

使用 $.ajax。示例代码:

 var con = $('#content').val();//待提交的数据

    $.post("checkContent.action",{"mess.content":con},
    function (data){
  
   if(data != "")//有非法敏感字
    {  
     alert(data);
     $('#content').focus();
    }
  },"html");


点击提交:

posted @ 2009-09-03 14:42 秋枫故事 阅读(3110) | 评论 (4)编辑 收藏

xmlns:XML命名空间

以下转载自:
http://hi.baidu.com/tianhesj/blog/item/0dd9718d32be4011b21bbacc.html

Namespaces翻译为命名空间。命名空间有什么作用呢?当我们在一个XML文档中使用他人的或者多个DTD文件,就会出现这样的矛盾:因为XML中标识都是自己创建的,在不同的DTD文件中,标识名可能相同但表示的含义不同,这就可能引起数据混乱。
比如在一个文档<table>wood table</table>中<table>表示桌子,
而在另一个文档<table>namelist</table>中<table>表示表格。如果我需要同时处理这两个文档,就会发生名字冲突。
了解决这个问题,我们引进了namespaces这个概念。namespaces通过给标识名称加一个网址(URL)定位的方法来区别这些名称相同的标识。
Namespaces同样需要在XML文档的开头部分声明,声明的语法如下:
<document xmlns:yourname='URL'>
其中yourname是由你定义的namespaces的名称,URL就是名字空间的网址。
假设上面的"桌子<table>"文档来自http://www.zhuozi.com,我们就可以声明为
<document xmlns:zhuozi='http://www.zhuozi.com'>;
然后在后面的标识中使用定义好的名字空间:
<zhuozi:table>wood table</table>
这样就将这两个<table>区分开来。注意的是:设置URL并不是说这个标识真的要到那个网址去读取,仅仅作为一种区别的标志而已。


命名冲突
因为XML文档中使用的元素不是固定的,那么两个不同的XML文档使用同一个名字来描述不同类型的元素的情况就可能发生。而这种情况又往往会导致命名冲突。请看下面两个例子

这个 XML 文档在table元素中携带了水果的信息:

<table>
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
这个 XML 文档在table元素中携带了桌子的信息(家具,不能吃的哦):

<table>
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>

如果上面两个XML文档片断碰巧在一起使用的话,那么将会出现命名冲突的情况。因为这两个片断都包含了<table>元素,而这两个table元素的定义与所包含的内容又各不相同。


--------------------------------------------------------------------------------

使用前缀解决命名冲突问题
下面的XML文档在table元素中携带了信息:

<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>

下面的XML文档携带了家具table的信息:

<f:table>
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>

现在已经没有元素命名冲突的问题了,因为这两个文档对各自的table元素使用了不同的前缀,table元素在两个文档中分别是(<h:table> 和<f:table>)。

通过使用前缀,我们创建了两个不同的table元素。


--------------------------------------------------------------------------------

使用命名空间
下面的XML文档在table元素中携带了信息:

<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>

下面的XML文档携带了家具table的信息:

<f:table xmlns:f="http://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>

在上面两个例子中除了使用前缀外,两个table元素都使用了xmlns属性,使元素和不同的命名空间关联到一起。


--------------------------------------------------------------------------------

命名空间属性
命名空间属性一般放置在元素的开始标记处,其使用语法如下所示:

xmlns:namespace-prefix="namespace"

在上面的例子中,命名空间定义了一个Internet 地址:

xmlns:f="http://www.w3schools.com/furniture"

W3C 命名规范声明命名空间本身就是一个统一资源标示符,Uniform Resource Identifier (URI)。

当我们在元素的开始标记处使用命名空间时,该元素所有的子元素都将通过一个前缀与同一个命名空间相互关联。

注意:用来标识命名空间的网络地址并不被XML解析器调用,XML解析器不需要从这个网络地址中查找信息,该网络地址的作用仅仅是给命名空间一个唯一的名字,因此这个网络地址也可以是虚拟的,然而又很多公司经常把这个网络地址值象一个真实的Web页面,这个地址包含了关于当前命名空间更详细的信息。
可以访问http://www.w3.org/TR/html4/.


--------------------------------------------------------------------------------

统一资源标识符
通用资源标识符(A Uniform Resource Identifier (URI))是一个标识网络资源的字符串。最普通的URI应该是统一资源定位符Uniform Resource Locator (URL)。URL用于标识网络主机的地址。另一方面,另一个不常用的URI是通用资源名字Universal Resource Name (URN)。在我们的例子中,一般使用的是URLs。

既然前面的例子使用的URL地址来标识命名空间,我们可以确信这个命名空间是唯一的。


--------------------------------------------------------------------------------

默认的命名空间
定义一个默认的XML命名空间使得我们在子元素的开始标记中不需要使用前缀。他的语法如下所示:

<element xmlns="namespace">

下面的XML文档在table元素中包含了水果的信息:

<table xmlns="http://www.w3.org/TR/html4/">
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>

下面的XML文档包含了家具table的信息:

<table xmlns="http://www.w3schools.com/furniture">
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>

--------------------------------------------------------------------------------

使用命名空间
档开始使用XSL的时候,就会发现命名空间使用的是如此频繁。XSL样式单主要用于将XML文档转换成类似于HTML文件的格式。

如果看一下下面的XSL文档,就会发现有很多标记都是HTML标记。那些标记并不是HTML标记,是加了前缀的XSL,这个XSL前缀由命名空间"http://www.w3.org/TR/xsl"所标识:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/xsl">
<xsl:template match="/">
<html>
<body>
<table border="2" bgcolor="yellow">
<tr>
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="CATALOG/CD">
<tr>
<td><xsl:value-of select="TITLE"/></td>
<td><xsl:value-of select="ARTIST"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yc_8301/archive/2008/11/19/3335738.aspx

posted @ 2009-08-04 10:46 秋枫故事 阅读(1317) | 评论 (0)编辑 收藏

关于表单中的重置按钮

表单中有一个type=reset的button,可以将表单中的数据重置为初始表单的数据,但如果表单中有一些“单选”或“多选”框,其默认值是通过javascript脚本控制的;这种情况通过reset按钮不会重置为初始状态,所以不能简单的调用reset自带按钮,解决方法:将重置按钮设为普通按钮,在onclick方法中,选调用form.reset()方法,然后再调用javascript脚本

posted @ 2009-05-08 11:37 秋枫故事 阅读(2505) | 评论 (1)编辑 收藏

myeclipse连接oracle出现ora-12705错误的解决办法

我用的myeclipse 6.0版本,oracle是10g版本,在连接的时候出现了以下问题

 java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-12705: Cannot access NLS data files or invalid environment specified

一开始以为是驱动程序的问题,其实不是,只需在eclipse目录下找到eclipse.ini文件,把

Duser.language=en  改成 Duser.language=zh就行了。

有可能大家出现的问题不一样,按我的方法有可能不好使,我写出来仅供大家参考,因为当时为解决这问题,花了不少时间,希望大家少走弯路

posted @ 2009-04-28 17:40 秋枫故事 阅读(201) | 评论 (0)编辑 收藏

摘一部电影中的内容


    我有一把白色塑胶雨伞。买的时候喜欢它雪白可爱,瘦瘦长长,简直像个鹤立鸡群的美女。可惜这种美丽偏偏不耐看,风吹雨打久了,颜色变黄,还多了雀斑一样的污迹。而且瘦长是没用的,哪里像折伞这么善解人意。于是,我开始制造各种机会。 趁着下雨带它出门,左搁一会儿,右放一下,希望一下子大意忘了拿,让它自动消失,大家无痛分手。我就可以理直气壮买一把新的,多好!
失宠的人通常最敏感。 有一天,它突如其来消失了,完全不用花我任何心思。伞也有它的自尊。问题是,等一等,我还没有准备好。不行,它不可以没经我的同意就玩失踪。我便一心一意要找它回来,花尽心思去想,到底在哪里弄丢的呢?书店,餐厅还是公共汽车地铁呢?
真是峰回路转,没想到在戏院把它找回来,小别重逢,它苦着副脸在等我来新发现。重拾旧欢,大团圆结局。 换一个角度来看,如果我失败了,找不到它,它永远消失了,淡淡的遗憾感觉,会不会更合我心意?
人世间的破镜重圆,大概都是一言难尽。

posted @ 2009-04-23 09:15 秋枫故事 阅读(204) | 评论 (0)编辑 收藏

group by 。。。

 select t2.*,t3.ncount from 
(select groupid, count(id) as ncount  from t_txlEmploy group by groupid) t3, t_txlgroup t2
where  t2.id=t3.groupid(+)
group by t2.id,t3.groupid

构架一张t3表,字段为“集团编号”,“集团用户数”

然后用“集团表”和t3表再关联

posted @ 2009-04-22 16:37 秋枫故事 阅读(228) | 评论 (0)编辑 收藏

Spring获取ApplicationContext的正确方式

前两天联华对单系统频频出现out of memory的问题,经过层层分析,终于弄明白原来瓶颈出现在Spring获取Bean那一步上。以前的做法是在delegate层ApplicationContext context = new ClassPathXmlApplicationContext("Compare.xml"); 这样我把log4j的debug打开后发现,每做1步操作的时候系统都会重新加载这个xml,重新创建Bean的实例,重新获取url-mapping,这无疑是个及其错误的方式。      研究后发现正确的使用方式是:      首先在web.xml里配置ApplicationContext      <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/applicationContext.xml</param-value>
     </context-param>     <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     </listener>     然后在Action中编写如下代码得到Context,(我是覆盖了Struts Action的setServlet方法,也许还有更好的方法)。     public void setServlet(ActionServlet servlet){
         super.setServlet(servlet);
         ServletContext servletContext = servlet.getServletContext();
        WebApplicationContext wac =    WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
         // get yours beans     }     这样在启动服务时已经加载了xml中的配置,而不用每次都重新加载,大大提高了系统的效率

posted @ 2009-04-17 16:45 秋枫故事 阅读(1012) | 评论 (0)编辑 收藏

suse硬盘安装(网络收集)

事先,把你的硬盘划出 10G左右的空闲空间!

1.下载suse安装光盘,准备好8G左右的空间,最好是ntfs格式的。现在有 10.1正式版和10.2的beta 2版,2006年12月7号,10.2就除正式版了!然后将五张光盘全部解压,加压到根目录的一个文件夹下,比如X:\suse\

2.找到解压出的第一张光盘linux和initrd文件,放在根目录下.

32位的路径应该是 x:\suse\SUSE-Linux-10.1-Remastered-x86_64-CD1\boot\i386\loader\

64位的路径是:X:\suse\SUSE-Linux-10.1-Remastered-x86_64-CD1\boot\x96_64\loader\

3.下载Grub for dos。下载网址:http://download.it168.com/14/1411/33307/33307_4.shtml

http://grub4dos.sourceforge.net

4.将下载的grub for dos 解压到C盘可能会提示覆盖什么profile.sys文件,直接替换就行。

5.改boot.ini文件,先把boot.ini文件的隐藏属性给去掉!

把boot.ini文件用记事本打开在最下添加这么一行

C:\GRLDR="GRUB"

然后保存,

6.下一步就是重启系统了,当要选择要启动的系统时,选择grub,找到类似 commanderline ,按下enter,进入dos 提示符状态下,

输入 find /linux 回车,此时会显示

hd(0,6)——(肯定会有不同,请看下面注释

kernel hd(0,6)/linux回车

initrd hd(0,6)/initrd回车

boot回车

注释:hd(0,6)   6是你的分区,根据你的分区不同,这个数字会不同,0表示是第一块硬盘。)

进入图形界面,

会提示类似 no cd in your cd drive的语句,不用管他,选择back

7.按照提示选择,都是简单的英语,完全可以搞定的(抄袭linuxsir.org几位大侠的话。。呵呵)

8.等到要你指定安装文件的位置的时候,你把你刚才解压的suse的几张光盘的位置填进去就行了,然后回车,会提示选择安装语言,键盘鼠标什么的,按照提示选就ok了。大家安装时候注意分区,不要采用它默认的分区方式,那样的你的windows操作系统就会被它给删掉了。

再罗嗦一点,Suse的分区方式没有fedora和ubuntu做的好,后面的两个全部可以手动分区,而suse只有切换到专家模式下才能更改分区,刚开始,搞的我又点郁闷。

等待安装完成。。。。大约40 ~ 1个小时。不要着急!中间还要填root密码和给机器命名,添加user等操作!

9.安装完成后,重启,进入系统,user不用填密码自动登录系统(现在我还不知道怎么才能不让它自动登录)

祝大家好运。。。。

——部分内容来自linuxsir.org,感谢Thruth大侠!

 

posted @ 2008-11-25 13:51 秋枫故事 阅读(433) | 评论 (0)编辑 收藏

关于ORACLE中的DECODE

     摘要: 关于ORACLE中的DECODE- -                               ...  阅读全文

posted @ 2008-11-13 15:59 秋枫故事 阅读(2922) | 评论 (0)编辑 收藏

Spring MVC 入门(转)

如果你手上有一本《Spring in Action》, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦!

    首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 应用程序接收到 http://localhost:8088/hello.do(请求路径为/hello.do) 的请求后, Spring 将这个请求交给一个名为 helloController 的程序进行处理, helloController 再调用 一个名为 hello.jsp 的 jsp 文件生成 HTML 代码发给用户的浏览器显示. 上面的名称(/hello.do, helloController, hello.jsp) 都是变量, 你可以更改.

    在 Spring MVC 中, jsp 文件中尽量不要有 Java 代码, 只有 HTML 代码和"迭代(forEach)"与"判断(if)"两个jstl标签. jsp 文件只作为渲染(或称为视图 View)模板使用.

    好了, 我们开始吧. 首先我们需要一个放在 WEB-INF 目录下的 web.xml 文件:

web.xml:
 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 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">
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   /WEB-INF/database.xml
   /WEB-INF/applicationContext.xml
  </param-value>
 </context-param>
 
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 
 <filter>
  <filter-name>EncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>
 
 <filter-mapping>
  <filter-name>EncodingFilter</filter-name>
  <url-pattern>*.do</url-pattern>
 </filter-mapping>
 
 <servlet>
  <servlet-name>test</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>test</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>
 
 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>index.html</welcome-file>
 </welcome-file-list>
 
 <jsp-config>
  <taglib>
   <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
   <taglib-location>/WEB-INF/c.tld</taglib-location>
  </taglib>
  <taglib>   
   <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri>
   <taglib-location>/WEB-INF/fmt.tld</taglib-location>
  </taglib>
 </jsp-config>
</web-app>
它配置了以下功能:
  • 配置 DispatcherServlet (servlet 标签), 它是一个 Java Servlet 程序. 我们将它命名为 test. 然后我们再配置 Servlet 映射(test-mapping 标签), 也就是你希望哪些请求被DispatcherServlet处理. 这里, 我们设置后缀名为 do(*.do) 的所有URL请求都被名为 test 的 DispatcherServlet 的程序处理. 选择 .do 只是一个习惯,但是你不要选择 .html! 虽然《Spring in Action》选择了 .html, 但是那是一种非常糟糕的作法, 特别是你整合 ApacheTomcat 的时候.

  • 配置 CharacterEncodingFilter (filter 标签), 否则你会发现中文乱码. 因为我的 jsp 和 html 文件都是 UTF-8 编码的, 所以我在 param-value 标签中设置了 UTF-8. 估计你使用的是 GB2312 或者 GBK, 立即转到 UTF-8 上来吧.

  • 分解配置文件. context-param 标签指明我们的配置文件还有 /WEB-INF/database.xml 和 /WEB-INF/applicationContext.xml. ContextLoaderListener(listener 标签) 由此得知配置文件是哪些, 它会将它们载入.

因为我们将 DispatcherServlet 命名为test, 所以我们在 WEB-INF 目录下建立一个名为 test-servlet.xml 的文件:

test-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/jsp/"/>
  <property name="suffix" value=".jsp"/>
 </bean>
 
 <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/hello.do">helloController</prop>
   </props>
  </property>
 </bean>
 <bean id="helloController" class="com.ecnulxq.test.HelloController">
 </bean>
</beans>
它配置了以下功能:
  • 配置 InternalResourceViewResolver, 它是 jsp 渲染模板的处理器. 如果你告诉 InternalResourceViewResolver 处理一个名为 hello 的模板时, 它会渲染 /WEB-INF/jsp/hello.jsp 文件. 把 jsp 文件放到 /WEB-INF/jsp/ 目录下是被鼓励的, 这样可以防止用户不经过 Controller 直接访问 jsp 文件从而出错(有些顽皮的人很喜欢这样做).

  • 配置 SimpleUrlHandlerMapping, 在上面的配置文件中, /hello.do 的请求将被 helloController 处理. "/hello.do"和"helloController" 是变量, 你可以更改. 但是你注意到了吗, hello.do 以 .do 作为后缀名. 如果这里(本文的条件下)你不使用.do 作为后缀名, 就没有程序来处理这个请求了. 因为 DispatcherServlet 将收到的请求转交给 SimpleUrlHandlerMapping, DispatcherServlet 收不到的请求, SimpleUrlHandlerMapping 当然也收不到了. 你可以在 props 标签内配置多个 prop 标签.

  • 我们将在后面编写com.ecnulxq.test.HelloController类.

上面, 我们在 web.xml 文件中告诉 ContextLoaderListener, 我们还有另外两个配置文件 /WEB-INF/database.xml 和 /WEB-INF/applicationContext.xml.

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
 <bean id="propertyConfigure" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
   <list>
    <value>/WEB-INF/jdbc.properties</value>
   </list>
  </property>
 </bean>

</beans>

它配置了以下功能:

  • 读取 /WEB-INF/jdbc.properties 文件. 你可以在 list 标签中配置多个 value 标签.

database.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
 
<beans>
<!-- Remove this if your database setting is fine.
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
  </bean>
-->
  <!-- Transaction manager for a single JDBC DataSource
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>
   -->
  <!--
  <bean id="attributeManager" class="com.ideawu.core.AttributeManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>
  -->
</beans>

它配置了以下功能(不过,已经注释掉了):

  • 配置数据库连接. 类似${jbbc.url}是一种访问变量的方法. 我们可以从 /WEB-INF/jdbc.properties 中找到这个变量的值. 如果你的数据库已经配置好, 就将第一个注释去掉.

jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
现在, 我们来编写 Java 代码吧.
 
package com.ecnulxq.test;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;



/**
 * @author lxq ecnulxq@163.com
 * @version 创建时间:Oct 12, 2007 类说明
 *
 */
public class HelloController implements Controller {



 public ModelAndView handleRequest(HttpServletRequest request,
   HttpServletResponse response) throws Exception {
  request.setAttribute("hello_1", "你好!Spring!");
  request.setAttribute("hello_2", "Hello!Spring!");
  return new ModelAndView("hello");
 }



}


return new ModelAndView("hello"); 告诉 InternalResourceViewResolver jsp 模板的名字叫作 hello. request.setAttribute() 设置的对象我们可以在 jsp 文件中使用.

hello.jsp:

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Hello World!</title>
 </head>
 <body>



  <h2>
   ${hello_1}
  </h2>



  <h2>
   ${hello_2}
  </h2>



 </body>
</html>

posted @ 2008-06-05 12:46 秋枫故事 阅读(901) | 评论 (1)编辑 收藏

JSTL详解(一转)

7 Functions 标签库

        称呼 Functions 标签库为标签库,倒不如称呼其为函数库来得更容易理解些。因为 Functions 标签库并没有提供传统的标签来为 JSP 页面的工作服务,而是被用于 EL 表达式语句中。在 JSP2.0 规范下出现的 Functions 标签库为 EL 表达式语句提供了许多更为有用的功能。 Functions 标签库分为两大类,共 16 个函数。

长度函数: fn:length

字符串处理函数: fn:contains 、 fn:containsIgnoreCase 、 fn:endsWith 、 fn:escapeXml 、 fn:indexOf 、 fn:join 、 fn:replace 、 fn:split 、 fn:startsWith 、 fn:substring 、 fn:substringAfter 、 fn:substringBefore 、 fn:toLowerCase 、 fn:toUpperCase 、 fn:trim

以下是各个函数的用途和属性以及简单示例。

9.7.1  长度函数 fn:length 函数

     长度函数 fn:length 的出现有重要的意义。在 JSTL1.0 中,有一个功能被忽略了,那就是对集合的长度取值。虽然 java.util.Collection 接口定义了 size 方法,但是该方法不是一个标准的 JavaBean 属性方法(没有 get,set 方法),因此,无法通过 EL 表达式“ ${collection.size} ”来轻松取得。

fn:length 函数正是为了解决这个问题而被设计出来的。它的参数为 input ,将计算通过该属性传入的对象长度。该对象应该为集合类型或 String 类型。其返回结果是一个 int 类型的值。下面看一个示例。

<%ArrayList arrayList1 = new ArrayList();

                            arrayList1.add("aa");

                            arrayList1.add("bb");

                            arrayList1.add("cc");

%>

<%request.getSession().setAttribute("arrayList1", arrayList1);%>

${fn:length(sessionScope.arrayList1)}

假设一个 ArrayList 类型的实例“ arrayList1 ”,并为其添加三个字符串对象,使用 fn:length 函数后就可以取得返回结果为“ 3 ”。

9.7.2  判断函数 fn:contains 函数

fn:contains 函数用来判断源字符串是否包含子字符串。它包括 string 和 substring 两个参数,它们都是 String 类型,分布表示源字符串和子字符串。其返回结果为一个 boolean 类型的值。下面看一个示例。

${fn:contains("ABC", "a")}<br>

${fn:contains("ABC", "A")}<br>

前者返回“ false ”,后者返回“ true ”。

9.7.3 fn:containsIgnoreCase 函数

fn:containsIgnoreCase 函数与 fn:contains 函数的功能差不多,唯一的区别是 fn:containsIgnoreCase 函数对于子字符串的包含比较将忽略大小写。它与 fn:contains 函数相同,包括 string 和 substring 两个参数,并返回一个 boolean 类型的值。下面看一个示例。

${fn:containsIgnoreCase("ABC", "a")}<br>

${fn:containsIgnoreCase("ABC", "A")}<br>

前者和后者都会返回“ true ”。

9.7.4  词头判断函数 fn:startsWith 函数

fn:startsWith 函数用来判断源字符串是否符合一连串的特定词头。它除了包含一个 string 参数外,还包含一个 subffx 参数,表示词头字符串,同样是 String 类型。该函数返回一个 boolean 类型的值。下面看一个示例。

${fn:startsWith ("ABC", "ab")}<br>

${fn:startsWith ("ABC", "AB")}<br>

前者返回“ false ”,后者返回“ true ”。

9.7.5  词尾判断函数 fn:endsWith 函数

fn:endsWith 函数用来判断源字符串是否符合一连串的特定词尾。它与 fn:startsWith 函数相同,包括 string 和 subffx 两个参数,并返回一个 boolean 类型的值。下面看一个示例。

${fn:endsWith("ABC", "bc")}<br>

${fn:endsWith("ABC", "BC")}<br>

前者返回“ false ”,后者返回“ true ”。

9.7.6  字符实体转换函数 fn:escapeXml 函数

fn:escapeXml 函数用于将所有特殊字符转化为字符实体码。它只包含一个 string 参数,返回一个 String 类型的值。

9.7.8  字符匹配函数 fn:indexOf 函数

fn:indexOf 函数用于取得子字符串与源字符串匹配的开始位置,若子字符串与源字符串中的内容没有匹配成功将返回“ -1 ”。它包括 string 和 substring 两个参数,返回结果为 int 类型。下面看一个示例。

${fn:indexOf("ABCD","aBC")}<br>

${fn:indexOf("ABCD","BC")}<br>

前者由于没有匹配成功,所以返回 -1 ,后者匹配成功将返回位置的下标,为 1 。

posted @ 2008-06-05 09:49 秋枫故事 阅读(222) | 评论 (0)编辑 收藏

hibernate二级缓存的实现

     摘要: 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键.简单来讲Hibernate就是对JDBC进行封装,以实现内部状态的管理,OR关系的映射等,但随之带来的就是数据访问效率的降低,和性能的下降,而缓存就是弥补这一缺点的重要方法.     缓存就是数据库数据在内存中的临时容器,包括数据库数据在内存中的临时拷贝,它位于数据库与数...  阅读全文

posted @ 2008-04-16 18:17 秋枫故事 阅读(1759) | 评论 (1)编辑 收藏

深入浅出SQL教程之Group By和Having

在介绍GROUP BY 和 HAVING 子句前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数,例如SUM, COUNT, MAX, AVG等。这些函数和其它函数的根本区别就是它们一般作用在多条记录上。 

SELECT SUM(population) FROM bbc 

这里的SUM作用在所有返回记录的population字段上,结果就是该查询只返回一个结果,即所有国家的总人口数。 

通过使用GROUP BY 子句,可以让SUM 和 COUNT 这些函数对属于一组的数据起作用。当你指定 GROUP BY region 时, 属于同一个region(地区)的一组数据将只能返回一行值,也就是说,表中所有除region(地区)的字段,只能通过 SUM, COUNT等聚合函数运算后返回一个值。  HAVING子句可以让我们筛选成组后的各组数据,WHERE子句在聚合前先筛选记录.也就是说作用在GROUP BY 子句和HAVING子句前,而 HAVING子句在聚合后对组记录进行筛选。 

让我们还是通过具体的实例来理解GROUP BY 和 HAVING 子句,还采用第三节介绍的bbc表。 

SQL实例: 

一、显示每个地区的总人口数和总面积: 

SELECT region, SUM(population), SUM(area)

FROM bbc

GROUP BY region

 

先以region把返回记录分成多个组,这就是GROUP BY的字面含义。分完组后,然后用聚合函数对每组中的不同字段(一或多条记录)作运算。 

二、 显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区。 

SELECT region, SUM(population), SUM(area)

FROM bbc

GROUP BY region

HAVING SUM(area)>1000000

 

在这里,我们不能用where来筛选超过1000000的地区,因为表中不存在这样一条记录。 

相反,HAVING子句可以让我们筛选成组后的各组数据。


group by分组统计SQL语句(实例)

用一条查询语句,查出各姓名的数值余额.

用户表:
姓名
a
b
c
....

扣费表:
姓名 数值
a 3.5
b 5.2
a 2
...

充值表:
姓名 数值
b 10
a 10
a 10.5
...

返回:
姓名 差额(充值和-扣费和)

测试通过

select table1.TNAME,table1.TelName, (table3.充值-table2.扣费) as 差额
from 用户表 table1,(select TelName,sum(TelQryh)as 扣费 from 扣费表 group by TelName)table2,
(select TelName,sum(TelQryc)as 充值 from 充值表 group by TelName)table3 where
table1.TelName=table2.TelName and table1.TelName=table3.TelName

posted @ 2008-04-12 19:32 秋枫故事 阅读(143) | 评论 (0)编辑 收藏

(转)Struts Spring Hibernate 整合报空指针解决方法

最近一直在弄WebWork,Struts都快忘了。今天又自己小试了一下SSH,结果每次都是报空指针异常,经过一番研究,发现,如果不把action的type改成

org.springframework.web.struts.DelegatingActionProxy

的话,就会报这个

java.lang.NullPointerException

 com.test.struts.action.UserAction.show(UserAction.java:46)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:274)
org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:194)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
解决办法:
1.在struts-config.xml的action把type改成org.springframework.web.struts.DelegatingActionProxy,例如:
<action attribute="userForm" input="/index.jsp" name="userForm"
          parameter="param" path="/user" scope="request"
          type="org.springframework.web.struts.DelegatingActionProxy"
          validate="false">
          <forward name="success" path="/success.jsp" />
</action>
2.在spring的配置文件(applicationContext.xml)里添加一些代码:
<bean id="transactionManager"
         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
         <property name="sessionFactory">
          <ref bean="sessionFactory" />
         </property>
</bean>
给DAO加上代理
<bean id="UserDAOIProxy"
         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
         <property name="transactionManager">
          <ref bean="transactionManager" />
         </property>
         <property name="target">
          <ref bean="UserDao" />
         </property>
         <property name="transactionAttributes">
          <props>
           <prop key="create*">PROPAGATION_REQUIRED</prop>
           <prop key="update*">PROPAGATION_REQUIRED</prop>
           <prop key="delete*">PROPAGATION_REQUIRED</prop>
           <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
          </props>
         </property>
</bean>
3.更改Service的引用
 <bean name="UserService"
         class="com.test.service.impl.UserServiceImpl">
         <property name="userDao">
          <ref bean="
UserDAOIProxy" />
         </property>
</bean>
这样就不会报那个异常了,测试通过^_^
我的配置文件代码:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource"
         class="org.apache.commons.dbcp.BasicDataSource">
         <property name="driverClassName"
          value="oracle.jdbc.driver.OracleDriver">
         </property>
         <property name="url"
          value="jdbc:oracle:thin:@192.192.192.19:1521:orcl">
         </property>
         <property name="username" value="sunyu"></property>
         <property name="password" value="19830317"></property>
</bean>
<bean id="sessionFactory"
         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
         <property name="dataSource">
          <ref bean="dataSource" />
         </property>
         <property name="hibernateProperties">
          <props>
           <prop key="hibernate.dialect">
            org.hibernate.dialect.Oracle9Dialect
           </prop>
           <prop key="hibernate.show_sql">true</prop>
          </props>
         </property>
         <property name="mappingResources">
          <list>
           <value>com/test/model/TestUser.hbm.xml</value>
          </list>
         </property>
</bean>
<bean id="transactionManager"
         class="org.springframework.orm.hibernate3.HibernateTransactionManager">
         <property name="sessionFactory">
          <ref bean="sessionFactory" />
         </property>
</bean>
<bean name="UserDao" class="com.test.dao.impl.UserDaoImpl">
         <property name="sessionFactory">
          <ref bean="sessionFactory" />
         </property>
</bean>
<bean id="UserDAOIProxy"
         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
         <property name="transactionManager">
          <ref bean="transactionManager" />
         </property>
         <property name="target">
          <ref bean="UserDao" />
         </property>
         <property name="transactionAttributes">
          <props>
           <prop key="create*">PROPAGATION_REQUIRED</prop>
           <prop key="update*">PROPAGATION_REQUIRED</prop>
           <prop key="delete*">PROPAGATION_REQUIRED</prop>
           <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
          </props>
         </property>
</bean>
<bean name="UserService"
         class="com.test.service.impl.UserServiceImpl">
         <property name="userDao">
          <ref bean="UserDAOIProxy" />
         </property>
</bean>
<bean name="/user" class="com.test.struts.action.UserAction">
         <property name="userService">
          <ref bean="UserService" />
         </property>
</bean>
</beans>
struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "
http://struts.apache.org/dtds/struts-config_1_2.dtd
">
<struts-config>
<data-sources />
<form-beans>
         <form-bean name="userForm" type="com.test.struts.form.UserForm" />
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings>
         <action attribute="userForm" input="/index.jsp" name="userForm"
          parameter="param" path="/user" scope="request"
          type="org.springframework.web.struts.DelegatingActionProxy"
          validate="false">
          <forward name="success" path="/success.jsp" />
         </action>
</action-mappings>
<message-resources parameter="com.test.struts.ApplicationResources" />
<plug-in
         className="org.springframework.web.struts.ContextLoaderPlugIn">
         <set-property property="contextConfigLocation"
          value="/WEB-INF/applicationContext.xml" />
</plug-in>

</struts-config>



------------------------------------------
第二种方法,如果在struts-config.xml里面加上

<controller>
<set-property property="processorClass"
value="org.springframework.web.struts.DelegatingRequestProcessor" />
</controller>

这样action就不需要type属性了
----------------------------------------------

posted @ 2008-04-03 19:14 秋枫故事 阅读(2442) | 评论 (0)编辑 收藏

(转)jboss部署ejb

开发sessionbean EJB最少也需要三个class,remote interface,home interface,and bean implementation(bean行为).

1. remote interface 用来揭示EJB对外的一些方法.

package helloWorld; import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface RemoteHello extends EJBObject
{ public String HelloEcho(String inputString) throws RemoteException; }
2.home interface 是用来规定怎样创建一个实现remote interface的bean.
package helloWorld;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface HomeHello extends EJBHome

{ RemoteHello create() throws RemoteException, CreateException; }

3.bean implementation 是提供方法的实现,这些方法在上述两种interface中都有规定了.

package helloWorld;

import java.rmi.RemoteException;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

public class HelloBean implements SessionBean{

   public String HelloEcho(String inputString) {

     System.out.println("Someone called 'Hello Echo Successed!'");

     return "*********" + inputString + "*********"; }

     /** Empty method body  */

     public void ejbCreate() {

        System.out.println("Ejb 4 is creating!...");}

     /** Every ejbCreate() method ALWAYS needs a corresponding   ejbPostCreate () method with exactly the same parameter types.   */

public void ejbPostCreate() {}

/** Empty method body   */

public void ejbRemove() {

    System.out.println("Ejb 4 is removing!...");}

 /** Empty method body */

public void ejbActivate() {

   System.out.println("Ejb 4 is activating!...");}

/** Empty method body */

public void ejbPassivate()

 {}

/** Empty method body   */

public void setSessionContext(SessionContext sc)

 {}

}

部署jar

这些classes必须打包进一个JAR文件中,JAR文件中包含了目录结构和包的层次.在本例中, 这些classes是在包helloworld,这样他们需要在目录helloWorld/ 下.

部署发布描述器ejb-jar.XML和jboss.xml
在JAR文档创建之前,还需要一个叫META-INF的目录,这是存放部署发布描述器的(一般叫ejb-jar.xml).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD EntERPrise JavaBeans 2.0//EN" "
http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
 <description>Neosue Helloworld Sample Application</description>
 <display-name>Helloworld EJB</display-name>
 <enterprise-beans>
  <session>
   <ejb-name>Helloworld</ejb-name>
   <!-- home interface -->
   <home>helloWorld.HomeHello</home>
   <!-- remote interface -->
   <remote>helloWorld.RemoteHello</remote>
   <!-- bean implementation -->
   <ejb-class>helloWorld.HelloBean</ejb-class>
   <session-type>Stateless</session-type>
   <transaction-type>Bean</transaction-type>
  </session>
 </enterprise-beans>
</ejb-jar>

jboss.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "
http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">
<jboss>
 <enterprise-beans>
  <session>
   <ejb-name>Helloworld</ejb-name>
   <jndi-name>Helloworld/Hello</jndi-name>
  </session>
 </enterprise-beans>
</jboss>
虽然有了上面你的应用程序和JNDI name的梆定,但是一旦部署发布到JBoss服务器上,你还需要一个jndi.properties文件,以告诉调用你程序的客户端请求到哪里去初始化JNDI naming service.

测试程序:

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.rmi.PortableRemoteObject;

import helloWorld.*;

public class MyTest {

   public static void main(String[] args) {

      try{ Context ctx=new InitialContext();

           Object ref=ctx.lookup("Helloworld/Hello");

           HomeHello home=(HomeHello)PortableRemoteObject.narrow(ref,HomeHello.class);

           RemoteHello user=home.create(); System.out.println(user.HelloEcho("So easy!"));

        }catch(Exception e) {

          e.printStackTrace();

        }

   }

}

Jboss EJB 部署步骤 建立 remote interface-->home interface-->and bean implementation--> ejb-jar.xml-->jboss.xml--打包(package[jar cvf packageName.jar .])-->复制到jboss deploy目录.

---------------------------------------------------------
原文 URL
http://blog.blogchina.com/refer.159508.html
---------------------------------------------------------
补充说明如下:

OS: windows 2000;
JDK: 1.5.0rc;
JBoss: 4.0

HelloWorld.jar
|--META-INF
|      |--jboss.xml
|      |--ejb-jar.xml
|      |--MANIFEST.MF (自动生成)
|--helloWorld
       |--RemoteHello.class
       |--jndi.properties
       |--HomeHello.class
       |--HelloBean.class


其中 测试文件 MyTest.class 同目录拷贝一份 jndi.properties 文件过来.

jndi.properties 的内容如下:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

posted @ 2008-03-30 19:38 秋枫故事 阅读(1049) | 评论 (0)编辑 收藏

( 转)重写自已的HashCode()方法

 大家都知道,在Java里对对象的操作是基于引用的。而当我们需要对一组对象操作的时候,  就需要有接收这一组引用的容器。平时我们最常用的就是数组。在Java里可以定义一个对象数组来完成许多操作。可是,数组长度是固定的,如果我们需要更 加灵活的解决方案该怎么办呢?

       Java提供了container  classes来解决这一问题。container  classes包括两个部分:Collection和Map。

它们的结构是这样的: 

       本文重点介绍HashMap。首先介绍一下什么是Map。在数组中我们是通过数组下标来对其内容索引的,  而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。  在下文中会有例子具体说明。

       再来看看HashMap和TreeMap有什么区别。HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着 某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。

下面就要进入本文的主题了。先举个例子说明一下怎样使用HashMap:













程序代码:
import java.util.*; 
public class Exp1 { 
     public static void main(String[] args){ 
          HashMap h1=new HashMap(); 
          Random r1=new Random();     
          for(int i=0;i< 1000;i++){ 
               Integer t=new Integer(r1.nextInt(20)); 
               if(h1.containsKey(t)) 
                    ((Ctime)h1.get(t)).count++; 
               else 
                    h1.put(t, new Ctime()); 
          } 
          System.out.println(h1); 
     } 

class Ctime{ 
     int count=1; 
     public String toString(){ 
          return Integer.toString(count); 
     } 


           在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看 出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的方面差异并不大。

         前面介绍了,HashMap是基于HashCode的,在所有对象的超类Object中有一个HashCode()方法,  但是它和equals方法一样,并不能适用于所有的情况,这样我们就需要重写自己的HashCode()方法。
下面就举这样一个例子:













程序代码:
import java.util.*; 
public class Exp2 { 
     public static void main(String[] args){ 
          HashMap h2=new HashMap(); 
          for(int i=0;i< 10;i++) 
               h2.put(new Element(i), new Figureout()); 
          System.out.println("h2:"); 
          System.out.println("Get the result for Element:"); 
          Element test=new Element(5); 
          if(h2.containsKey(test)) 
               System.out.println((Figureout)h2.get(test)); 
          else 
               System.out.println("Not found"); 
     } 

class Element{ 
     int number; 
     public Element(int n){ 
          number=n; 
     } 

class Figureout{ 
     Random r=new Random(); 
     boolean possible=r.nextDouble()>0.5; 
     public String toString(){ 
          if(possible) 
               return "OK!"
          else 
               return "Impossible!"
     } 

 
       在这个例子中,Element用来索引对象Figureout,也即Element为key,Figureout为value。  在Figureout中随机生成一个浮点数,如果它比0.5大,打印“OK!”,否则打印“Impossible!”。  之后查看Element(5)对应的Figureout结果如何。  

       结果却发现,无论你运行多少次,得到的结果都是“Not  found”。也就是说索引Element(5)并不在HashMap中。这怎么可能呢?

       原因得慢慢来说:Element的HashCode方法继承自Object,而Object中的HashCode方法返回的HashCode对应于当前 的地址,也就是说对于不同的对象,即使它们的内容完全相同,用HashCode()返回的值也会不同。这样实际上违背了我们的意图。因为我们在使用 HashMap时,  希望利用相同内容的对象索引得到相同的目标对象,这就需要HashCode()在此时能够返回相同的值。

       在上面的例子中,我们期望new  Element(i)  (i=5)与  Element  test=new  Element(5)是相同的,  而实际上这是两个不同的对象,尽管它们的内容相同,但它们在内存中的地址不同。因此很自然的,  上面的程序得不到我们设想的结果。下面对Element类更改如下:













程序代码:
class Element{ 
  int number; 
  public Element(int n){ 
    number=n; 
 } 
  public int hashCode(){ 
   return number; 
  } 
  public boolean equals(Object o){ 
   return (o instanceof Element) && (number==((Element)o).number); 
  } 


           在这里Element覆盖了Object中的hashCode()和equals()方法。覆盖hashCode()使其以number的值作为 hashcode返回,这样对于相同内容的对象来说它们的hashcode也就相同了。而覆盖equals()是为了在HashMap判断两个key是否 相等时使结果有意义(有关重写equals()的内容可以参考我的另一篇文章《重新编写Object类中的方法  》)。修改后的程序运行结果如下:

h2:  
Get  the  result  for  Element:  
Impossible!  

请记住:如果你想有效的使用HashMap,你就必须重写在其的HashCode()。

还有两条重写HashCode()的原则:

       不必对每个不同的对象都产生一个唯一的hashcode,只要你的HashCode方法使get()能够得到put()放进去的内容就可以了。即“不为 一原则”。  生成hashcode的算法尽量使hashcode的值分散一些,  不要很多hashcode都集中在一个范围内,这样有利于提高HashMap的性能。即“分散原则”。  至于第二条原则的具体原因,有兴趣者可以参考Bruce  Eckel的《Thinking  in  Java》,
在那里有对HashMap内部实现原理的介绍,这里就不赘述了。

       掌握了这两条原则,你就能够用好HashMap编写自己的程序了。不知道大家注意没有,  java.lang.Object中提供的三个方法:clone(),equals()和hashCode()虽然很典型,  但在很多情况下都不能够适用,它们只是简单的由对象的地址得出结果。  这就需要我们在自己的程序中重写它们,其实java类库中也重写了千千万万个这样的方法。  利用面向对象的多态性——覆盖,Java的设计者很优雅的构建了Java的结构,也更加体现了Java是一门纯OOP语言的特性。

     Java提供的Collection和Map的功能是十分强大的,它们能够使你的程序实现方式更为灵活,  执行效率更高。希望本文能够对大家更好的使用HashMap有所帮助。

posted @ 2008-03-28 11:17 秋枫故事 阅读(249) | 评论 (0)编辑 收藏

产生对象个数问题

String a = "hello";
String b = "world";
String c = "ok";
String d = "is";
String result = a+b+c+d;
问:共产生多少个对象?

答:
现在的编译器早就对这些代码作了优化,编译成如下:
String a = "hello";
String b = "world";
String c = "ok";
String d = "is";
String result = new StringBuffer().append(a),append(b),append(c).append(d).toString();
因此产生了6个对象,其中5个字符串对象,一个StringBuffer临时对象。

posted @ 2008-03-28 10:39 秋枫故事 阅读(305) | 评论 (0)编辑 收藏

java 文件操作(拷贝一个文件)

try
{

  BufferedReader in = new BufferedReader(new FileReader("c:\\1.txt"));
  PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter("c:\\2.txt")),true);
  String tmp = "";
  while((tmp=in.readLine()) != null)
  {
    writer.println(tmp);
  }
  writer.close();
  in.close();
}
catch(Exception e)
{
e.printStackTrace();
}

posted @ 2008-03-25 22:35 秋枫故事 阅读(354) | 评论 (0)编辑 收藏

[转] 解析oracle的ROWNUM

对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。
 举例说明:
例如表:student(学生)表,表结构为:
ID       char(6)      --学号
name    VARCHAR2(10)   --姓名
create table student (ID char(6), name VARCHAR2(100));
insert into sale values('200001',‘张一’);
insert into sale values('200002',‘王二’);
insert into sale values('200003',‘李三’);
insert into sale values('200004',‘赵四’);
commit;

(1) rownum 对于等于某值的查询条件
如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。
SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)
SQL> select rownum,id,name from student where rownum=1;
    ROWNUM ID     NAME
---------- ------ ---------------------------------------------------
         1 200001 张一
SQL> select rownum,id,name from student where rownum =2;
    ROWNUM ID     NAME
---------- ------ ---------------------------------------------------

(2)rownum对于大于某值的查询条件
   如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录
SQL> select rownum,id,name from student where rownum >2;
ROWNUM ID     NAME
---------- ------ ---------------------------------------------------
那如何才能找到第二行以后的记录呀。可以使用以下的子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
SQL>select * from(select rownum no ,id,name from student) where no>2;
        NO ID     NAME
---------- ------ ---------------------------------------------------
         3 200003 李三
         4 200004 赵四
SQL> select * from(select rownum,id,name from student)where rownum>2;
    ROWNUM ID     NAME
---------- ------ ---------------------------------------------------

(3)rownum对于小于某值的查询条件
如果想找到第三条记录以前的记录,当使用rownum<3是能得到两条记录的。显然rownum对于rownum<n((n>1的自然数)的条件认为是成立的,所以可以找到记录。
SQL> select rownum,id,name from student where rownum <3;
    ROWNUM ID     NAME
---------- ------ ---------------------------------------------------
        1 200001 张一
        2 200002 王二
综上几种情况,可能有时候需要查询rownum在某区间的数据,那怎么办呀从上可以看出rownum对小于某值的查询条件是人为true的,rownum对于大于某值的查询条件直接认为是false的,但是可以间接的让它转为认为是true的。那就必须使用子查询。例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。
SQL> select * from (select rownum no,id,name from student where rownum<=3 ) where no >=2;
        NO ID     NAME
---------- ------ ---------------------------------------------------
         2 200002 王二
         3 200003 李三

(4)rownum和排序
Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。
SQL> select rownum ,id,name from student order by name;
    ROWNUM ID     NAME
---------- ------ ---------------------------------------------------
         3 200003 李三
         2 200002 王二
         1 200001 张一
         4 200004 赵四
可以看出,rownum并不是按照name列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rowid也是顺序分配的。为了解决这个问题,必须使用子查询
SQL> select rownum ,id,name from (select * from student order by name);
    ROWNUM ID     NAME
---------- ------ ---------------------------------------------------
         1 200003 李三
         2 200002 王二
         3 200001 张一
         4 200004 赵四
这样就成了按name排序,并且用rownum标出正确序号(有小到大)
笔者在工作中有一上百万条记录的表,在jsp页面中需对该表进行分页显示, 便考虑用rownum来作,下面是具体方法(每页
显示20条):
  “select * from tabname where rownum<20 order by name" 但却发现oracle却不能按自己的意愿来执行,而是先随便
取20条记录,然后再 order by,后经咨询oracle,说rownum确实就这样,想用的话,只能用子查询 来实现先排序,后
rownum,方法如下:
  "select * from (select * from tabname order by name) where  rownum<20",但这样一来,效率会较低很多。
  后经笔者试验,只需在order by 的字段上加主键或索引即可让oracle先按 该字段排序,然后再rownum;方法不变:
   “select * from tabname where rownum<20 order by name"

取得某列中第N大的行

select column_name from
(select table_name.*,dense_rank() over (order by column desc) rank from table_name)
where rank = &N;
 假如要返回前5条记录:

  select * from tablename where rownum<6;(或是rownum <= 5 或是rownum != 6)
假如要返回第5-9条记录:

select * from tablename
where …
and rownum<10
minus
select * from tablename
where …
and rownum<5
order by name
选出结果后用name排序显示结果。(先选再排序)

注意:只能用以上符号(<、<=、!=)。

select * from tablename where rownum != 10;返回的是前9条记录。
不能用:>,>=,=,Between...and。由于rownum是一个总是从1开始的伪列,Oracle 认为这种条件 不成立,查不到记录.

另外,这个方法更快:

select * from (
select rownum r,a from yourtable
where rownum <= 20
order by name )
where r > 10
这样取出第11-20条记录!(先选再排序再选)

要先排序再选则须用select嵌套:内层排序外层选。
rownum是随着结果集生成的,一旦生成,就不会变化了;同时,生成的结果是依次递加的,没有1就永远不会有2!
rownum 是在 查询集合产生的过程中产生的伪列,并且如果where条件中存在 rownum 条件的话,则:

1: 假如 判定条件是常量,则:
只能 rownum = 1, <= 大于1 的自然数, = 大于1 的数是没有结果的, 大于一个数也是没有结果的
即 当出现一个 rownum 不满足条件的时候则 查询结束   this is stop key!

2: 当判定值不是常量的时候
若条件是 = var , 则只有当 var 为1 的时候才满足条件,这个时候不存在 stop key ,必须进行 full scan ,对每个满足其他where条件的数据进行判定
选出一行后才能去选rownum=2的行…… 

posted @ 2008-03-24 19:35 秋枫故事 阅读(172) | 评论 (0)编辑 收藏

Group By SQL

 

我们现在回到函数上。记得我们用 SUM 这个指令来算出所有的 Sales (营业额)吧!如果我们的需求变成是要算出每一间店 (store_name) 的营业额 (sales),那怎么办呢?在这个情况下,我们要做到两件事:第一,我们对于 store_name 及 Sales 这两个栏位都要选出。第二,我们需要确认所有的 sales 都要依照各个 store_name 来分开算。这个语法为:

SELECT "栏位1", SUM("栏位2")
FROM "表格名"
GROUP BY "栏位1"

在我们的示范上,

Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

我们就打入,

SELECT store_name, SUM(Sales)
FROM Store_Information
GROUP BY store_name

结果:

store_name SUM(Sales)
Los Angeles $1800
San Diego $250
Boston $700

当我们选不只一个栏位,且其中至少一个栏位有包含函数的运用时,我们就需要用到 GROUP BY 这个指令。在这个情况下,我们需要确定我们有 GROUP BY 所有其他的栏位。换句话说,除了有包括函数的栏位外,我 们都需要将其放在 GROUP BY 的子句中。

posted @ 2008-03-23 10:00 秋枫故事 阅读(196) | 评论 (0)编辑 收藏

java排序

冒泡排序:
/*
  * 冒泡排序:
  */
 public static void sort(int[] data) {
  for (int i = 0; i < data.length; i++) {
   for (int j = data.length - 1; j > i; j--) {
    if (data[j] < data[j - 1]) {
     
     int tmp = data[j];
     data[j] = data[j-1];
     data[j-1] = tmp;
    }
   }
  }
 }

posted @ 2008-03-22 00:22 秋枫故事 阅读(138) | 评论 (0)编辑 收藏

为什么要使用“外连接”

之前我们看到的左连接 (left join),又称内部连接 (inner join)。在这个情况下,要两个表格内都有同样的值,那一笔资料才会被选出。那如果我们想要列出一个表格中每一笔的资料,无论它的值在另一个表格中有没有出现,那该怎么办呢?在这个时候,我们就需要用到 SQL OUTER JOIN (外部连接) 的指令。

外部连接的语法是依数据库的不同而有所不同的。举例来说,在 Oracle 上,我们会在 WHERE 子句中要选出所有资料的那个表格之后加上一个 "(+)" 来代表说这个表格中的所有资料我们都要。

假设我们有以下的两个表格:

Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

Geography 表格
region_name store_name
East Boston
East New York
West Los Angeles
West San Diego

我们需要知道每一间店的营业额。如果我们用一个普通的连接,我们将会漏失掉 'New York'这个店,因为它并不存在于 Store_Information 这个表格。所以,在这个情况下,我们需要用外部连接来串联这两个表格:

SELECT A1.store_name, SUM(A2.Sales) SALES
FROM Georgraphy A1, Store_Information A2
WHERE A1.store_name = A2.store_name (+)
GROUP BY A1.store_name

我们在这里是使用了 Oracle 的外部连接语法。

如果换成了Mysql:
select a1.store_name,sum(a2.sales) from geography a1 left join store_information a2
on a1.store_name=a2.store_name group by a1.store_name;


结果:

store_name SALES
Boston $700
New York
Los Angeles $1800
San Diego $250

请注意: 当第二个表格没有相对的资料时,SQL 会传回 NULL 值。在这一个例子中, 'New York' 并不存在于 Store_Information 表格,所以它的 "SALES" 栏位是 NULL。

posted @ 2008-03-20 20:07 秋枫故事 阅读(614) | 评论 (0)编辑 收藏

内连接和外连接区别

在之前,我对MSSQL中的内连接和外连接所得出的数据集不是很清楚。这几天重新温习了一下SQL的书本,现在的思路应该是很清楚了,现在把自己的理解发出来给大家温习下。希望和我一样对SQL的连接语句不太理解的朋友能够有所帮助。(发这么菜的教程,各位大大们别笑话偶了,呵:D )

有两个表A和表B。
表A结构如下:
Aid:int;标识种子,主键,自增ID
Aname:varchar

数据情况,即用select * from A出来的记录情况如下图1所示:


图1:A表数据

表B结构如下:
Bid:int;标识种子,主键,自增ID
Bnameid:int

数据情况,即用select * from B出来的记录情况如下图2所示:



图2:B表数据

为了把Bid和Aid加以区分,不让大家有误解,所以把Bid的起始种子设置为100。
有SQL基本知识的人都知道,两个表要做连接,就必须有个连接字段,从上表中的数据可以看出,在A表中的Aid和B表中的Bnameid就是两个连接字段。
下图3说明了连接的所有记录集之间的关系:



图3:连接关系图

现在我们对内连接和外连接一一讲解。
1.内连接:利用内连接可获取两表的公共部分的记录,即图3的记录集C
语句如下:Select * from A JOIN B ON A.Aid=B.Bnameid
运行结果如下图4所示:



图4:内连接数据

其实select * from A,B where A.Aid=B.Bnameid与Select * from A JOIN B ON A.Aid=B.Bnameid的运行结果是一样的。
2.外连接:外连接分为两种,一种是左连接(Left JOIN)和右连接(Right JOIN)
  (1)左连接(Left JOIN):即图3公共部分记录集C+表A记录集A1。     
     语句如下:select * from A Left JOIN B ON A.Aid=B.Bnameid
     运行结果如下图5所示:



图5:左连接数据

     说明:
           在语句中,A在B的左边,并且是Left Join,所以其运算方式为:A左连接B的记录=图3公共部分记录集C+表A记录集A1
           在图3中即记录集C中的存在的Aid为:2 3 6 7 8           
           图1中即表A所有记录集A中存在的Aid为:1 2 3 4 5 6 7 8 9
           表A记录集A1中存在的Aid=(图1中即A表中所有Aid)-(图3中即记录集C中存在的Aid),最终得出为:1 4 5 9
           由此得出图5中A左连接B的记录=图3公共部分记录集C+表A记录集A1,
           最终得出的结果图5中可以看出Bnameid及Bid非NULL的记录都为图3公共部分记录集C中的记录;Bnameid及Bid为NULL的Aid为1 4 5 9的四笔记录就是表A记录集A1中存在的Aid。

  (2)右连接(Right JOIN):即图3公共部分记录集C+表B记录集B1。
     语句如下:select * from A Right JOIN B ON A.Aid=B.Bnameid
     运行结果如下图6所示:



图6:右连接数据

     说明:
           在语句中,A在B的左边,并且是Right Join,所以其运算方式为:A右连接B的记录=图3公共部分记录集C+表B记录集B1
           在图3中即记录集C中的存在的Aid为:2 3 6 7 8           
           图2中即表B所有记录集B中存在的Bnameid为:2 3 6 7 8 11
           表B记录集B1中存在的Bnameid=(图2中即B表中所有Bnameid)-(图3中即记录集C中存在的Aid),最终得出为:11
           由此得出图6中A右连接B的记录=图3公共部分记录集C+表B记录集B1,
           最终得出的结果图6中可以看出Aid及Aname非NULL的记录都为图3公共部分记录集C中的记录;Aid及Aname为NULL的Aid为11的记录就是表B记录集B1中存在的Bnameid。
     
总结:

通过上面的运算解说,相信很多人已经想到,上面的情况(包括图3的关系图)说明的都只是A在B的左边的情况,
以下语句B在A的右边的又会出现什么情况呢??
select * from B Left JOIN A ON A.Aid=B.Bnameid
select * from B Right JOIN A ON A.Aid=B.Bnameid

其实对图3左右翻转一下就可以得出以下结论:
select * from B Left JOIN A ON A.Aid=B.Bnameid和select * from A Right JOIN B ON A.Aid=B.Bnameid所得出的记录集是一样的

select * from B Right JOIN A ON A.Aid=B.Bnameid和select * from A Left JOIN B ON A.Aid=B.Bnameid所得出的记录集也是一样的。

posted @ 2008-03-20 17:06 秋枫故事 阅读(3665) | 评论 (3)编辑 收藏

用jdom解析xml文件时如何解决中文问题

import java.io.*;

public class DOMTest {

 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("王");
   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());
  }
 }
}

posted @ 2008-03-19 16:59 秋枫故事 阅读(854) | 评论 (0)编辑 收藏

JAVA内部类

public class Aqiang {

// 静态内部类
 static class Test
 {
  private int i ;
  public Test()
  {
   i = 2;
  }
 }
 class TestB
 {
  private int i = 3;
 }

 private int j;

 public static void main(String args[]) {
  
  // 静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象
  Aqiang.Test test = new Aqiang.Test();
  System.out.println("test" + test.i);
  
  // 而非静态内部类,需要选创建一个外部类对象,然后才能创建内部内对象
  Aqiang aqiang = new Aqiang();
  Aqiang.TestB tb = aqiang.new TestB();
  System.out.println("testb" + tb.i);

 }
}

posted @ 2008-03-18 23:28 秋枫故事 阅读(129) | 评论 (0)编辑 收藏

Java IO中字节流和字符流的区别

 
1
流是一个有序的字节序列,可作为一个输入源,也可作为一个输出的目的地。
字节流以字节为单位输入输出,字节流类名含有stream,字符流以字符为单位输入输出,字节流
类名含有reader或writer.为了通用性,java中字符是16位的unicode字符,所以8位的字节流必
须和16位的字符流进行转换。字节流到字符流的转换使用InputStreamReader类:
public InputStreamReader(InputStream in);
public InputStreamReader(InputStream in,String encoding);
public OuputStreamWriter(OnputStream in);
public OnputStreamWriter(OnputStream in,String encoding);
Reader和Writer类允许用户在程序中无缝的支持国际字符集,如果要读区的文件是别国语言,
要使用字符流。
JavaI/O字节流与字符流就是java 实现输入/输出 数据 字节流是一个字节一个字节的输入/输出 数据 (两个字节组成一个汉字)所以在用字节流读一串汉字时会出现乱码问题,
同样字符流是一个字符一个字符流(一个字符=两个字节)的输入/输出 数据 用字符流读一串汉字可以解决乱码问题.

posted @ 2008-03-18 18:24 秋枫故事 阅读(5358) | 评论 (3)编辑 收藏

实例:设备,设备类型,设备端口

有以下三个对象:
US设备对象:USDevie
US设备类型对象:USDeviceModle
US设备端口对象:USDevicePort
class USDevice
{
....
// US设备类型
USDeviceModel model;

// US设备端口对象集合
Set<USDevicePort> devicePortSet = new HashSet();

}

/**
US设备类型说明每种设备都有不同的端口数目
*/
class USDeviceModel
{
....

// 设备端口数目
int deviceport;
}

class USDevicePort
{
private int deviceId;
private int devicePort;
}

               1              :                    1                    :                    n
一种US设备(device)----->设备类型(model)------>不同数目的设备端口
US设备:设备类型:设备端口数目 = 1:1:n
所以,如果新增设备的时候,要根据设备类型,得到相应的设备端口数目,
然后在USDevicePort对应的数据库表中插入记录.
编辑设备的时候,如果编辑了US设备类型,则相应的设备端口就会改变,这种
情况除了更新USDevice对应的数据表中设备类型外,因为在USDevicePort表中
存放在以前设备类型的端口记录,所以应该先删除之前的端口记录,然后再插入
现在类型所对应的端口记录.
其实只需:

//这一步根据具体设备id,从数据库中取出相应的设备对象
USDevice device = .....

// 得到US设备端口对象集合
Set devicePortSet = device.getDevicePortSet();

// 先清空以前所有的端口记录
devicePortSet.clear();

// 根据编辑后类型ID,得到设备类型对象,并可以得到此种类型上的端口数目
USDeviceModel usModle = ....


// 根据上面得到的端口数据,构造"设备端口数目"对象,并把所有的设备端口对象添加到集合中

//最后更新US设备


这样,每当编辑一个US设备的类型后,在设备端口表中,这种设备编辑之前的类型所对应的端口记录
就会被删除,而保持只有新的设备类型端口记录.

注意在配置USDevice.hbm.xml文件时,要将<set name="devicePortSet " casecade="all-orphan-delete" .../>
因为它会将和USDevice没有关联的对象从数据中删除,这也与程序中devicePortSet.clear()相对应.

 

 

 


 

posted @ 2008-03-14 23:53 秋枫故事 阅读(371) | 评论 (0)编辑 收藏

Hashtable真的能存储对象吗?

 

看一看下面的很简单的代码,先是声明了一个HashtableStringBuffer对象,然后分四次把StriingBuffer对象放入到Hashtable表中,在每次放入之前都对这个StringBuffer对象append()了一些新的字符串:

package reference;

import java.util.*;

public class HashtableAdd{

    public static void main(String[] args){

        Hashtable ht = new Hashtable();

        StringBuffer sb = new StringBuffer();

        sb.append("abc,");

        ht.put("1",sb);    

        sb.append("def,");

        ht.put("2",sb);

        sb.append("mno,");

        ht.put("3",sb);

        sb.append("xyz.");

        ht.put("4",sb);

       

        int numObj=0;

        Enumeration it = ht.elements();

        while(it.hasMoreElements()){

            System.out.print("get StringBufffer "+(++numObj)+" from Hashtable: ");

            System.out.println(it.nextElement());

        }

    }

}

如果你认为输出的结果是:
get StringBufffer 1 from Hashtable: abc,
get StringBufffer 2 from Hashtable: abc,def

get StringBufffer 3 from Hashtable: abc,def,mno,
get StringBufffer 4 from Hashtable: abc,def,mno,xyz.

那么你就要回过头再仔细看一看上一个问题了,把对象时作为入口参数传给函数,实质上是传递了对象的引用,向Hashtable传递StringBuffer对象也是只传递了这个StringBuffer对象的引用!每一次向Hashtable表中put一次StringBuffer,并没有生成新的StringBuffer对象,只是在Hashtable表中又放入了一个指向同一StringBuffer对象的引用而已。

Hashtable表存储的任何一个StringBuffer对象(更确切的说应该是对象的引用)的改动,实际上都是对同一个"StringBuffer"的改动。所以Hashtable并不能真正存储能对象,而只能存储对象的引用。也应该知道这条原则对与Hashtable相似的Vector, List, Map, Set等都是一样的。

上面的例程的实际输出的结果是:

/* RUN RESULT

get StringBufffer 1 from Hashtable: abc,def,mno,xyz.

get StringBufffer 2 from Hashtable: abc,def,mno,xyz.

get StringBufffer 3 from Hashtable: abc,def,mno,xyz.

get StringBufffer 4 from Hashtable: abc,def,mno,xyz.

*/

posted @ 2008-03-14 10:45 秋枫故事 阅读(572) | 评论 (0)编辑 收藏

关于标签

在做编辑功能 的时候,往往会通过一个主键ID得到相应的对象信息,然后显示到编辑页面中。如果涉及到<html:select>标签,
表示点编辑的时候,选择下拉框会显示相应的选项。
JSP页面一般这样显示:
<html:select property="busiSetId" style="width:120px;">
 <option value="">请选择</option>
  <logic:present name="ret">
           <logic:iterate id="model" name="ret">
     <option value="<bean:write name="model" property="ID"/>"><bean:write name="model" property="name"/></option>
            </logic:iterate>
   </logic:present>
</html:select>
但这是样子总是显示第一条数据,解决这个问题最简单的方法是在JSP页面最后添加下面语句:
<script language="javascript">
document.all("busiSetId").value="<bean:write name='CustomerSetForm' property='busiSetId'/>";
</script>

因为这段代码表示手动设置busiSetId元素,也就是<html:select>控件的值为要显示的值,而且这个代码是放到JSP最后面,
每次都会执行。

标签嵌套使用注意事项:
<logic:equal value="<bean:write name='customer' property='cusId'/>" >
注意双引号内只能使用单引号了。

posted @ 2008-03-13 09:48 秋枫故事 阅读(258) | 评论 (0)编辑 收藏

项目中用到的JS代码

function addDev()
{
 var sFeatures="dialogWidth:700px;dialogHeight:500px;scroll:no;";
 var customerId = document.all['cusId'].value;
 var result= window.showModalDialog('<%=appURL %>/businesspermit/DeviceSelectAction.do?formAction=toAddPage&customerId='+customerId,"",sFeatures);
 if(result!=null )
 {
  <logic:present name="edit" scope="request">
     document.CustomerSetForm.action="<%=appURL %>/businesspermit/CustomerSetAction.do?formAction=toEditBusi&showType=1";
  </logic:present>
   <logic:notPresent name="edit" scope="request">
   document.CustomerSetForm.action="<%=appURL %>/businesspermit/CustomerSetAction.do?formAction=getBusinessSet";
   </logic:notPresent>
  
  // window.location.reload();
  
  CustomerSetForm.submit();
 }
}

这个函数表示:添加新的设备JS函数,window.showModalDialog()会返回一个值result,如果result!=null,则刷新这个页面。
原来是用window.location.reload();刷新页面的,但是这样就不能保留之前页面上输入的数据,为了保留原来输入的数据,换成了
document.CustomerSetForm.action=“”;
CustomerSetForm.submit();
上面的语句表示:让这个页面重新指向另一个action地址,然后提交。这样,用了Struts标签后,以前四输入的数据仍然会保留到返回后的页面了。

注意:在js代码中,可能使用譬如说<logic:present>等标签。

posted @ 2008-03-13 09:37 秋枫故事 阅读(286) | 评论 (0)编辑 收藏

Comparator接口实例

// 新建链表并加入元素
        List<Member> members=new ArrayList<Member>();  
        members.add(new Member("Andy",20));  
        members.add(new Member("Dell",23));
        members.add(new Member("Felex",24));
        members.add(new Member("Bill",21));
        members.add(new Member("Cindy",22));
        
        // 创建一个比较器匿名类
        Comparator comparator=new Comparator(){
          public int compare(Object op1,Object op2){
            Member memberOp1=(Member)op1;
            Member memberOp2=(Member)op2;
            
            // 按姓名排序
            return memberOp1.getName().compareTo(memberOp2.getName());
          }
        };
        
        // 排序
        Collections.sort(members,comparator);
        
        // 输出排序后的链表
        for(Member member:members){
          System.out.println(member.getName() + ":" + member.getAge());
        }
         
      }

输出结果:
Andy:20
Bill:21
Cindy:22
Dell:23
Felex:24

posted @ 2008-03-12 17:25 秋枫故事 阅读(316) | 评论 (0)编辑 收藏

IE浏览器自动刷新

当你做网页时,是不是有的时候想让你的网页自动不停刷新,或者过一段时间自动跳转到另外一个你自己设定的页面?其实实现这个效果非常地简单,而且这个效果甚至不能称之为特效。你只要把如下代码加入你的网页中就可以了。

  1,页面自动刷新:把如下代码加入<head>区域中<meta http-equiv="refresh" content="20">,其中20指每隔20秒刷新一次页面.

posted @ 2008-03-12 17:20 秋枫故事 阅读(1443) | 评论 (1)编辑 收藏

关于window.opener

window.opener 返回的是创建当前窗口的那个窗口的引用,比如点击了a.htm上的一个链接而打开了b.htm,然后我们打算在b.htm上输入一个值然后赋予a.htm上的一个id为“name”的textbox中,就可以写为:

window.opener.document.getElementById("name").value = "输入的数据";

posted @ 2008-03-12 17:15 秋枫故事 阅读(172) | 评论 (0)编辑 收藏

定时器改善

以前的好像是用Timer类来实现的,后来的JDK有改善了:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
  
  class RunnablTest implements Runnable
  {
   public void run()
   {
    System.out.println("ok");
   }
  }
  
    // 5秒后执行任务,每隔2秒执行一次任务:打印"ok"字符串
  executor.scheduleAtFixedRate(new RunnablTest(), 5, 2, TimeUnit.SECONDS);

posted @ 2008-03-12 17:13 秋枫故事 阅读(173) | 评论 (0)编辑 收藏

many-to-many映射

<class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses" table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
create table Address ( addressId bigint not null primary key )

posted @ 2008-03-12 17:10 秋枫故事 阅读(190) | 评论 (0)编辑 收藏

java中栈(stack)与堆(heap)

 在java中内存分为“栈”和“堆”这两种(Stack and Heap).基本数据类型存储在“栈”中,对象引用类型实际存储在“堆”中,在栈中只是保留了引用内存的地址值。
    顺便说说“==”与“equals()方法”,以帮助理解两者(Stack and Heap)的概念。
    在Java中利用"=="比较变量时候,系统使用变量在stack(栈)中所存的值来作为对比的依据,基本数据类型在stack中所存的值就是其內容值,而引用类型在stack中所存放的值是本身所指向Heap中对象的地址值。 Java.lang包中的Object类有public boolean equals (Object obj)方法。它比较两个对象是否相等。仅当被比较的两个引用指向同一对象时,对象的equals()方法返回true。(至于String类的equals()方法,是因为它重写(override)equals()方法)

posted @ 2008-03-12 17:06 秋枫故事 阅读(305) | 评论 (0)编辑 收藏

删除HashMap中值注意事项

java.util.Map m = new java.util.HashMap();
        m.put("aaa", "aaa ");
        m.put("bbb", " bbb");
        m.put("ccc", "ccc   ");

        Iterator iterator = m.keySet().iterator();
        while (iterator.hasNext())
        {
            String sessionId = (String) iterator.next();
            if ("aaa".equals(sessionId))
            {
                // 这行代码是关键
                iterator.remove();
            }
        }

posted @ 2008-03-12 16:57 秋枫故事 阅读(350) | 评论 (0)编辑 收藏

java初始化顺序

在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那些变量仍会在调用任何方法之前得到初始化——甚至在构建器调用之前。例如:
class Tag {
  Tag(int marker) {
    System.out.println("Tag(" + marker + ")");
  }
}

class Card {
  Tag t1 = new Tag(1); // 先初始化t1
  Card() {
    // Indicate we're in the constructor:
    System.out.println("Card()");
    t3 = new Tag(33); // Re-initialize t3
  }
  Tag t2 = new Tag(2); // 然后初始化t2
  void f() {
    System.out.println("f()");
  }
  Tag t3 = new Tag(3); // 接着初始化t3
}

public class OrderOfInitialization {
  public static void main(String[] args) {
    Card t = new Card();
    t.f(); // Shows that construction is done
  }
}

它的输入结果如下:
"Tag(1)",
   "Tag(2)",
   "Tag(3)",
   "Card()",
   "Tag(33)",
   "f()"
// 以下是人综合例子:
//总的原则:先静态后动态,先定义初始化,后构造函数初始化
/**
   * 实例化Child对象时
   * 先父类静态成员初始化,后子类静态成员初始化
   * 然后是父类成员,父类构造函数,最后是子类
   * 成员,子类构造函数
*/

class Parent {
 private static int s = getS("父类静态成员");

 private int num = getNum();

 public Parent() {
  System.out.println("父类构造函数");
 }

 private static int getS(String string) {
  System.out.println(string);
  return 47;
 }

 public int getNum() {
  System.out.println("父类私有成员");
  return num;
 }

 public static void setS(int s) {
  Parent.s = s;
 }

}

class Child extends Parent {
 private int num = prt("子类私有成员");

 private static int s = getS("子类静态成员");

 public static void setS(int s) {
  Child.s = s;
 }

 public Child() {
  System.out.println("子类构造函数");
 }

 public void setNum(int num) {
  this.num = num;
 }

 private int prt(String string) {
  System.out.println(string);
  return 5;
 }

 public static int getS(String string) {
  System.out.println(string);
  return s;
 }
}


public class Tee {

 /**
  * @param args
  */
 public static void main(String[] args) {
  Child c = new Child();
  c.setNum(100);

  // 为什么输出的是0
  System.out.print(c.getNum());

//  Child cStatic = new Child();
//  cStatic.setS(100);
//  System.out.println(cStatic.getS("s"));
     


 }

}

最后输出结果:
父类静态成员
子类静态成员
父类私有成员
父类构造函数
子类私有成员
子类构造函数
父类私有成员
0

posted @ 2008-03-12 15:09 秋枫故事 阅读(380) | 评论 (0)编辑 收藏

JAVA集合类总结

 

l       HashSet:如果集合中对象所属的类重新定义了equals()方法,那么这个类也必须重新定义hashCode()方法,并且保证当两个对象用equals()方法比较的结果为true时,这两个对象的hashCode()方法的返回值相等。

l       TreeSet:如果对集合中的对象进行自然排序,要求对象所属的类实现Comparable接口,并且保证这个类的compareTo()equals()方法采用相同的比较规则来比较两个对象是否相等。

l       HashMap:如果集合中键对象所属的类重新定义了equals()方法,那么这个类也必须重新定义hashCode()方法,并且保证当两个键对象用equals()方法比较的结果为true时,这两个键对象的hashCode()方法的返回值相等。

l       TreeMap:如果对集合中的键对象进行自然排序,要求键对象所属的类实现Comparable接口,并且保证这个类的compareTo()equals()方法采用相同的比较规则来比较两个对象是否相等。

由此可见,为了使应用程序更加健壮,在编写JAVA类时不妨养这样的编程习惯:

l       如果JAVA类重新定义了equals()方法,那么这个类也必须重新定义hashCode()方法,并且保证当两个对象用equals()方法比较的结果为true时,这两个对象的hashCode()方法的返回值相等。

l       如果JAVA类实现了Comparable接口,那么应该重新定义compareTo()equals()hashCode()方法,保证compareTo()equals()方法采用相同的比较规则来比较两个对象是否相等,并且保证当两个对象用equals()方法比较的结果为true时,这两个对象的hashCode()方法的返回值相等。

posted @ 2008-03-12 14:29 秋枫故事 阅读(245) | 评论 (0)编辑 收藏

(转)使用java.text.SimpleDateFormat类进行文本日期和Date日期的转换

Date类内部既不存储年月日也不存储时分秒,而是存储一个从1970年1月1日0点0分0秒开始的毫秒数,而真正有用的年月日时分秒毫秒都是从这个毫秒数转化而来,这是它不容易被使用的地方,尤其是显示和存储的场合。但Date类的优势在于方便计算和比较。
另一点,日常生活中我们习惯用年月日时分秒这样的文本日期来表示时间,它方便显示和存储,也容易理解,但不容易计算和比较。
综上所述,我们在程序中进行日期时间处理时经常需要在在文本日期和Date类之间进行转换,为此我们需要借助java.text.SimpleDateFormat类来进行处理,下文列举了它的几个常用示例。

1.将Date转化为常见的日期时间字符串
这里我们需要用到java.text.SimpleDateFormat类的format方法,其中可以指定年月日时分秒的模式字符串格式。
Date date = new Date();
Format formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
System.out.println("转化的时间等于="+formatter.format(date));
其中
yyyy表示四位数的年份
MM表示两位数的月份
dd表示两位数的日期
HH表示两位数的小时
mm表示两位数的分钟
ss表示两位数的秒钟

2.将文本日期转化为Date以方便比较
文本日期的优势在于便于记忆,容易处理,但缺点是不方便比较,这时我们需要借助SimpleDateFormat的parse方法得到Date对象再进行比较,实例如下:
String strDate1="2004年8月9日";
String strDate2="2004年10月5日";

SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy年MM月dd日");
java.util.Date date1 = myFormatter.parse(strDate1);

java.util.Date date2 = myFormatter.parse(strDate2);

// Date比较能得出正确结果
if(date2.compareTo(date1)>0){
      System.out.println(strDate2+">"+strDate1);
}

// 字符串比较得不出正确结果
if(strDate2.compareTo(strDate1)>0){
      System.out.println(strDate2+">"+strDate1);
}


3.100天后的时间

       // 当前时间
        Date date = new Date();
        SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd");
        String str = formate.format(date);
        System.out.println("当前时间:"+str);
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        // 100天后
        c.add(Calendar.DAY_OF_MONTH, 100);

        System.out.println("100天后时间:"+formate.format(c.getTime()));


SimpleDateFormat 类字段:
字母  日期或时间元素  表示  示例 
G  Era 标志符  Text  AD 
y  年  Year  1996; 96 
M  年中的月份  Month  July; Jul; 07 
w  年中的周数  Number  27 
W  月份中的周数  Number  2 
D  年中的天数  Number  189 
d  月份中的天数  Number  10 
F  月份中的星期  Number  2 
E  星期中的天数  Text  Tuesday; Tue 
a  Am/pm 标记  Text  PM 
H  一天中的小时数(0-23)  Number  0 
k  一天中的小时数(1-24)  Number  24 
K  am/pm 中的小时数(0-11)  Number  0 
h  am/pm 中的小时数(1-12)  Number  12 
m  小时中的分钟数  Number  30 
s  分钟中的秒数  Number  55 
S  毫秒数  Number  978 
z  时区  General time zone  Pacific Standard Time; PST; GMT-08:00 
Z  时区  RFC 822 time zone  -0800 

posted @ 2008-03-12 09:52 秋枫故事 阅读(3319) | 评论 (0)编辑 收藏

java面试基础知识

最近因为要换工作了,所以在网上找了一些java面试基础知识:
1.谈谈final, finally, finalize的区别
final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。

  finally?在异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。

  finalize?方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。

2.HashMap和Hashtable的区别
HashMap与HashTable主要从三方面来说。
一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

3.Collection 和 Collections的区别
Collection是集合类的上级接口,继承与他的接口主要有Set List.
Collections
是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作

4.


public class Hea {
 
 // 定义一个String没有给予初始值,默认为null
 String a ;
 int i =3;
 
 // 覆盖hashCode()方法
 public int hashCode() {
  
  return 12;
 }

 public static void main(String[] args) {
  Hea he = new Hea();
  
  // String数组默认为null
  String[] b = new String[3];
  
  System.out.println("a="+he.a);
  System.out.println(b[2]);
  
  System.out.println(he.hashCode());
  
  Object obj = (Object)he;
  
  Hea tmp = (Hea)obj;
  System.out.println(tmp.i);
  
  String h = "abc";
  String h2 = h;
  h = "bcd";
  System.out.println(h2);
 }
}

输出结果:
a=null
null
12
3
abc

posted @ 2008-03-12 09:20 秋枫故事 阅读(211) | 评论 (0)编辑 收藏

热烈庆祝自已开通博客了:)

希望以后能够将自已学习JAVA的点点滴滴记录在这里。。。

posted @ 2008-03-11 21:12 秋枫故事 阅读(117) | 评论 (0)编辑 收藏

<2008年3月>
2425262728291
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

新闻档案

搜索

最新评论

阅读排行榜

评论排行榜