2008年3月11日
class loader 加載 class file 到內(nèi)存
jvm內(nèi)存包括: method area(存放class name, class path , 類修飾符等信息), java stack(每一個(gè)線程單獨(dú)有個(gè)stack),java heap(存放對(duì)象的數(shù)據(jù),數(shù)組數(shù)據(jù)等,被所有線程共享的), pc寄存器(每一個(gè)線程單獨(dú)有個(gè)pc寄存器,用于存放下一步指令),本地方法棧。
java 堆 可 分為三部分:Perm,Tenured,Yong區(qū)??梢酝ㄟ^參數(shù)來配置空間大小:
-Xms :指定了JVM初始啟動(dòng)以后初始化內(nèi)存
-Xmx:指定JVM堆得最大內(nèi)存,在JVM啟動(dòng)以后,會(huì)分配-Xmx參數(shù)指定大小的內(nèi)存給JVM,但是不一定全部使用,JVM會(huì)根據(jù)-Xms參數(shù)來調(diào)節(jié)真正用于JVM的內(nèi)存
Perm Generation
-XX:PermSize=16M -XX:MaxPermSize=64M
jQuery.post( url, [data], [callback], [type] ) :使用POST方式來進(jìn)行異步請(qǐng)求
參數(shù):
url (String) : 發(fā)送請(qǐng)求的URL地址.
data (Map) : (可選) 要發(fā)送給服務(wù)器的數(shù)據(jù),以 Key/value 的鍵值對(duì)形式表示。
callback (Function) : (可選) 載入成功時(shí)回調(diào)函數(shù)(只有當(dāng)Response的返回狀態(tài)是success才是調(diào)用該方法)。
type (String) : (可選)官方的說明是:Type of data to be sent。其實(shí)應(yīng)該為客戶端請(qǐng)求的類型(JSON,XML,等等)
這是一個(gè)簡(jiǎn)單的 POST 請(qǐng)求功能以取代復(fù)雜 $.ajax 。請(qǐng)求成功時(shí)可調(diào)用回調(diào)函數(shù)。如果需要在出錯(cuò)時(shí)執(zhí)行函數(shù),請(qǐng)
使用 $.ajax。示例代碼:
var con = $('#content').val();//待提交的數(shù)據(jù)
$.post("checkContent.action",{"mess.content":con},
function (data){
if(data != "")//有非法敏感字
{
alert(data);
$('#content').focus();
}
},"html");
點(diǎn)擊提交:
以下轉(zhuǎn)載自:
http://hi.baidu.com/tianhesj/blog/item/0dd9718d32be4011b21bbacc.html
Namespaces翻譯為命名空間。命名空間有什么作用呢?當(dāng)我們?cè)谝粋€(gè)XML文檔中使用他人的或者多個(gè)DTD文件,就會(huì)出現(xiàn)這樣的矛盾:因?yàn)閄ML中標(biāo)識(shí)都是自己創(chuàng)建的,在不同的DTD文件中,標(biāo)識(shí)名可能相同但表示的含義不同,這就可能引起數(shù)據(jù)混亂。
比如在一個(gè)文檔<table>wood table</table>中<table>表示桌子,
而在另一個(gè)文檔<table>namelist</table>中<table>表示表格。如果我需要同時(shí)處理這兩個(gè)文檔,就會(huì)發(fā)生名字沖突。
了解決這個(gè)問題,我們引進(jìn)了namespaces這個(gè)概念。namespaces通過給標(biāo)識(shí)名稱加一個(gè)網(wǎng)址(URL)定位的方法來區(qū)別這些名稱相同的標(biāo)識(shí)。
Namespaces同樣需要在XML文檔的開頭部分聲明,聲明的語法如下:
<document xmlns:yourname='URL'>
其中yourname是由你定義的namespaces的名稱,URL就是名字空間的網(wǎng)址。
假設(shè)上面的"桌子<table>"文檔來自http://www.zhuozi.com,我們就可以聲明為
<document xmlns:zhuozi='http://www.zhuozi.com'>;
然后在后面的標(biāo)識(shí)中使用定義好的名字空間:
<zhuozi:table>wood table</table>
這樣就將這兩個(gè)<table>區(qū)分開來。注意的是:設(shè)置URL并不是說這個(gè)標(biāo)識(shí)真的要到那個(gè)網(wǎng)址去讀取,僅僅作為一種區(qū)別的標(biāo)志而已。
命名沖突
因?yàn)閄ML文檔中使用的元素不是固定的,那么兩個(gè)不同的XML文檔使用同一個(gè)名字來描述不同類型的元素的情況就可能發(fā)生。而這種情況又往往會(huì)導(dǎo)致命名沖突。請(qǐng)看下面兩個(gè)例子
這個(gè) XML 文檔在table元素中攜帶了水果的信息:
<table>
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
這個(gè) XML 文檔在table元素中攜帶了桌子的信息(家具,不能吃的哦):
<table>
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
如果上面兩個(gè)XML文檔片斷碰巧在一起使用的話,那么將會(huì)出現(xiàn)命名沖突的情況。因?yàn)檫@兩個(gè)片斷都包含了<table>元素,而這兩個(gè)table元素的定義與所包含的內(nèi)容又各不相同。
--------------------------------------------------------------------------------
使用前綴解決命名沖突問題
下面的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>
現(xiàn)在已經(jīng)沒有元素命名沖突的問題了,因?yàn)檫@兩個(gè)文檔對(duì)各自的table元素使用了不同的前綴,table元素在兩個(gè)文檔中分別是(<h:table> 和<f:table>)。
通過使用前綴,我們創(chuàng)建了兩個(gè)不同的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>
在上面兩個(gè)例子中除了使用前綴外,兩個(gè)table元素都使用了xmlns屬性,使元素和不同的命名空間關(guān)聯(lián)到一起。
--------------------------------------------------------------------------------
命名空間屬性
命名空間屬性一般放置在元素的開始標(biāo)記處,其使用語法如下所示:
xmlns:namespace-prefix="namespace"
在上面的例子中,命名空間定義了一個(gè)Internet 地址:
xmlns:f="http://www.w3schools.com/furniture"
W3C 命名規(guī)范聲明命名空間本身就是一個(gè)統(tǒng)一資源標(biāo)示符,Uniform Resource Identifier (URI)。
當(dāng)我們?cè)谠氐拈_始標(biāo)記處使用命名空間時(shí),該元素所有的子元素都將通過一個(gè)前綴與同一個(gè)命名空間相互關(guān)聯(lián)。
注意:用來標(biāo)識(shí)命名空間的網(wǎng)絡(luò)地址并不被XML解析器調(diào)用,XML解析器不需要從這個(gè)網(wǎng)絡(luò)地址中查找信息,該網(wǎng)絡(luò)地址的作用僅僅是給命名空間一個(gè)唯一的名字,因此這個(gè)網(wǎng)絡(luò)地址也可以是虛擬的,然而又很多公司經(jīng)常把這個(gè)網(wǎng)絡(luò)地址值象一個(gè)真實(shí)的Web頁(yè)面,這個(gè)地址包含了關(guān)于當(dāng)前命名空間更詳細(xì)的信息。
可以訪問http://www.w3.org/TR/html4/.
--------------------------------------------------------------------------------
統(tǒng)一資源標(biāo)識(shí)符
通用資源標(biāo)識(shí)符(A Uniform Resource Identifier (URI))是一個(gè)標(biāo)識(shí)網(wǎng)絡(luò)資源的字符串。最普通的URI應(yīng)該是統(tǒng)一資源定位符Uniform Resource Locator (URL)。URL用于標(biāo)識(shí)網(wǎng)絡(luò)主機(jī)的地址。另一方面,另一個(gè)不常用的URI是通用資源名字Universal Resource Name (URN)。在我們的例子中,一般使用的是URLs。
既然前面的例子使用的URL地址來標(biāo)識(shí)命名空間,我們可以確信這個(gè)命名空間是唯一的。
--------------------------------------------------------------------------------
默認(rèn)的命名空間
定義一個(gè)默認(rèn)的XML命名空間使得我們?cè)谧釉氐拈_始標(biāo)記中不需要使用前綴。他的語法如下所示:
<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的時(shí)候,就會(huì)發(fā)現(xiàn)命名空間使用的是如此頻繁。XSL樣式單主要用于將XML文檔轉(zhuǎn)換成類似于HTML文件的格式。
如果看一下下面的XSL文檔,就會(huì)發(fā)現(xiàn)有很多標(biāo)記都是HTML標(biāo)記。那些標(biāo)記并不是HTML標(biāo)記,是加了前綴的XSL,這個(gè)XSL前綴由命名空間"http://www.w3.org/TR/xsl"所標(biāo)識(shí):
<?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博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/yc_8301/archive/2008/11/19/3335738.aspx
表單中有一個(gè)type=reset的button,可以將表單中的數(shù)據(jù)重置為初始表單的數(shù)據(jù),但如果表單中有一些“單選”或“多選”框,其默認(rèn)值是通過javascript腳本控制的;這種情況通過reset按鈕不會(huì)重置為初始狀態(tài),所以不能簡(jiǎn)單的調(diào)用reset自帶按鈕,解決方法:將重置按鈕設(shè)為普通按鈕,在onclick方法中,選調(diào)用form.reset()方法,然后再調(diào)用javascript腳本
我用的myeclipse 6.0版本,oracle是10g版本,在連接的時(shí)候出現(xiàn)了以下問題
java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-12705: Cannot access NLS data files or invalid environment specified
一開始以為是驅(qū)動(dòng)程序的問題,其實(shí)不是,只需在eclipse目錄下找到eclipse.ini文件,把
Duser.language=en 改成 Duser.language=zh就行了。
有可能大家出現(xiàn)的問題不一樣,按我的方法有可能不好使,我寫出來僅供大家參考,因?yàn)楫?dāng)時(shí)為解決這問題,花了不少時(shí)間,希望大家少走彎路
我有一把白色塑膠雨傘。買的時(shí)候喜歡它雪白可愛,瘦瘦長(zhǎng)長(zhǎng),簡(jiǎn)直像個(gè)鶴立雞群的美女??上н@種美麗偏偏不耐看,風(fēng)吹雨打久了,顏色變黃,還多了雀斑一樣的污跡。而且瘦長(zhǎng)是沒用的,哪里像折傘這么善解人意。于是,我開始制造各種機(jī)會(huì)。 趁著下雨帶它出門,左擱一會(huì)兒,右放一下,希望一下子大意忘了拿,讓它自動(dòng)消失,大家無痛分手。我就可以理直氣壯買一把新的,多好!
失寵的人通常最敏感。 有一天,它突如其來消失了,完全不用花我任何心思。傘也有它的自尊。問題是,等一等,我還沒有準(zhǔn)備好。不行,它不可以沒經(jīng)我的同意就玩失蹤。我便一心一意要找它回來,花盡心思去想,到底在哪里弄丟的呢?書店,餐廳還是公共汽車地鐵呢?
真是峰回路轉(zhuǎn),沒想到在戲院把它找回來,小別重逢,它苦著副臉在等我來新發(fā)現(xiàn)。重拾舊歡,大團(tuán)圓結(jié)局。 換一個(gè)角度來看,如果我失敗了,找不到它,它永遠(yuǎn)消失了,淡淡的遺憾感覺,會(huì)不會(huì)更合我心意?
人世間的破鏡重圓,大概都是一言難盡。
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
構(gòu)架一張t3
表,字段為“集團(tuán)編號(hào)”,“集團(tuán)用戶數(shù)”
然后用“集團(tuán)表”和t3表再關(guān)聯(lián)
前兩天聯(lián)華對(duì)單系統(tǒng)頻頻出現(xiàn)out of memory的問題,經(jīng)過層層分析,終于弄明白原來瓶頸出現(xiàn)在Spring獲取Bean那一步上。以前的做法是在delegate層ApplicationContext context = new ClassPathXmlApplicationContext("Compare.xml"); 這樣我把log4j的debug打開后發(fā)現(xiàn),每做1步操作的時(shí)候系統(tǒng)都會(huì)重新加載這個(gè)xml,重新創(chuàng)建Bean的實(shí)例,重新獲取url-mapping,這無疑是個(gè)及其錯(cuò)誤的方式。 研究后發(fā)現(xiàn)正確的使用方式是: 首先在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 } 這樣在啟動(dòng)服務(wù)時(shí)已經(jīng)加載了xml中的配置,而不用每次都重新加載,大大提高了系統(tǒng)的效率
事先,把你的硬盤劃出 10G左右的空閑空間!
1.下載suse安裝光盤,準(zhǔn)備好8G左右的空間,最好是ntfs格式的?,F(xiàn)在有 10.1正式版和10.2的beta 2版,2006年12月7號(hào),10.2就除正式版了!然后將五張光盤全部解壓,加壓到根目錄的一個(gè)文件夾下,比如X:\suse\
2.找到解壓出的第一張光盤linux和initrd文件,放在根目錄下.
32位的路徑應(yīng)該是 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。下載網(wǎng)址:http://download.it168.com/14/1411/33307/33307_4.shtml
http://grub4dos.sourceforge.net
4.將下載的grub for dos 解壓到C盤可能會(huì)提示覆蓋什么profile.sys文件,直接替換就行。
5.改boot.ini文件,先把boot.ini文件的隱藏屬性給去掉!
把boot.ini文件用記事本打開在最下添加這么一行
C:\GRLDR="GRUB"
然后保存,
6.下一步就是重啟系統(tǒng)了,當(dāng)要選擇要啟動(dòng)的系統(tǒng)時(shí),選擇grub,找到類似 commanderline ,按下enter,進(jìn)入dos 提示符狀態(tài)下,
輸入 find /linux 回車,此時(shí)會(huì)顯示
hd(0,6)——(肯定會(huì)有不同,請(qǐng)看下面注釋)
kernel hd(0,6)/linux回車
initrd hd(0,6)/initrd回車
boot回車
(注釋:hd(0,6) 6是你的分區(qū),根據(jù)你的分區(qū)不同,這個(gè)數(shù)字會(huì)不同,0表示是第一塊硬盤。)
進(jìn)入圖形界面,
會(huì)提示類似 no cd in your cd drive的語句,不用管他,選擇back
7.按照提示選擇,都是簡(jiǎn)單的英語,完全可以搞定的(抄襲linuxsir.org幾位大俠的話。。呵呵)
8.等到要你指定安裝文件的位置的時(shí)候,你把你剛才解壓的suse的幾張光盤的位置填進(jìn)去就行了,然后回車,會(huì)提示選擇安裝語言,鍵盤鼠標(biāo)什么的,按照提示選就ok了。大家安裝時(shí)候注意分區(qū),不要采用它默認(rèn)的分區(qū)方式,那樣的你的windows操作系統(tǒng)就會(huì)被它給刪掉了。
再羅嗦一點(diǎn),Suse的分區(qū)方式?jīng)]有fedora和ubuntu做的好,后面的兩個(gè)全部可以手動(dòng)分區(qū),而suse只有切換到專家模式下才能更改分區(qū),剛開始,搞的我又點(diǎn)郁悶。
等待安裝完成。。。。大約40 ~ 1個(gè)小時(shí)。不要著急!中間還要填root密碼和給機(jī)器命名,添加user等操作!
9.安裝完成后,重啟,進(jìn)入系統(tǒng),user不用填密碼自動(dòng)登錄系統(tǒng)(現(xiàn)在我還不知道怎么才能不讓它自動(dòng)登錄)
祝大家好運(yùn)。。。。
——部分內(nèi)容來自linuxsir.org,感謝Thruth大俠!
摘要: 關(guān)于ORACLE中的DECODE- -
 ...
