风雨无阻

2008年3月20日

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 秋枫故事 阅读(233) | 评论 (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 秋枫故事 阅读(3103) | 评论 (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 秋枫故事 阅读(1309) | 评论 (0)编辑 收藏

关于表单中的重置按钮

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

posted @ 2009-05-08 11:37 秋枫故事 阅读(2477) | 评论 (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 秋枫故事 阅读(195) | 评论 (0)编辑 收藏

摘一部电影中的内容


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

posted @ 2009-04-23 09:15 秋枫故事 阅读(197) | 评论 (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 秋枫故事 阅读(222) | 评论 (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 秋枫故事 阅读(1006) | 评论 (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 秋枫故事 阅读(424) | 评论 (0)编辑 收藏

关于ORACLE中的DECODE

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

posted @ 2008-11-13 15:59 秋枫故事 阅读(2912) | 评论 (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 秋枫故事 阅读(897) | 评论 (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 秋枫故事 阅读(216) | 评论 (0)编辑 收藏

hibernate二级缓存的实现

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

posted @ 2008-04-16 18:17 秋枫故事 阅读(1753) | 评论 (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 秋枫故事 阅读(135) | 评论 (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 秋枫故事 阅读(2437) | 评论 (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 秋枫故事 阅读(1046) | 评论 (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 秋枫故事 阅读(240) | 评论 (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 秋枫故事 阅读(298) | 评论 (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 秋枫故事 阅读(347) | 评论 (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 秋枫故事 阅读(167) | 评论 (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 秋枫故事 阅读(191) | 评论 (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 秋枫故事 阅读(130) | 评论 (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 秋枫故事 阅读(608) | 评论 (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 秋枫故事 阅读(3660) | 评论 (3)编辑 收藏

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

导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

新闻档案

搜索

最新评论

阅读排行榜

评论排行榜