閱讀全文
如果你手上有一本《Spring in Action》, 那么你最好從第三部分"Spring 在 Web 層的應(yīng)用--建立 Web 層"開始看, 否則那將是一場(chǎng)惡夢(mèng)!
首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 應(yīng)用程序接收到 http://localhost:8088/hello.do(請(qǐng)求路徑為/hello.do) 的請(qǐng)求后, Spring 將這個(gè)請(qǐng)求交給一個(gè)名為 helloController 的程序進(jìn)行處理, helloController 再調(diào)用 一個(gè)名為 hello.jsp 的 jsp 文件生成 HTML 代碼發(fā)給用戶的瀏覽器顯示. 上面的名稱(/hello.do, helloController, hello.jsp) 都是變量, 你可以更改.
在 Spring MVC 中, jsp 文件中盡量不要有 Java 代碼, 只有 HTML 代碼和"迭代(forEach)"與"判斷(if)"兩個(gè)jstl標(biāo)簽. jsp 文件只作為渲染(或稱為視圖 View)模板使用.
好了, 我們開始吧. 首先我們需要一個(gè)放在 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 標(biāo)簽), 它是一個(gè) Java Servlet 程序. 我們將它命名為 test. 然后我們?cè)倥渲?Servlet 映射(test-mapping 標(biāo)簽), 也就是你希望哪些請(qǐng)求被DispatcherServlet處理. 這里, 我們?cè)O(shè)置后綴名為 do(*.do) 的所有URL請(qǐng)求都被名為 test 的 DispatcherServlet 的程序處理. 選擇 .do 只是一個(gè)習(xí)慣,但是你不要選擇 .html! 雖然《Spring in Action》選擇了 .html, 但是那是一種非常糟糕的作法, 特別是你整合 Apache 和 Tomcat 的時(shí)候.
-
配置 CharacterEncodingFilter (filter 標(biāo)簽), 否則你會(huì)發(fā)現(xiàn)中文亂碼. 因?yàn)槲业?jsp 和 html 文件都是 UTF-8 編碼的, 所以我在 param-value 標(biāo)簽中設(shè)置了 UTF-8. 估計(jì)你使用的是 GB2312 或者 GBK, 立即轉(zhuǎn)到 UTF-8 上來吧.
-
分解配置文件. context-param 標(biāo)簽指明我們的配置文件還有 /WEB-INF/database.xml 和 /WEB-INF/applicationContext.xml. ContextLoaderListener(listener 標(biāo)簽) 由此得知配置文件是哪些, 它會(huì)將它們載入.
因?yàn)槲覀儗?DispatcherServlet 命名為test, 所以我們?cè)?WEB-INF 目錄下建立一個(gè)名為 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 處理一個(gè)名為 hello 的模板時(shí), 它會(huì)渲染 /WEB-INF/jsp/hello.jsp 文件. 把 jsp 文件放到 /WEB-INF/jsp/ 目錄下是被鼓勵(lì)的, 這樣可以防止用戶不經(jīng)過 Controller 直接訪問 jsp 文件從而出錯(cuò)(有些頑皮的人很喜歡這樣做).
-
配置 SimpleUrlHandlerMapping, 在上面的配置文件中, /hello.do 的請(qǐng)求將被 helloController 處理. "/hello.do"和"helloController" 是變量, 你可以更改. 但是你注意到了嗎, hello.do 以 .do 作為后綴名. 如果這里(本文的條件下)你不使用.do 作為后綴名, 就沒有程序來處理這個(gè)請(qǐng)求了. 因?yàn)?DispatcherServlet 將收到的請(qǐng)求轉(zhuǎn)交給 SimpleUrlHandlerMapping, DispatcherServlet 收不到的請(qǐng)求, SimpleUrlHandlerMapping 當(dāng)然也收不到了. 你可以在 props 標(biāo)簽內(nèi)配置多個(gè) prop 標(biāo)簽.
-
我們將在后面編寫com.ecnulxq.test.HelloController類.
上面, 我們?cè)?web.xml 文件中告訴 ContextLoaderListener, 我們還有另外兩個(gè)配置文件 /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>
它配置了以下功能:
database.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ">
<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>
它配置了以下功能(不過,已經(jīng)注釋掉了):
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
現(xiàn)在, 我們來編寫 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 創(chuàng)建時(shí)間: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() 設(shè)置的對(duì)象我們可以在 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>
7 Functions 標(biāo)簽庫(kù)
稱呼 Functions 標(biāo)簽庫(kù)為標(biāo)簽庫(kù),倒不如稱呼其為函數(shù)庫(kù)來得更容易理解些。因?yàn)?Functions 標(biāo)簽庫(kù)并沒有提供傳統(tǒng)的標(biāo)簽來為 JSP 頁(yè)面的工作服務(wù),而是被用于 EL 表達(dá)式語句中。在 JSP2.0 規(guī)范下出現(xiàn)的 Functions 標(biāo)簽庫(kù)為 EL 表達(dá)式語句提供了許多更為有用的功能。 Functions 標(biāo)簽庫(kù)分為兩大類,共 16 個(gè)函數(shù)。
長(zhǎng)度函數(shù): fn:length
字符串處理函數(shù): 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
以下是各個(gè)函數(shù)的用途和屬性以及簡(jiǎn)單示例。
9.7.1 長(zhǎng)度函數(shù) fn:length 函數(shù)
長(zhǎng)度函數(shù) fn:length 的出現(xiàn)有重要的意義。在 JSTL1.0 中,有一個(gè)功能被忽略了,那就是對(duì)集合的長(zhǎng)度取值。雖然 java.util.Collection 接口定義了 size 方法,但是該方法不是一個(gè)標(biāo)準(zhǔn)的 JavaBean 屬性方法(沒有 get,set 方法),因此,無法通過 EL 表達(dá)式“ ${collection.size} ”來輕松取得。
fn:length 函數(shù)正是為了解決這個(gè)問題而被設(shè)計(jì)出來的。它的參數(shù)為 input ,將計(jì)算通過該屬性傳入的對(duì)象長(zhǎng)度。該對(duì)象應(yīng)該為集合類型或 String 類型。其返回結(jié)果是一個(gè) int 類型的值。下面看一個(gè)示例。
<%ArrayList arrayList1 = new ArrayList();
arrayList1.add("aa");
arrayList1.add("bb");
arrayList1.add("cc");
%>
<%request.getSession().setAttribute("arrayList1", arrayList1);%>
${fn:length(sessionScope.arrayList1)}
假設(shè)一個(gè) ArrayList 類型的實(shí)例“ arrayList1 ”,并為其添加三個(gè)字符串對(duì)象,使用 fn:length 函數(shù)后就可以取得返回結(jié)果為“ 3 ”。
9.7.2 判斷函數(shù) fn:contains 函數(shù)
fn:contains 函數(shù)用來判斷源字符串是否包含子字符串。它包括 string 和 substring 兩個(gè)參數(shù),它們都是 String 類型,分布表示源字符串和子字符串。其返回結(jié)果為一個(gè) boolean 類型的值。下面看一個(gè)示例。
${fn:contains("ABC", "a")}<br>
${fn:contains("ABC", "A")}<br>
前者返回“ false ”,后者返回“ true ”。
9.7.3 fn:containsIgnoreCase 函數(shù)
fn:containsIgnoreCase 函數(shù)與 fn:contains 函數(shù)的功能差不多,唯一的區(qū)別是 fn:containsIgnoreCase 函數(shù)對(duì)于子字符串的包含比較將忽略大小寫。它與 fn:contains 函數(shù)相同,包括 string 和 substring 兩個(gè)參數(shù),并返回一個(gè) boolean 類型的值。下面看一個(gè)示例。
${fn:containsIgnoreCase("ABC", "a")}<br>
${fn:containsIgnoreCase("ABC", "A")}<br>
前者和后者都會(huì)返回“ true ”。
9.7.4 詞頭判斷函數(shù) fn:startsWith 函數(shù)
fn:startsWith 函數(shù)用來判斷源字符串是否符合一連串的特定詞頭。它除了包含一個(gè) string 參數(shù)外,還包含一個(gè) subffx 參數(shù),表示詞頭字符串,同樣是 String 類型。該函數(shù)返回一個(gè) boolean 類型的值。下面看一個(gè)示例。
${fn:startsWith ("ABC", "ab")}<br>
${fn:startsWith ("ABC", "AB")}<br>
前者返回“ false ”,后者返回“ true ”。
9.7.5 詞尾判斷函數(shù) fn:endsWith 函數(shù)
fn:endsWith 函數(shù)用來判斷源字符串是否符合一連串的特定詞尾。它與 fn:startsWith 函數(shù)相同,包括 string 和 subffx 兩個(gè)參數(shù),并返回一個(gè) boolean 類型的值。下面看一個(gè)示例。
${fn:endsWith("ABC", "bc")}<br>
${fn:endsWith("ABC", "BC")}<br>
前者返回“ false ”,后者返回“ true ”。
9.7.6 字符實(shí)體轉(zhuǎn)換函數(shù) fn:escapeXml 函數(shù)
fn:escapeXml 函數(shù)用于將所有特殊字符轉(zhuǎn)化為字符實(shí)體碼。它只包含一個(gè) string 參數(shù),返回一個(gè) String 類型的值。
9.7.8 字符匹配函數(shù) fn:indexOf 函數(shù)
fn:indexOf 函數(shù)用于取得子字符串與源字符串匹配的開始位置,若子字符串與源字符串中的內(nèi)容沒有匹配成功將返回“ -1 ”。它包括 string 和 substring 兩個(gè)參數(shù),返回結(jié)果為 int 類型。下面看一個(gè)示例。
${fn:indexOf("ABCD","aBC")}<br>
${fn:indexOf("ABCD","BC")}<br>
前者由于沒有匹配成功,所以返回 -1 ,后者匹配成功將返回位置的下標(biāo),為 1 。
摘要: 對(duì)于Hibernate這類ORM而言,緩存顯的尤為重要,它是持久層性能提升的關(guān)鍵.簡(jiǎn)單來講Hibernate就是對(duì)JDBC進(jìn)行封裝,以實(shí)現(xiàn)內(nèi)部狀態(tài)的管理,OR關(guān)系的映射等,但隨之帶來的就是數(shù)據(jù)訪問效率的降低,和性能的下降,而緩存就是彌補(bǔ)這一缺點(diǎn)的重要方法.
緩存就是數(shù)據(jù)庫(kù)數(shù)據(jù)在內(nèi)存中的臨時(shí)容器,包括數(shù)據(jù)庫(kù)數(shù)據(jù)在內(nèi)存中的臨時(shí)拷貝,它位于數(shù)據(jù)庫(kù)與數(shù)...
閱讀全文
在介紹GROUP BY 和 HAVING 子句前,我們必需先講講sql語言中一種特殊的函數(shù):聚合函數(shù),例如SUM, COUNT, MAX, AVG等。這些函數(shù)和其它函數(shù)的根本區(qū)別就是它們一般作用在多條記錄上。
SELECT SUM(population) FROM bbc
這里的SUM作用在所有返回記錄的population字段上,結(jié)果就是該查詢只返回一個(gè)結(jié)果,即所有國(guó)家的總?cè)丝跀?shù)。
通過使用GROUP BY 子句,可以讓SUM 和 COUNT 這些函數(shù)對(duì)屬于一組的數(shù)據(jù)起作用。當(dāng)你指定 GROUP BY region 時(shí), 屬于同一個(gè)region(地區(qū))的一組數(shù)據(jù)將只能返回一行值,也就是說,表中所有除region(地區(qū))外的字段,只能通過 SUM, COUNT等聚合函數(shù)運(yùn)算后返回一個(gè)值。 HAVING子句可以讓我們篩選成組后的各組數(shù)據(jù),WHERE子句在聚合前先篩選記錄.也就是說作用在GROUP BY 子句和HAVING子句前,而 HAVING子句在聚合后對(duì)組記錄進(jìn)行篩選。
讓我們還是通過具體的實(shí)例來理解GROUP BY 和 HAVING 子句,還采用第三節(jié)介紹的bbc表。
SQL實(shí)例:
一、顯示每個(gè)地區(qū)的總?cè)丝跀?shù)和總面積:
SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
先以region把返回記錄分成多個(gè)組,這就是GROUP BY的字面含義。分完組后,然后用聚合函數(shù)對(duì)每組中的不同字段(一或多條記錄)作運(yùn)算。
二、 顯示每個(gè)地區(qū)的總?cè)丝跀?shù)和總面積.僅顯示那些面積超過1000000的地區(qū)。
SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
HAVING SUM(area)>1000000
在這里,我們不能用where來篩選超過1000000的地區(qū),因?yàn)楸碇胁淮嬖谶@樣一條記錄。
相反,HAVING子句可以讓我們篩選成組后的各組數(shù)據(jù)。
group by分組統(tǒng)計(jì)SQL語句(實(shí)例)
用一條查詢語句,查出各姓名的數(shù)值余額.
用戶表:
姓名
a
b
c
....
扣費(fèi)表:
姓名 數(shù)值
a 3.5
b 5.2
a 2
...
充值表:
姓名 數(shù)值
b 10
a 10
a 10.5
...
返回:
姓名 差額(充值和-扣費(fèi)和)
測(cè)試通過
select table1.TNAME,table1.TelName, (table3.充值-table2.扣費(fèi)) as 差額
from 用戶表 table1,(select TelName,sum(TelQryh)as 扣費(fèi) from 扣費(fèi)表 group by TelName)table2,
(select TelName,sum(TelQryc)as 充值 from 充值表 group by TelName)table3 where
table1.TelName=table2.TelName and table1.TelName=table3.TelName
最近一直在弄WebWork,Struts都快忘了。今天又自己小試了一下SSH,結(jié)果每次都是報(bào)空指針異常,經(jīng)過一番研究,發(fā)現(xiàn),如果不把a(bǔ)ction的type改成
org.springframework.web.struts.DelegatingActionProxy
的話,就會(huì)報(bào)這個(gè)
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>
這樣就不會(huì)報(bào)那個(gè)異常了,測(cè)試通過^_^
我的配置文件代碼:
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屬性了
----------------------------------------------
開發(fā)sessionbean EJB最少也需要三個(gè)class,remote interface,home interface,and bean implementation(bean行為).
1. remote interface 用來揭示EJB對(duì)外的一些方法.
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 是用來規(guī)定怎樣創(chuàng)建一個(gè)實(shí)現(xiàn)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 是提供方法的實(shí)現(xiàn),這些方法在上述兩種interface中都有規(guī)定了.
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必須打包進(jìn)一個(gè)JAR文件中,JAR文件中包含了目錄結(jié)構(gòu)和包的層次.在本例中, 這些classes是在包helloworld,這樣他們需要在目錄helloWorld/ 下.
部署發(fā)布描述器ejb-jar.XML和jboss.xml
在JAR文檔創(chuàng)建之前,還需要一個(gè)叫META-INF的目錄,這是存放部署發(fā)布描述器的(一般叫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>
雖然有了上面你的應(yīng)用程序
和JNDI name的梆定,但是一旦部署發(fā)布到JBoss服務(wù)器上,你還需要一個(gè)jndi.properties文件,以告訴調(diào)用你程序的客戶端請(qǐng)求到哪里去初始化JNDI naming service.
測(cè)試
程序:
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 .])-->復(fù)制到j(luò)boss deploy目錄.
---------------------------------------------------------
原文 URL http://blog.blogchina.com/refer.159508.html
---------------------------------------------------------
補(bǔ)充說明如下:
OS: windows 2000;
JDK: 1.5.0rc;
JBoss: 4.0
HelloWorld.jar
|--META-INF
| |--jboss.xml
| |--ejb-jar.xml
| |--MANIFEST.MF (自動(dòng)生成)
|--helloWorld
|--RemoteHello.class
|--jndi.properties
|--HomeHello.class
|--HelloBean.class
其中 測(cè)試文件 MyTest.class 同目錄拷貝一份 jndi.properties 文件過來.
jndi.properties 的內(nèi)容如下:
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
大家都知道,在Java里對(duì)對(duì)象的操作是基于引用的。而當(dāng)我們需要對(duì)一組對(duì)象操作的時(shí)候, 就需要有接收這一組引用的容器。平時(shí)我們最常用的就是數(shù)組。在Java里可以定義一個(gè)對(duì)象數(shù)組來完成許多操作。可是,數(shù)組長(zhǎng)度是固定的,如果我們需要更 加靈活的解決方案該怎么辦呢?
Java提供了container classes來解決這一問題。container classes包括兩個(gè)部分:Collection和Map。
它們的結(jié)構(gòu)是這樣的:

本文重點(diǎn)介紹HashMap。首先介紹一下什么是Map。在數(shù)組中我們是通過數(shù)組下標(biāo)來對(duì)其內(nèi)容索引的, 而在Map中我們通過對(duì)象來對(duì)對(duì)象進(jìn)行索引,用來索引的對(duì)象叫做key,其對(duì)應(yīng)的對(duì)象叫做value。 在下文中會(huì)有例子具體說明。
再來看看HashMap和TreeMap有什么區(qū)別。HashMap通過hashcode對(duì)其內(nèi)容進(jìn)行快速查找,而TreeMap中所有的元素都保持著 某種固定的順序,如果你需要得到一個(gè)有序的結(jié)果你就應(yīng)該使用TreeMap(HashMap中元素的排列順序是不固定的)。
下面就要進(jìn)入本文的主題了。先舉個(gè)例子說明一下怎樣使用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()則用來檢驗(yàn)對(duì)象是否已經(jīng)存在??梢钥?出,和ArrayList的操作相比,HashMap除了通過key索引其內(nèi)容之外,別的方面差異并不大。
前面介紹了,HashMap是基于HashCode的,在所有對(duì)象的超類Object中有一個(gè)HashCode()方法, 但是它和equals方法一樣,并不能適用于所有的情況,這樣我們就需要重寫自己的HashCode()方法。
下面就舉這樣一個(gè)例子:
程序代碼: |
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!";
}
} |
在這個(gè)例子中,Element用來索引對(duì)象Figureout,也即Element為key,F(xiàn)igureout為value。 在Figureout中隨機(jī)生成一個(gè)浮點(diǎn)數(shù),如果它比0.5大,打印“OK!”,否則打印“Impossible!”。 之后查看Element(5)對(duì)應(yīng)的Figureout結(jié)果如何。
結(jié)果卻發(fā)現(xiàn),無論你運(yùn)行多少次,得到的結(jié)果都是“Not found”。也就是說索引Element(5)并不在HashMap中。這怎么可能呢?
原因得慢慢來說:Element的HashCode方法繼承自O(shè)bject,而Object中的HashCode方法返回的HashCode對(duì)應(yīng)于當(dāng)前 的地址,也就是說對(duì)于不同的對(duì)象,即使它們的內(nèi)容完全相同,用HashCode()返回的值也會(huì)不同。這樣實(shí)際上違背了我們的意圖。因?yàn)槲覀冊(cè)谑褂?HashMap時(shí), 希望利用相同內(nèi)容的對(duì)象索引得到相同的目標(biāo)對(duì)象,這就需要HashCode()在此時(shí)能夠返回相同的值。
在上面的例子中,我們期望new Element(i) (i=5)與 Element test=new Element(5)是相同的, 而實(shí)際上這是兩個(gè)不同的對(duì)象,盡管它們的內(nèi)容相同,但它們?cè)趦?nèi)存中的地址不同。因此很自然的, 上面的程序得不到我們?cè)O(shè)想的結(jié)果。下面對(duì)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返回,這樣對(duì)于相同內(nèi)容的對(duì)象來說它們的hashcode也就相同了。而覆蓋equals()是為了在HashMap判斷兩個(gè)key是否 相等時(shí)使結(jié)果有意義(有關(guān)重寫equals()的內(nèi)容可以參考我的另一篇文章《
重新編寫Object類中的方法 》)。修改后的程序運(yùn)行結(jié)果如下:
h2:
Get the result for Element:
Impossible!
請(qǐng)記?。喝绻阆胗行У氖褂肏ashMap,你就必須重寫在其的HashCode()。
還有兩條重寫HashCode()的原則:
不必對(duì)每個(gè)不同的對(duì)象都產(chǎn)生一個(gè)唯一的hashcode,只要你的HashCode方法使get()能夠得到put()放進(jìn)去的內(nèi)容就可以了。即“不為 一原則”。 生成hashcode的算法盡量使hashcode的值分散一些, 不要很多hashcode都集中在一個(gè)范圍內(nèi),這樣有利于提高HashMap的性能。即“分散原則”。 至于第二條原則的具體原因,有興趣者可以參考Bruce Eckel的《Thinking in Java》,
在那里有對(duì)HashMap內(nèi)部實(shí)現(xiàn)原理的介紹,這里就不贅述了。
掌握了這兩條原則,你就能夠用好HashMap編寫自己的程序了。不知道大家注意沒有, java.lang.Object中提供的三個(gè)方法:clone(),equals()和hashCode()雖然很典型, 但在很多情況下都不能夠適用,它們只是簡(jiǎn)單的由對(duì)象的地址得出結(jié)果。 這就需要我們?cè)谧约旱某绦蛑兄貙懰鼈?,其?shí)java類庫(kù)中也重寫了千千萬萬個(gè)這樣的方法。 利用面向?qū)ο蟮亩鄳B(tài)性——覆蓋,Java的設(shè)計(jì)者很優(yōu)雅的構(gòu)建了Java的結(jié)構(gòu),也更加體現(xiàn)了Java是一門純OOP語言的特性。
Java提供的Collection和Map的功能是十分強(qiáng)大的,它們能夠使你的程序?qū)崿F(xiàn)方式更為靈活, 執(zhí)行效率更高。希望本文能夠?qū)Υ蠹腋玫氖褂肏ashMap有所幫助。
String a = "hello";
String b = "world";
String c = "ok";
String d = "is";
String result = a+b+c+d;
問:共產(chǎn)生多少個(gè)對(duì)象?
答:
現(xiàn)在的編譯器早就對(duì)這些代碼作了優(yōu)化,編譯成如下:
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();
因此產(chǎn)生了6個(gè)對(duì)象,其中5個(gè)字符串對(duì)象,一個(gè)StringBuffer臨時(shí)對(duì)象。
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();
}
對(duì)于rownum來說它是oracle系統(tǒng)順序分配為從查詢返回的行的編號(hào),返回的第一行分配的是1,第二行是2,依此類推,這個(gè)偽字段可以用于限制查詢返回的總行數(shù),而且rownum不能以任何表的名稱作為前綴。
舉例說明:
例如表:student(學(xué)生)表,表結(jié)構(gòu)為:
ID char(6) --學(xué)號(hào)
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 對(duì)于等于某值的查詢條件
如果希望找到學(xué)生表中第一條學(xué)生的信息,可以使用rownum=1作為條件。但是想找到學(xué)生表中第二條學(xué)生的信息,使用rownum=2結(jié)果查不到數(shù)據(jù)。因?yàn)閞ownum都是從1開始,但是1以上的自然數(shù)在rownum做等于判斷是時(shí)認(rèn)為都是false條件,所以無法查到rownum = n(n>1的自然數(shù))。
SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回記錄條數(shù)的地方,保證不出錯(cuò),如:隱式游標(biāo))
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對(duì)于大于某值的查詢條件
如果想找到從第二行記錄以后的記錄,當(dāng)使用rownum>2是查不出記錄的,原因是由于rownum是一個(gè)總是從1開始的偽列,Oracle 認(rèn)為rownum> n(n>1的自然數(shù))這種條件依舊不成立,所以查不到記錄
SQL> select rownum,id,name from student where rownum >2;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
那如何才能找到第二行以后的記錄呀??梢允褂靡韵碌淖硬樵兎椒▉斫鉀Q。注意子查詢中的rownum必須要有別名,否則還是不會(huì)查出記錄來,這是因?yàn)閞ownum不是某個(gè)表的列,如果不起別名的話,無法知道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對(duì)于小于某值的查詢條件
如果想找到第三條記錄以前的記錄,當(dāng)使用rownum<3是能得到兩條記錄的。顯然rownum對(duì)于rownum<n((n>1的自然數(shù))的條件認(rèn)為是成立的,所以可以找到記錄。
SQL> select rownum,id,name from student where rownum <3;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
1 200001 張一
2 200002 王二
綜上幾種情況,可能有時(shí)候需要查詢r(jià)ownum在某區(qū)間的數(shù)據(jù),那怎么辦呀從上可以看出rownum對(duì)小于某值的查詢條件是人為true的,rownum對(duì)于大于某值的查詢條件直接認(rèn)為是false的,但是可以間接的讓它轉(zhuǎn)為認(rèn)為是true的。那就必須使用子查詢。例如要查詢r(jià)ownum在第二行到第三行之間的數(shù)據(jù),包括第二行和第三行數(shù)據(jù),那么我們只能寫以下語句,先讓它返回小于等于三的記錄行,然后在主查詢中判斷新的rownum的別名列大于等于二的記錄行。但是這樣的操作會(huì)在大數(shù)據(jù)集中影響速度。
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的是在取數(shù)據(jù)的時(shí)候產(chǎn)生的序號(hào),所以想對(duì)指定排序的數(shù)據(jù)去指定的rowmun行數(shù)據(jù)就必須注意了。
SQL> select rownum ,id,name from student order by name;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
3 200003 李三
2 200002 王二
1 200001 張一
4 200004 趙四
可以看出,rownum并不是按照name列來生成的序號(hào)。系統(tǒng)是按照記錄插入時(shí)的順序給記錄排的號(hào),rowid也是順序分配的。為了解決這個(gè)問題,必須使用子查詢
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標(biāo)出正確序號(hào)(有小到大)
筆者在工作中有一上百萬條記錄的表,在jsp頁(yè)面中需對(duì)該表進(jìn)行分頁(yè)顯示, 便考慮用rownum來作,下面是具體方法(每頁(yè)
顯示20條):
“select * from tabname where rownum<20 order by name" 但卻發(fā)現(xiàn)oracle卻不能按自己的意愿來執(zhí)行,而是先隨便
取20條記錄,然后再 order by,后經(jīng)咨詢oracle,說rownum確實(shí)就這樣,想用的話,只能用子查詢 來實(shí)現(xiàn)先排序,后
rownum,方法如下:
"select * from (select * from tabname order by name) where rownum<20",但這樣一來,效率會(huì)較低很多。
后經(jīng)筆者試驗(yàn),只需在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
選出結(jié)果后用name排序顯示結(jié)果。(先選再排序)
注意:只能用以上符號(hào)(<、<=、!=)。
select * from tablename where rownum != 10;返回的是前9條記錄。
不能用:>,>=,=,Between...and。由于rownum是一個(gè)總是從1開始的偽列,Oracle 認(rèn)為這種條件 不成立,查不到記錄.
另外,這個(gè)方法更快:
select * from (
select rownum r,a from yourtable
where rownum <= 20
order by name )
where r > 10
這樣取出第11-20條記錄!(先選再排序再選)
要先排序再選則須用select嵌套:內(nèi)層排序外層選。
rownum是隨著結(jié)果集生成的,一旦生成,就不會(huì)變化了;同時(shí),生成的結(jié)果是依次遞加的,沒有1就永遠(yuǎn)不會(huì)有2!
rownum 是在 查詢集合產(chǎn)生的過程中產(chǎn)生的偽列,并且如果where條件中存在 rownum 條件的話,則:
1: 假如 判定條件是常量,則:
只能 rownum = 1, <= 大于1 的自然數(shù), = 大于1 的數(shù)是沒有結(jié)果的, 大于一個(gè)數(shù)也是沒有結(jié)果的
即 當(dāng)出現(xiàn)一個(gè) rownum 不滿足條件的時(shí)候則 查詢結(jié)束 this is stop key!
2: 當(dāng)判定值不是常量的時(shí)候
若條件是 = var , 則只有當(dāng) var 為1 的時(shí)候才滿足條件,這個(gè)時(shí)候不存在 stop key ,必須進(jìn)行 full scan ,對(duì)每個(gè)滿足其他where條件的數(shù)據(jù)進(jìn)行判定
選出一行后才能去選rownum=2的行……
我們現(xiàn)在回到函數(shù)上。記得我們用 SUM 這個(gè)指令來算出所有的 Sales (營(yíng)業(yè)額)吧!如果我們的需求變成是要算出每一間店 (store_name) 的營(yíng)業(yè)額 (sales),那怎么辦呢?在這個(gè)情況下,我們要做到兩件事:第一,我們對(duì)于 store_name 及 Sales 這兩個(gè)欄位都要選出。第二,我們需要確認(rèn)所有的 sales 都要依照各個(gè) store_name 來分開算。這個(gè)語法為:
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
結(jié)果:
store_name |
SUM(Sales) |
Los Angeles |
$1800 |
San Diego |
$250 |
Boston |
$700 |
當(dāng)我們選不只一個(gè)欄位,且其中至少一個(gè)欄位有包含函數(shù)的運(yùn)用時(shí),我們就需要用到 GROUP BY 這個(gè)指令。在這個(gè)情況下,我們需要確定我們有 GROUP BY 所有其他的欄位。換句話說,除了有包括函數(shù)的欄位外,我 們都需要將其放在 GROUP BY 的子句中。
冒泡排序:
/*
* 冒泡排序:
*/
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;
}
}
}
}
之前我們看到的左連接 (left join),又稱內(nèi)部連接 (inner join)。在這個(gè)情況下,要兩個(gè)表格內(nèi)都有同樣的值,那一筆資料才會(huì)被選出。那如果我們想要列出一個(gè)表格中每一筆的資料,無論它的值在另一個(gè)表格中有沒有出現(xiàn),那該怎么辦呢?在這個(gè)時(shí)候,我們就需要用到 SQL OUTER JOIN (外部連接) 的指令。
外部連接的語法是依數(shù)據(jù)庫(kù)的不同而有所不同的。舉例來說,在 Oracle 上,我們會(huì)在 WHERE 子句中要選出所有資料的那個(gè)表格之后加上一個(gè) "(+)" 來代表說這個(gè)表格中的所有資料我們都要。
假設(shè)我們有以下的兩個(gè)表格:
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 |
|
我們需要知道每一間店的營(yíng)業(yè)額。如果我們用一個(gè)普通的連接,我們將會(huì)漏失掉 'New York'這個(gè)店,因?yàn)樗⒉淮嬖谟?Store_Information 這個(gè)表格。所以,在這個(gè)情況下,我們需要用外部連接來串聯(lián)這兩個(gè)表格:
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
我們?cè)谶@里是使用了 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;
結(jié)果:
store_name |
SALES |
Boston |
$700 |
New York |
|
Los Angeles |
$1800 |
San Diego |
$250 |
請(qǐng)注意: 當(dāng)?shù)诙€(gè)表格沒有相對(duì)的資料時(shí),SQL 會(huì)傳回 NULL 值。在這一個(gè)例子中, 'New York' 并不存在于 Store_Information 表格,所以它的 "SALES" 欄位是 NULL。
在之前,我對(duì)MSSQL中的內(nèi)連接和外連接所得出的數(shù)據(jù)集不是很清楚。這幾天重新溫習(xí)了一下SQL的書本,現(xiàn)在的思路應(yīng)該是很清楚了,現(xiàn)在把自己的理解發(fā)出來給大家溫習(xí)下。希望和我一樣對(duì)SQL的連接語句不太理解的朋友能夠有所幫助。(發(fā)這么菜的教程,各位大大們別笑話偶了,呵:D )
有兩個(gè)表A和表B。
表A結(jié)構(gòu)如下:
Aid:int;標(biāo)識(shí)種子,主鍵,自增ID
Aname:varchar
數(shù)據(jù)情況,即用select * from A出來的記錄情況如下圖1所示:
圖1:A表數(shù)據(jù)
表B結(jié)構(gòu)如下:
Bid:int;標(biāo)識(shí)種子,主鍵,自增ID
Bnameid:int
數(shù)據(jù)情況,即用select * from B出來的記錄情況如下圖2所示:
圖2:B表數(shù)據(jù)
為了把Bid和Aid加以區(qū)分,不讓大家有誤解,所以把Bid的起始種子設(shè)置為100。
有SQL基本知識(shí)的人都知道,兩個(gè)表要做連接,就必須有個(gè)連接字段,從上表中的數(shù)據(jù)可以看出,在A表中的Aid和B表中的Bnameid就是兩個(gè)連接字段。
下圖3說明了連接的所有記錄集之間的關(guān)系:
圖3:連接關(guān)系圖
現(xiàn)在我們對(duì)內(nèi)連接和外連接一一講解。
1.內(nèi)連接:利用內(nèi)連接可獲取兩表的公共部分的記錄,即圖3的記錄集C
語句如下:Select * from A JOIN B ON A.Aid=B.Bnameid
運(yùn)行結(jié)果如下圖4所示:
圖4:內(nèi)連接數(shù)據(jù)
其實(shí)select * from A,B where A.Aid=B.Bnameid與Select * from A JOIN B ON A.Aid=B.Bnameid的運(yùn)行結(jié)果是一樣的。
2.外連接:外連接分為兩種,一種是左連接(Left JOIN)和右連接(Right JOIN)
(1)左連接(Left JOIN):即圖3公共部分記錄集C+表A記錄集A1。
語句如下:select * from A Left JOIN B ON A.Aid=B.Bnameid
運(yùn)行結(jié)果如下圖5所示:
圖5:左連接數(shù)據(jù)
說明:
在語句中,A在B的左邊,并且是Left Join,所以其運(yùn)算方式為: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,
最終得出的結(jié)果圖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
運(yùn)行結(jié)果如下圖6所示:
圖6:右連接數(shù)據(jù)
說明:
在語句中,A在B的左邊,并且是Right Join,所以其運(yùn)算方式為: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,
最終得出的結(jié)果圖6中可以看出Aid及Aname非NULL的記錄都為圖3公共部分記錄集C中的記錄;Aid及Aname為NULL的Aid為11的記錄就是表B記錄集B1中存在的Bnameid。
總結(jié):
通過上面的運(yùn)算解說,相信很多人已經(jīng)想到,上面的情況(包括圖3的關(guān)系圖)說明的都只是A在B的左邊的情況,
以下語句B在A的右邊的又會(huì)出現(xiàn)什么情況呢??
select * from B Left JOIN A ON A.Aid=B.Bnameid
select * from B Right JOIN A ON A.Aid=B.Bnameid
其實(shí)對(duì)圖3左右翻轉(zhuǎn)一下就可以得出以下結(jié)論:
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所得出的記錄集也是一樣的。
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());
}
}
}
public class Aqiang {
// 靜態(tài)內(nèi)部類
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[]) {
// 靜態(tài)內(nèi)部類(Inner Class)意味著1創(chuàng)建一個(gè)static內(nèi)部類的對(duì)象,不需要一個(gè)外部類對(duì)象
Aqiang.Test test = new Aqiang.Test();
System.out.println("test" + test.i);
// 而非靜態(tài)內(nèi)部類,需要選創(chuàng)建一個(gè)外部類對(duì)象,然后才能創(chuàng)建內(nèi)部?jī)?nèi)對(duì)象
Aqiang aqiang = new Aqiang();
Aqiang.TestB tb = aqiang.new TestB();
System.out.println("testb" + tb.i);
}
}
流是一個(gè)有序的字節(jié)序列,可作為一個(gè)輸入源,也可作為一個(gè)輸出的目的地。
字節(jié)流以字節(jié)為單位輸入輸出,字節(jié)流類名含有stream,字符流以字符為單位輸入輸出,字節(jié)流
類名含有reader或writer.為了通用性,java中字符是16位的unicode字符,所以8位的字節(jié)流必
須和16位的字符流進(jìn)行轉(zhuǎn)換。字節(jié)流到字符流的轉(zhuǎn)換使用InputStreamReader類:
public InputStreamReader(InputStream in);
public InputStreamReader(InputStream in,String encoding);
public OuputStreamWriter(OnputStream in);
public OnputStreamWriter(OnputStream in,String encoding);
Reader和Writer類允許用戶在程序中無縫的支持國(guó)際字符集,如果要讀區(qū)的文件是別國(guó)語言,
要使用字符流。
JavaI/O字節(jié)流與字符流就是java 實(shí)現(xiàn)輸入/輸出 數(shù)據(jù) 字節(jié)流是一個(gè)字節(jié)一個(gè)字節(jié)的輸入/輸出 數(shù)據(jù) (兩個(gè)字節(jié)組成一個(gè)漢字)所以在用字節(jié)流讀一串漢字時(shí)會(huì)出現(xiàn)亂碼問題,
同樣字符流是一個(gè)字符一個(gè)字符流(一個(gè)字符=兩個(gè)字節(jié))的輸入/輸出 數(shù)據(jù) 用字符流讀一串漢字可以解決亂碼問題.
有以下三個(gè)對(duì)象:
US設(shè)備對(duì)象:USDevie
US設(shè)備類型對(duì)象:USDeviceModle
US設(shè)備端口對(duì)象:USDevicePort
class USDevice
{
....
// US設(shè)備類型
USDeviceModel model;
// US設(shè)備端口對(duì)象集合
Set<USDevicePort> devicePortSet = new HashSet();
}
/**
US設(shè)備類型說明每種設(shè)備都有不同的端口數(shù)目
*/
class USDeviceModel
{
....
// 設(shè)備端口數(shù)目
int deviceport;
}
class USDevicePort
{
private int deviceId;
private int devicePort;
}
1 : 1 : n
一種US設(shè)備(device)----->設(shè)備類型(model)------>不同數(shù)目的設(shè)備端口
US設(shè)備:設(shè)備類型:設(shè)備端口數(shù)目 = 1:1:n
所以,如果新增設(shè)備的時(shí)候,要根據(jù)設(shè)備類型,得到相應(yīng)的設(shè)備端口數(shù)目,
然后在USDevicePort對(duì)應(yīng)的數(shù)據(jù)庫(kù)表中插入記錄.
編輯設(shè)備的時(shí)候,如果編輯了US設(shè)備類型,則相應(yīng)的設(shè)備端口就會(huì)改變,這種
情況除了更新USDevice對(duì)應(yīng)的數(shù)據(jù)表中設(shè)備類型外,因?yàn)樵赨SDevicePort表中
存放在以前設(shè)備類型的端口記錄,所以應(yīng)該先刪除之前的端口記錄,然后再插入
現(xiàn)在類型所對(duì)應(yīng)的端口記錄.
其實(shí)只需:
//這一步根據(jù)具體設(shè)備id,從數(shù)據(jù)庫(kù)中取出相應(yīng)的設(shè)備對(duì)象
USDevice device = .....
// 得到US設(shè)備端口對(duì)象集合
Set devicePortSet = device.getDevicePortSet();
// 先清空以前所有的端口記錄
devicePortSet.clear();
// 根據(jù)編輯后類型ID,得到設(shè)備類型對(duì)象,并可以得到此種類型上的端口數(shù)目
USDeviceModel usModle = ....
// 根據(jù)上面得到的端口數(shù)據(jù),構(gòu)造"設(shè)備端口數(shù)目"對(duì)象,并把所有的設(shè)備端口對(duì)象添加到集合中
//最后更新US設(shè)備
這樣,每當(dāng)編輯一個(gè)US設(shè)備的類型后,在設(shè)備端口表中,這種設(shè)備編輯之前的類型所對(duì)應(yīng)的端口記錄
就會(huì)被刪除,而保持只有新的設(shè)備類型端口記錄.
注意在配置USDevice.hbm.xml文件時(shí),要將<set name="devicePortSet " casecade="all-orphan-delete" .../>
因?yàn)樗鼤?huì)將和USDevice沒有關(guān)聯(lián)的對(duì)象從數(shù)據(jù)中刪除,這也與程序中devicePortSet.clear()相對(duì)應(yīng).
看一看下面的很簡(jiǎn)單的代碼,先是聲明了一個(gè)Hashtable和StringBuffer對(duì)象,然后分四次把StriingBuffer對(duì)象放入到Hashtable表中,在每次放入之前都對(duì)這個(gè)StringBuffer對(duì)象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());
}
}
}
|
如果你認(rèn)為輸出的結(jié)果是:
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.
那么你就要回過頭再仔細(xì)看一看上一個(gè)問題了,把對(duì)象時(shí)作為入口參數(shù)傳給函數(shù),實(shí)質(zhì)上是傳遞了對(duì)象的引用,向Hashtable傳遞StringBuffer對(duì)象也是只傳遞了這個(gè)StringBuffer對(duì)象的引用!每一次向Hashtable表中put一次StringBuffer,并沒有生成新的StringBuffer對(duì)象,只是在Hashtable表中又放入了一個(gè)指向同一StringBuffer對(duì)象的引用而已。
對(duì)Hashtable表存儲(chǔ)的任何一個(gè)StringBuffer對(duì)象(更確切的說應(yīng)該是對(duì)象的引用)的改動(dòng),實(shí)際上都是對(duì)同一個(gè)"StringBuffer"的改動(dòng)。所以Hashtable并不能真正存儲(chǔ)能對(duì)象,而只能存儲(chǔ)對(duì)象的引用。也應(yīng)該知道這條原則對(duì)與Hashtable相似的Vector, List, Map, Set等都是一樣的。
上面的例程的實(shí)際輸出的結(jié)果是:
/* 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.
*/
|
在做編輯功能 的時(shí)候,往往會(huì)通過一個(gè)主鍵ID得到相應(yīng)的對(duì)象信息,然后顯示到編輯頁(yè)面中。如果涉及到<html:select>標(biāo)簽,
表示點(diǎn)編輯的時(shí)候,選擇下拉框會(huì)顯示相應(yīng)的選項(xiàng)。
JSP頁(yè)面一般這樣顯示:
<html:select property="busiSetId" style="width:120px;">
<option value="">請(qǐng)選擇</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>
但這是樣子總是顯示第一條數(shù)據(jù),解決這個(gè)問題最簡(jiǎn)單的方法是在JSP頁(yè)面最后添加下面語句:
<script language="javascript">
document.all("busiSetId").value="<bean:write name='CustomerSetForm' property='busiSetId'/>";
</script>
因?yàn)檫@段代碼表示手動(dòng)設(shè)置busiSetId元素,也就是<html:select>控件的值為要顯示的值,而且這個(gè)代碼是放到JSP最后面,
每次都會(huì)執(zhí)行。
標(biāo)簽嵌套使用注意事項(xiàng):
<logic:equal value="<bean:write name='customer' property='cusId'/>" >
注意雙引號(hào)內(nèi)只能使用單引號(hào)了。
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();
}
}
這個(gè)函數(shù)表示:添加新的設(shè)備JS函數(shù),window.showModalDialog()會(huì)返回一個(gè)值result,如果result!=null,則刷新這個(gè)頁(yè)面。
原來是用window.location.reload();刷新頁(yè)面的,但是這樣就不能保留之前頁(yè)面上輸入的數(shù)據(jù),為了保留原來輸入的數(shù)據(jù),換成了
document.CustomerSetForm.action=“”;
CustomerSetForm.submit();
上面的語句表示:讓這個(gè)頁(yè)面重新指向另一個(gè)action地址,然后提交。這樣,用了Struts標(biāo)簽后,以前四輸入的數(shù)據(jù)仍然會(huì)保留到返回后的頁(yè)面了。
注意:在js代碼中,可能使用譬如說<logic:present>等標(biāo)簽。
// 新建鏈表并加入元素
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));
// 創(chuàng)建一個(gè)比較器匿名類
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());
}
}
輸出結(jié)果:
Andy:20
Bill:21
Cindy:22
Dell:23
Felex:24
當(dāng)你做網(wǎng)頁(yè)時(shí),是不是有的時(shí)候想讓你的網(wǎng)頁(yè)自動(dòng)不停刷新,或者過一段時(shí)間自動(dòng)跳轉(zhuǎn)到另外一個(gè)你自己設(shè)定的頁(yè)面?其實(shí)實(shí)現(xiàn)這個(gè)效果非常地簡(jiǎn)單,而且這個(gè)效果甚至不能稱之為特效。你只要把如下代碼加入你的網(wǎng)頁(yè)中就可以了。
1,頁(yè)面自動(dòng)刷新:把如下代碼加入<head>區(qū)域中<meta http-equiv="refresh" content="20">,其中20指每隔20秒刷新一次頁(yè)面.
window.opener 返回的是創(chuàng)建當(dāng)前窗口的那個(gè)窗口的引用,比如點(diǎn)擊了a.htm上的一個(gè)鏈接而打開了b.htm,然后我們打算在b.htm上輸入一個(gè)值然后賦予a.htm上的一個(gè)id為“name”的textbox中,就可以寫為:
window.opener.document.getElementById("name").value = "輸入的數(shù)據(jù)";
以前的好像是用Timer類來實(shí)現(xiàn)的,后來的JDK有改善了:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
class RunnablTest implements Runnable
{
public void run()
{
System.out.println("ok");
}
}
// 5秒后執(zhí)行任務(wù),每隔2秒執(zhí)行一次任務(wù):打印"ok"字符串
executor.scheduleAtFixedRate(new RunnablTest(), 5, 2, TimeUnit.SECONDS);
<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 )
在java中內(nèi)存分為“棧”和“堆”這兩種(Stack and Heap).基本數(shù)據(jù)類型存儲(chǔ)在“棧”中,對(duì)象引用類型實(shí)際存儲(chǔ)在“堆”中,在棧中只是保留了引用內(nèi)存的地址值。
順便說說“==”與“equals()方法”,以幫助理解兩者(Stack and Heap)的概念。
在Java中利用"=="比較變量時(shí)候,系統(tǒng)使用變量在stack(棧)中所存的值來作為對(duì)比的依據(jù),基本數(shù)據(jù)類型在stack中所存的值就是其內(nèi)容值,而引用類型在stack中所存放的值是本身所指向Heap中對(duì)象的地址值。 Java.lang包中的Object類有public boolean equals (Object obj)方法。它比較兩個(gè)對(duì)象是否相等。僅當(dāng)被比較的兩個(gè)引用指向同一對(duì)象時(shí),對(duì)象的equals()方法返回true。(至于String類的equals()方法,是因?yàn)樗貙懀╫verride)equals()方法)
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))
{
// 這行代碼是關(guān)鍵
iterator.remove();
}
}
在一個(gè)類里,初始化的順序是由變量在類內(nèi)的定義順序決定的。即使變量定義大量遍布于方法定義的中間,那些變量仍會(huì)在調(diào)用任何方法之前得到初始化——甚至在構(gòu)建器調(diào)用之前。例如:
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
}
}
它的輸入結(jié)果如下:
"Tag(1)",
"Tag(2)",
"Tag(3)",
"Card()",
"Tag(33)",
"f()"
// 以下是人綜合例子:
//總的原則:先靜態(tài)后動(dòng)態(tài),先定義初始化,后構(gòu)造函數(shù)初始化
/**
* 實(shí)例化Child對(duì)象時(shí)
* 先父類靜態(tài)成員初始化,后子類靜態(tài)成員初始化
* 然后是父類成員,父類構(gòu)造函數(shù),最后是子類
* 成員,子類構(gòu)造函數(shù)
*/
class Parent {
private static int s = getS("父類靜態(tài)成員");
private int num = getNum();
public Parent() {
System.out.println("父類構(gòu)造函數(shù)");
}
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("子類靜態(tài)成員");
public static void setS(int s) {
Child.s = s;
}
public Child() {
System.out.println("子類構(gòu)造函數(shù)");
}
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"));
}
}
最后輸出結(jié)果:
父類靜態(tài)成員
子類靜態(tài)成員
父類私有成員
父類構(gòu)造函數(shù)
子類私有成員
子類構(gòu)造函數(shù)
父類私有成員
0
l HashSet:如果集合中對(duì)象所屬的類重新定義了equals()方法,那么這個(gè)類也必須重新定義hashCode()方法,并且保證當(dāng)兩個(gè)對(duì)象用equals()方法比較的結(jié)果為true時(shí),這兩個(gè)對(duì)象的hashCode()方法的返回值相等。
l TreeSet:如果對(duì)集合中的對(duì)象進(jìn)行自然排序,要求對(duì)象所屬的類實(shí)現(xiàn)Comparable接口,并且保證這個(gè)類的compareTo()和equals()方法采用相同的比較規(guī)則來比較兩個(gè)對(duì)象是否相等。
l HashMap:如果集合中鍵對(duì)象所屬的類重新定義了equals()方法,那么這個(gè)類也必須重新定義hashCode()方法,并且保證當(dāng)兩個(gè)鍵對(duì)象用equals()方法比較的結(jié)果為true時(shí),這兩個(gè)鍵對(duì)象的hashCode()方法的返回值相等。
l TreeMap:如果對(duì)集合中的鍵對(duì)象進(jìn)行自然排序,要求鍵對(duì)象所屬的類實(shí)現(xiàn)Comparable接口,并且保證這個(gè)類的compareTo()和equals()方法采用相同的比較規(guī)則來比較兩個(gè)對(duì)象是否相等。
由此可見,為了使應(yīng)用程序更加健壯,在編寫JAVA類時(shí)不妨養(yǎng)這樣的編程習(xí)慣:
l 如果JAVA類重新定義了equals()方法,那么這個(gè)類也必須重新定義hashCode()方法,并且保證當(dāng)兩個(gè)對(duì)象用equals()方法比較的結(jié)果為true時(shí),這兩個(gè)對(duì)象的hashCode()方法的返回值相等。
l 如果JAVA類實(shí)現(xiàn)了Comparable接口,那么應(yīng)該重新定義compareTo(),equals()和hashCode()方法,保證compareTo()和equals()方法采用相同的比較規(guī)則來比較兩個(gè)對(duì)象是否相等,并且保證當(dāng)兩個(gè)對(duì)象用equals()方法比較的結(jié)果為true時(shí),這兩個(gè)對(duì)象的hashCode()方法的返回值相等。
Date類內(nèi)部既不存儲(chǔ)年月日也不存儲(chǔ)時(shí)分秒,而是存儲(chǔ)一個(gè)從1970年1月1日0點(diǎn)0分0秒開始的毫秒數(shù),而真正有用的年月日時(shí)分秒毫秒都是從這個(gè)毫秒數(shù)轉(zhuǎn)化而來,這是它不容易被使用的地方,尤其是顯示和存儲(chǔ)的場(chǎng)合。但Date類的優(yōu)勢(shì)在于方便計(jì)算和比較。
另一點(diǎn),日常生活中我們習(xí)慣用年月日時(shí)分秒這樣的文本日期來表示時(shí)間,它方便顯示和存儲(chǔ),也容易理解,但不容易計(jì)算和比較。
綜上所述,我們?cè)诔绦蛑羞M(jìn)行日期時(shí)間處理時(shí)經(jīng)常需要在在文本日期和Date類之間進(jìn)行轉(zhuǎn)換,為此我們需要借助java.text.SimpleDateFormat類來進(jìn)行處理,下文列舉了它的幾個(gè)常用示例。
1.將Date轉(zhuǎn)化為常見的日期時(shí)間字符串
這里我們需要用到j(luò)ava.text.SimpleDateFormat類的format方法,其中可以指定年月日時(shí)分秒的模式字符串格式。
Date date = new Date();
Format formatter = new SimpleDateFormat("yyyy年MM月dd日HH時(shí)mm分ss秒");
System.out.println("轉(zhuǎn)化的時(shí)間等于="+formatter.format(date));
其中
yyyy表示四位數(shù)的年份
MM表示兩位數(shù)的月份
dd表示兩位數(shù)的日期
HH表示兩位數(shù)的小時(shí)
mm表示兩位數(shù)的分鐘
ss表示兩位數(shù)的秒鐘
2.將文本日期轉(zhuǎn)化為Date以方便比較
文本日期的優(yōu)勢(shì)在于便于記憶,容易處理,但缺點(diǎn)是不方便比較,這時(shí)我們需要借助SimpleDateFormat的parse方法得到Date對(duì)象再進(jìn)行比較,實(shí)例如下:
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比較能得出正確結(jié)果
if(date2.compareTo(date1)>0){
System.out.println(strDate2+">"+strDate1);
}
// 字符串比較得不出正確結(jié)果
if(strDate2.compareTo(strDate1)>0){
System.out.println(strDate2+">"+strDate1);
}
3.100天后的時(shí)間
// 當(dāng)前時(shí)間
Date date = new Date();
SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd");
String str = formate.format(date);
System.out.println("當(dāng)前時(shí)間:"+str);
Calendar c = Calendar.getInstance();
c.setTime(date);
// 100天后
c.add(Calendar.DAY_OF_MONTH, 100);
System.out.println("100天后時(shí)間:"+formate.format(c.getTime()));
SimpleDateFormat 類字段:
字母 日期或時(shí)間元素 表示 示例
G Era 標(biāo)志符 Text AD
y 年 Year 1996; 96
M 年中的月份 Month July; Jul; 07
w 年中的周數(shù) Number 27
W 月份中的周數(shù) Number 2
D 年中的天數(shù) Number 189
d 月份中的天數(shù) Number 10
F 月份中的星期 Number 2
E 星期中的天數(shù) Text Tuesday; Tue
a Am/pm 標(biāo)記 Text PM
H 一天中的小時(shí)數(shù)(0-23) Number 0
k 一天中的小時(shí)數(shù)(1-24) Number 24
K am/pm 中的小時(shí)數(shù)(0-11) Number 0
h am/pm 中的小時(shí)數(shù)(1-12) Number 12
m 小時(shí)中的分鐘數(shù) Number 30
s 分鐘中的秒數(shù) Number 55
S 毫秒數(shù) Number 978
z 時(shí)區(qū) General time zone Pacific Standard Time; PST; GMT-08:00
Z 時(shí)區(qū) RFC 822 time zone -0800
最近因?yàn)橐獡Q工作了,所以在網(wǎng)上找了一些java面試基礎(chǔ)知識(shí):
1.談?wù)刦inal, finally, finalize的區(qū)別
final?修飾符(關(guān)鍵字)如果一個(gè)類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個(gè)類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,可以保證它們?cè)谑褂弥胁槐桓淖儭1宦暶鳛閒inal的變量必須在聲明時(shí)給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載。
finally?在異常處理時(shí)提供 finally 塊來執(zhí)行任何清除操作。如果拋出一個(gè)異常,那么相匹配的 catch 子句就會(huì)執(zhí)行,然后控制就會(huì)進(jìn)入 finally 塊(如果有的話)。
finalize?方法名。Java 技術(shù)允許使用 finalize() 方法在垃圾收集器將對(duì)象從內(nèi)存中清除出去之前做必要的清理工作。這個(gè)方法是由垃圾收集器在確定這個(gè)對(duì)象沒有被引用時(shí)對(duì)這個(gè)對(duì)象調(diào)用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。finalize() 方法是在垃圾收集器刪除對(duì)象之前對(duì)這個(gè)對(duì)象調(diào)用的。
2.HashMap和Hashtable的區(qū)別
HashMap與HashTable主要從三方面來說。
一.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進(jìn)的Map接口的一個(gè)實(shí)現(xiàn)
二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的
三.值:只有HashMap可以讓你將空值作為一個(gè)表的條目的key或value
3.Collection 和 Collections的區(qū)別
Collection是集合類的上級(jí)接口,繼承與他的接口主要有Set 和List.
Collections是針對(duì)集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作
4.
public class Hea {
// 定義一個(gè)String沒有給予初始值,默認(rèn)為null
String a ;
int i =3;
// 覆蓋hashCode()方法
public int hashCode() {
return 12;
}
public static void main(String[] args) {
Hea he = new Hea();
// String數(shù)組默認(rèn)為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);
}
}
輸出結(jié)果:
a=null
null
12
3
abc
希望以后能夠?qū)⒆砸褜W(xué)習(xí)JAVA的點(diǎn)點(diǎn)滴滴記錄在這里。。。