在java中DecimalFormat 是表示格式的,例如
double avprice="28234.2534";
java.text.DecimalFormat df =new java.text.DecimalFormat("#.00");
String aveprice=df.format(avprice);
這種寫(xiě)法就是整數(shù)保留不變,后面保留2位小數(shù),不足則補(bǔ)0
在oracle里有時(shí)需要查詢(xún)結(jié)果就保持格式
to_char(col_name,'99999D99')
這表示整數(shù)保持5位,小數(shù)2位,如果把9改成0,就是強(qiáng)制補(bǔ)0
select current_timestamp from dual
select sysdate from dual
select to_date('2005-08-19 12:59:59','yyyy-mm-dd hh24:mi:ss') datevalue from
dual;
select to_char(sysdate,'yyyymmdd') from dual;
sqlserver的有用的日期函數(shù)- -
作者: 日期: 2005-4-12 15:36:05 訪問(wèn)次數(shù):出處:
?顯示選項(xiàng): 自動(dòng)滾屏[左鍵停止]
1.一個(gè)月第一天的
SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)
2.本周的星期一
SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)
3.一年的第一天
SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)
4.季度的第一天
SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)
5.當(dāng)天的半夜
SELECT DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)
6.上個(gè)月的最后一天
SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0))
7.去年的最后一天
SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))
8.本月的最后一天
SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))
9.本年的最后一天
SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))
10.本月的第一個(gè)星期一
select DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,6-datepart(day,getdate()),getdate())), 0)
1.用一條語(yǔ)句得出某日期所在月份的最大天數(shù)?
SELECT DAY(DATEADD(dd, -DAY('2004-02-13'), DATEADD(mm, 1, '2004-02-13'))) AS 'Day Number'
?
在oracle中有很多關(guān)于日期的函數(shù),如:
1、add_months()用于從一個(gè)日期值增加或減少一些月份
date_value:=add_months(date_value,number_of_months)
例:
SQL> select add_months(sysdate,12) "Next Year" from dual;
?
Next Year
----------
13-11月-04
?
SQL> select add_months(sysdate,112) "Last Year" from dual;
?
Last Year
----------
13-3月 -13
?
SQL>?
?
2、current_date()返回當(dāng)前會(huì)放時(shí)區(qū)中的當(dāng)前日期
date_value:=current_date
SQL> column sessiontimezone for a15
SQL> select sessiontimezone,current_date from dual;
?
SESSIONTIMEZONE CURRENT_DA
--------------- ----------
+08:00????????? 13-11月-03
?
SQL> alter session set time_zone='-11:00'
?? 2? /
?
會(huì)話已更改。
?
SQL> select sessiontimezone,current_timestamp from dual;
?
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
-11:00????????? 12-11月-03 04.59.13.668000 下午 -11:
???????????????? 00
?
SQL>?
?
3、current_timestamp()以timestamp with time zone數(shù)據(jù)類(lèi)型返回當(dāng)前會(huì)放時(shí)區(qū)中的當(dāng)前日期
timestamp_with_time_zone_value:=current_timestamp([timestamp_precision])
SQL> column sessiontimezone for a15
SQL> column current_timestamp format a36
SQL> select sessiontimezone,current_timestamp from dual;
?
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
+08:00????????? 13-11月-03 11.56.28.160000 上午 +08:
???????????????? 00
?
SQL> alter session set time_zone='-11:00'
?? 2? /
?
會(huì)話已更改。
?
SQL> select sessiontimezone,current_timestamp from dual;
?
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
-11:00????????? 12-11月-03 04.58.00.243000 下午 -11:
???????????????? 00
?
SQL>?
?
4、dbtimezone()返回時(shí)區(qū)
varchar_value:=dbtimezone
SQL> select dbtimezone from dual;
?
DBTIME
------
-07:00
?
SQL>?
?
5、extract()找出日期或間隔值的字段值
date_value:=extract(date_field from [datetime_value|interval_value])
SQL> select extract(month from sysdate) "This Month" from dual;
?
This Month
----------
???????? 11
?
SQL> select extract(year from add_months(sysdate,36)) "3 Years Out" from dual;
?
3 Years Out
-----------
??????? 2006
?
SQL>?
?
6、last_day()返回包含了日期參數(shù)的月份的最后一天的日期
date_value:=last_day(date_value)
SQL> select last_day(date'2000-02-01') "Leap Yr?" from dual;
?
Leap Yr?
----------
29-2月 -00
?
SQL> select last_day(sysdate) "Last day of this month" from dual;
?
Last day o
----------
30-11月-03
?
SQL>?
?
7、localtimestamp()返回會(huì)話中的日期和時(shí)間
timestamp_value:=localtimestamp
SQL> column localtimestamp format a28
SQL> select localtimestamp from dual;
?
LOCALTIMESTAMP
----------------------------
13-11月-03 12.09.15.433000
下午
?
SQL> select localtimestamp,current_timestamp from dual;
?
LOCALTIMESTAMP?????????????? CURRENT_TIMESTAMP
---------------------------- ------------------------------------
13-11月-03 12.09.31.006000?? 13-11月-03 12.09.31.006000 下午 +08:
下午???????????????????????? 00
?
SQL> alter session set time_zone='-11:00';
?
會(huì)話已更改。
?
SQL> select localtimestamp,to_char(sysdate,'DD-MM-YYYY HH:MI:SS AM') "SYSDATE" from dual;
?
LOCALTIMESTAMP?????????????? SYSDATE
---------------------------- ------------------------
12-11月-03 05.11.31.259000?? 13-11-2003 12:11:31 下午
下午
?
SQL>?
?
8、months_between()判斷兩個(gè)日期之間的月份數(shù)量
number_value:=months_between(date_value,date_value)
SQL> select months_between(sysdate,date'1971-05-18') from dual;
?
MONTHS_BETWEEN(SYSDATE,DATE'1971-05-18')
----------------------------------------
?????????????????????????????? 389.855143
?
SQL> select months_between(sysdate,date'2001-01-01') from dual;
?
MONTHS_BETWEEN(SYSDATE,DATE'2001-01-01')
----------------------------------------
?????????????????????????????? 34.4035409
?
SQL>?
?
9、next_day()給定一個(gè)日期值,返回由第二個(gè)參數(shù)指出的日子第一次出現(xiàn)在的日期值(應(yīng)返回相應(yīng)日子的名稱(chēng)字符串)
Oracle的日期函數(shù)
風(fēng)逝空靈 發(fā)表于 2005-6-21 9:28:46
相信很多人都有過(guò)統(tǒng)計(jì)某些數(shù)據(jù)的經(jīng)歷,比如,要統(tǒng)計(jì)財(cái)務(wù)的情況,可能要按每年,每季度,每月,甚至每個(gè)星期來(lái)分別統(tǒng)計(jì)。那在oracle中應(yīng)該怎么來(lái)寫(xiě)sql語(yǔ)句呢,這個(gè)時(shí)候Oracle的日期函數(shù)會(huì)給我們很多幫助。
?常用日期型函數(shù)
1。Sysdate 當(dāng)前日期和時(shí)間
SQL> Select sysdate from dual;
SYSDATE
----------
21-6月 -05
2。Last_day 本月最后一天
SQL> Select last_day(sysdate) from dual;
LAST_DAY(S
----------
30-6月 -05
3。Add_months(d,n) 當(dāng)前日期d后推n個(gè)月
SQL> Select add_months(sysdate,2) from dual;
ADD_MONTHS
----------
21-8月 -05
4。Months_between(f,s) 日期f和s間相差月數(shù)
SQL> select months_between(sysdate,to_date('2005-11-12','yyyy-mm-dd'))from dual;
MONTHS_BETWEEN(SYSDATE,TO_DATE('2005-11-12','YYYY-MM-DD'))
----------------------------------------------------------
??????????????????????????????????????????????? -4.6966741
5。NEXT_DAY(d, day_of_week)
返回由"day_of_week"命名的,在變量"d"指定的日期之后的第一個(gè)工作日的日期。參數(shù)"day_of_week"必須為該星期中的某一天。
SQL> SELECT next_day(to_date('20050620','YYYYMMDD'),1) FROM dual;
NEXT_DAY(T
----------
26-6月 -05
6。current_date()返回當(dāng)前會(huì)話時(shí)區(qū)中的當(dāng)前日期
SQL> select current_date from dual;
CURRENT_DA
----------
21-6月 -05
7。current_timestamp()以timestamp with time zone數(shù)據(jù)類(lèi)型返回當(dāng)前會(huì)話時(shí)區(qū)中的當(dāng)前日期
SQL> select current_timestamp from dual;
CURRENT_TIMESTAMP
---------------------------------------------------------------------------
21-6月 -05 10.13.08.220589 上午 +08:00
8。dbtimezone()返回時(shí)區(qū)
SQL> select dbtimezone from dual;
DBTIME
------
-08:00
9。extract()找出日期或間隔值的字段值
SQL> select extract(month from sysdate) "This Month" from dual;
This Month
----------
???????? 6
SQL> select extract(year from add_months(sysdate,36)) " Years" from dual;
???? Years
----------
????? 2008
10。localtimestamp()返回會(huì)話中的日期和時(shí)間
SQL> select localtimestamp from dual;
LOCALTIMESTAMP
---------------------------------------------------------------------------
21-6月 -05 10.18.15.855652 上午
常用日期數(shù)據(jù)格式(該段為摘抄)
Y或YY或YYY 年的最后一位,兩位或三位 Select to_char(sysdate,’YYY’) from dual; 002表示2002年
SYEAR或YEAR SYEAR使公元前的年份前加一負(fù)號(hào) Select to_char(sysdate,’SYEAR’) from dual; -1112表示公元前111 2年
Q 季度,1~3月為第一季度 Select to_char(sysdate,’Q’) from dual; 2表示第二季度①
MM 月份數(shù) Select to_char(sysdate,’MM’) from dual; 12表示12月
RM 月份的羅馬表示 Select to_char(sysdate,’RM’) from dual; IV表示4月
Month 用9個(gè)字符長(zhǎng)度表示的月份名 Select to_char(sysdate,’Month’) from dual; May后跟6個(gè)空格表示5月
WW 當(dāng)年第幾周 Select to_char(sysdate,’WW’) from dual; 24表示2002年6月13日為第24周
W 本月第幾周 Select to_char(sysdate,’W’) from dual; 2002年10月1日為第1周
DDD 當(dāng)年第幾, 1月1日為001,2月1日為032 Select to_char(sysdate,’DDD’) from dual; 363 2002年1 2月2 9日為第363天
DD 當(dāng)月第幾天 Select to_char(sysdate,’DD’) from dual; 04 10月4日為第4天
D 周內(nèi)第幾天 Select to_char(sysdate,’D’) from dual; 5 2002年3月14日為星期一
DY 周內(nèi)第幾天縮寫(xiě) Select to_char(sysdate,’DY’) from dual; SUN 2002年3月24日為星期天
HH或HH12 12進(jìn)制小時(shí)數(shù) Select to_char(sysdate,’HH’) from dual; 02 午夜2點(diǎn)過(guò)8分為02
HH24 24小時(shí)制 Select to_char(sysdate,’HH24’) from dual; 14 下午2點(diǎn)08分為14
MI 分鐘數(shù)(0~59) Select to_char(sysdate,’MI’) from dual; 17下午4點(diǎn)17分
SS 秒數(shù)(0~59) Select to_char(sysdate,’SS’) from dual; 22 11點(diǎn)3分22秒
提示注意不要將MM格式用于分鐘(分鐘應(yīng)該使用MI)。MM是用于月份的格式,將它用于分鐘也能工作,但結(jié)果是錯(cuò)誤的。
現(xiàn)在給出一些實(shí)踐后的用法:
1。上月末天:
SQL> select to_char(add_months(last_day(sysdate),-1),'yyyy-MM-dd') LastDay from
dual;
LASTDAY
----------
2005-05-31
2。上月今天
SQL> select to_char(add_months(sysdate,-1),'yyyy-MM-dd') PreToday from dual;
PRETODAY
----------
2005-05-21
3.上月首天
SQL> select to_char(add_months(last_day(sysdate)+1,-2),'yyyy-MM-dd') firstDay from dual;
FIRSTDAY
----------
2005-05-01
4.按照每周進(jìn)行統(tǒng)計(jì)
SQL> select to_char(sysdate,'ww') from dual group by to_char(sysdate,'ww');
TO
--
25
5。按照每月進(jìn)行統(tǒng)計(jì)
SQL> select to_char(sysdate,'mm') from dual group by to_char(sysdate,'mm');
TO
--
06
6。按照每季度進(jìn)行統(tǒng)計(jì)
SQL> select to_char(sysdate,'q') from dual group by to_char(sysdate,'q');
T
-
2
7。按照每年進(jìn)行統(tǒng)計(jì)
SQL> select to_char(sysdate,'yyyy') from dual group by to_char(sysdate,'yyyy');
TO_C
----
2005
到此結(jié)束。
?
閱讀全文(180) | 回復(fù)(1) | 引用通告(0) | 編輯
?
?
回復(fù):Oracle的日期函數(shù)
smilepig(游客)發(fā)表評(píng)論于2005-7-25 13:36:49
?
SQL> select to_char(sysdate,'DAY','NLS_DATE_LANGUAGE=''SIMPLIFIED CHINESE''') fr
om dual;
TO_CHA
------
星期一
?
SQLServer和Oracle是大家經(jīng)常用到的數(shù)據(jù)庫(kù),在此感謝作者總結(jié)出這些常用函數(shù)以供大家參考。
數(shù)學(xué)函數(shù):
1.絕對(duì)值
S:select abs(-1) value
O:select abs(-1) value from dual
2.取整(大)
S:select ceiling(-1.001) value
O:select ceil(-1.001) value from dual
3.取整(?。?
S:select floor(-1.001) value
O:select floor(-1.001) value from dual
4.取整(截?。?
S:select cast(-1.002 as int) value
O:select trunc(-1.002) value from dual
5.四舍五入
S:select round(1.23456,4) value 1.23460
O:select round(1.23456,4) value from dual 1.2346
6.e為底的冪
S:select Exp(1) value 2.7182818284590451
O:select Exp(1) value from dual 2.71828182
7.取e為底的對(duì)數(shù)
S:select log(2.7182818284590451) value 1
O:select ln(2.7182818284590451) value from dual; 1
8.取10為底對(duì)數(shù)
S:select log10(10) value 1
O:select log(10,10) value from dual; 1
9.取平方
S:select SQUARE(4) value 16
O:select power(4,2) value from dual 16
10.取平方根
S:select SQRT(4) value 2
O:select SQRT(4) value from dual 2
11.求任意數(shù)為底的冪
S:select power(3,4) value 81
O:select power(3,4) value from dual 81
12.取隨機(jī)數(shù)
S:select rand() value
O:select sys.dbms_random.value(0,1) value from dual;
13.取符號(hào)
S:select sign(-8) value -1
O:select sign(-8) value from dual -1
14.圓周率
S:SELECT PI() value 3.1415926535897931
O:不知道
15.sin,cos,tan 參數(shù)都以弧度為單位
例如:select sin(PI()/2) value 得到1(SQLServer)
16.Asin,Acos,Atan,Atan2 返回弧度
17.弧度角度互換(SQLServer,Oracle不知道)
DEGREES:弧度-〉角度
RADIANS:角度-〉弧度
數(shù)值間比較:
18. 求集合最大值
S:select max(value) value from
(select 1 value
union
select -2 value
union
select 4 value
union
select 3 value)a
O:select greatest(1,-2,4,3) value from dual
19. 求集合最小值
S:select min(value) value from
(select 1 value
union
select -2 value
union
select 4 value
union
select 3 value)a
O:select least(1,-2,4,3) value from dual
20.如何處理null值(F2中的null以10代替)
S:select F1,IsNull(F2,10) value from Tbl
O:select F1,nvl(F2,10) value from Tbl
21.求字符序號(hào)
S:select ascii('a') value
O:select ascii('a') value from dual
22.從序號(hào)求字符
S:select char(97) value
O:select chr(97) value from dual
23.連接
S:select '11'+'22'+'33' value
O:select CONCAT('11','22') 33 value from dual
23.子串位置 --返回3
S:select CHARINDEX('s','sdsq',2) value
O:select INSTR('sdsq','s',2) value from dual
23.模糊子串的位置 --返回2,參數(shù)去掉中間%則返回7
S:select patindex('%d%q%','sdsfasdqe') value
O:oracle沒(méi)發(fā)現(xiàn),但是instr可以通過(guò)第四個(gè)參數(shù)控制出現(xiàn)次數(shù)
select INSTR('sdsfasdqe','sd',1,2) value from dual 返回6
24.求子串
S:select substring('abcd',2,2) value
O:select substr('abcd',2,2) value from dual
25.子串代替 返回aijklmnef
S:SELECT STUFF('abcdef', 2, 3, 'ijklmn') value
O:SELECT Replace('abcdef', 'bcd', 'ijklmn') value from dual
26.子串全部替換
S:沒(méi)發(fā)現(xiàn)
O:select Translate('fasdbfasegas','fa','我' ) value from dual
27.長(zhǎng)度
S:len,datalength
O:length
28.大小寫(xiě)轉(zhuǎn)換 lower,upper
29.單詞首字母大寫(xiě)
S:沒(méi)發(fā)現(xiàn)
O:select INITCAP('abcd dsaf df') value from dual
30.左補(bǔ)空格(LPAD的第一個(gè)參數(shù)為空格則同space函數(shù))
S:select space(10)+'abcd' value
O:select LPAD('abcd',14) value from dual
31.右補(bǔ)空格(RPAD的第一個(gè)參數(shù)為空格則同space函數(shù))
S:select 'abcd'+space(10) value
O:select RPAD('abcd',14) value from dual
32.刪除空格
S:ltrim,rtrim
O:ltrim,rtrim,trim
33. 重復(fù)字符串
S:select REPLICATE('abcd',2) value
O:沒(méi)發(fā)現(xiàn)
34.發(fā)音相似性比較(這兩個(gè)單詞返回值一樣,發(fā)音相同)
S:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe')
O:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe') from dual
SQLServer中用SELECT DIFFERENCE('Smithers', 'Smythers') 比較soundex的差
返回0-4,4為同音,1最高
日期函數(shù):
35.系統(tǒng)時(shí)間
S:select getdate() value
O:select sysdate value from dual
36.前后幾日
直接與整數(shù)相加減
37.求日期
S:select convert(char(10),getdate(),20) value
O:select trunc(sysdate) value from dual
select to_char(sysdate,'yyyy-mm-dd') value from dual
38.求時(shí)間
S:select convert(char(8),getdate(),108) value
O:select to_char(sysdate,'hh24:mm:ss') value from dual
39.取日期時(shí)間的其他部分
S:DATEPART 和 DATENAME 函數(shù) (第一個(gè)參數(shù)決定)
O:to_char函數(shù) 第二個(gè)參數(shù)決定
參數(shù)---------------------------------下表需要補(bǔ)充
year yy, yyyy
quarter qq, q (季度)
month mm, m (m O無(wú)效)
dayofyear dy, y (O表星期)
day dd, d (d O無(wú)效)
week wk, ww (wk O無(wú)效)
weekday dw (O不清楚)
Hour hh,hh12,hh24 (hh12,hh24 S無(wú)效)
minute mi, n (n O無(wú)效)
second ss, s (s O無(wú)效)
millisecond ms (O無(wú)效)
----------------------------------------------
40.當(dāng)月最后一天
S:不知道
O:select LAST_DAY(sysdate) value from dual
41.本星期的某一天(比如星期日)
S:不知道
O:SELECT Next_day(sysdate,7) vaule FROM DUAL;
42.字符串轉(zhuǎn)時(shí)間
S:可以直接轉(zhuǎn)或者select cast('2004-09-08'as datetime) value
O:SELECT To_date('2004-01-05 22:09:38','yyyy-mm-dd hh24-mi-ss') vaule FROM DUAL;
43.求兩日期某一部分的差(比如秒)
S:select datediff(ss,getdate(),getdate()+12.3) value
O:直接用兩個(gè)日期相減(比如d1-d2=12.3)
SELECT (d1-d2)*24*60*60 vaule FROM DUAL;
44.根據(jù)差值求新的日期(比如分鐘)
S:select dateadd(mi,8,getdate()) value
O:SELECT sysdate+8/60/24 vaule FROM DUAL;
45.求不同時(shí)區(qū)時(shí)間
S:不知道
O:SELECT New_time(sysdate,'ydt','gmt' ) vaule FROM DUAL;
-----時(shí)區(qū)參數(shù),北京在東8區(qū)應(yīng)該是Ydt-------
AST ADT 大西洋標(biāo)準(zhǔn)時(shí)間
BST BDT 白令海標(biāo)準(zhǔn)時(shí)間
CST CDT 中部標(biāo)準(zhǔn)時(shí)間
EST EDT 東部標(biāo)準(zhǔn)時(shí)間
GMT 格林尼治標(biāo)準(zhǔn)時(shí)間
HST HDT 阿拉斯加?夏威夷標(biāo)準(zhǔn)時(shí)間
MST MDT 山區(qū)標(biāo)準(zhǔn)時(shí)間
NST 紐芬蘭標(biāo)準(zhǔn)時(shí)間
PST PDT 太平洋標(biāo)準(zhǔn)時(shí)間
YST YDT YUKON標(biāo)準(zhǔn)時(shí)間
java.text.DecimalFormat df =new java.text.DecimalFormat("#.00");
String aveprice=df.format(avprice);
這種寫(xiě)法就是整數(shù)保留不變,后面保留2位小數(shù),不足則補(bǔ)0
在oracle里有時(shí)需要查詢(xún)結(jié)果就保持格式
to_char(col_name,'99999D99')
這表示整數(shù)保持5位,小數(shù)2位,如果把9改成0,就是強(qiáng)制補(bǔ)0
最近幾天項(xiàng)目剛上線,這幾天估計(jì)不會(huì)有太多的事情。我也想學(xué)點(diǎn)東西,剛好利用這個(gè)時(shí)間學(xué)習(xí)一下JMS,現(xiàn)在就從基礎(chǔ)開(kāi)始學(xué)習(xí)JMS,以下為網(wǎng)上資料轉(zhuǎn)載:
一. JMS簡(jiǎn)介
1. JMS基本概念
JMS(Java Message Service)是訪問(wèn)企業(yè)消息系統(tǒng)的標(biāo)準(zhǔn)API,它便于消息系
統(tǒng)中的Java應(yīng)用程序進(jìn)行消息交換,并且通過(guò)提供標(biāo)準(zhǔn)的產(chǎn)生、發(fā)送、接收消息的接口簡(jiǎn)化企業(yè)應(yīng)用的開(kāi)發(fā)。
2. JMS基本功能
JMS是用于和面向消息的中間件相互通信的應(yīng)用程序接口。它既支持點(diǎn)對(duì)點(diǎn)(point-to-point)的域,又支持發(fā)布/訂閱(publish/subscribe)類(lèi)型的域,并且提供對(duì)下列類(lèi)型的支持:經(jīng)認(rèn)可的消息傳遞,事務(wù)型消息的傳遞,一致性消息和具有持久性的訂閱者支持。JMS還提供了另一種方式來(lái)對(duì)您的應(yīng)用與舊的后臺(tái)系統(tǒng)相集成。
3. WebLogic JMS Server介紹
WebLogic Server8.1符合JAVA規(guī)范,并通過(guò)Sun Microsystems J2EE 1.3認(rèn)
證.作為WebLogic的一部分,當(dāng)然WebLogic JMS Server也完全遵從JMS規(guī)范,還支持集群,并可以應(yīng)用于實(shí)際企業(yè)系統(tǒng).下圖是WebLogic JMS Server體系結(jié)構(gòu).圖中可以看到WebLogic JMS Server主要組件有: WebLogic JMS servers(用于消息通信),Java客戶端,JNDI(用于域名查找), 后備存儲(chǔ)(用于持久消息存儲(chǔ),基于文件或者JDBC數(shù)據(jù)庫(kù)).
二. WebLogic JMS特性
1. 消息通信模型
JMS 支持兩種消息通信模型:點(diǎn)到點(diǎn)(point-to-point)(PTP)模型和發(fā)布/訂閱(Pub/Sub)模型。除了下列不同之外,這兩種消息通信模型非常地相似:
PTP 模型規(guī)定了一個(gè)消息只能有一個(gè)接收者;Pub/Sub 模型允許一個(gè)消息可以有多個(gè)接收者。
2. 消息組成
消息傳遞系統(tǒng)的中心就是消息。
一條 Message 分為三個(gè)組成部分:
頭(header)是個(gè)標(biāo)準(zhǔn)字段集,客戶機(jī)和供應(yīng)商都用它來(lái)標(biāo)識(shí)和路由消息。
屬性(property)支持把可選頭字段添加到消息。如果您的應(yīng)用程序需要不使用標(biāo)準(zhǔn)頭字段對(duì)消息編目和分類(lèi),您就可以添加一個(gè)屬性到消息以實(shí)現(xiàn)這個(gè)編目和分類(lèi)。提供 set<Type>Property(...) 和 get<Type>Property(...) 方法以設(shè)置和獲取各種 Java 類(lèi)型的屬性,包括 Object。JMS 定義了一個(gè)供應(yīng)商選擇提供的標(biāo)準(zhǔn)屬性集。
消息的主體(body)包含要發(fā)送給接收應(yīng)用程序的內(nèi)容。每個(gè)消息接口特定于它所支持的內(nèi)容類(lèi)型。
JMS 為不同類(lèi)型的內(nèi)容提供了它們各自的消息類(lèi)型,但是所有消息都派生自 Message 接口。
StreamMessage:包含 Java 基本數(shù)值流,用標(biāo)準(zhǔn)流操作來(lái)順序的填充和讀取。
MapMessage:包含一組名/值對(duì);名稱(chēng)為 string 類(lèi)型,而值為 Java 的基本類(lèi)型。
TextMessage:包含一個(gè) String。
ObjectMessage:包含一個(gè) Serializable Java 對(duì)象;能使用 JDK 的集合類(lèi)。
BytesMessage:包含未解釋字節(jié)流: 編碼主體以匹配現(xiàn)存的消息格式。
XMLMessage: 包含XML內(nèi)容。擴(kuò)展TextMessage,XMLMessage 類(lèi)型的使用,使得消息過(guò)濾非常便利。
3. 消息確認(rèn)模式
非事務(wù)性會(huì)話中,應(yīng)用程序創(chuàng)建的會(huì)話有5 種確認(rèn)模式,而在事務(wù)性會(huì)話中,確認(rèn)模式被忽略。
五種確認(rèn)模式說(shuō)明:
AUTO_ACKNOWLEDGE:自動(dòng)確認(rèn)模式。一旦接收方應(yīng)用程序的方法調(diào)用從處理消息處返回,會(huì)話對(duì)象就會(huì)確認(rèn)消息的接收。
CLIENT_ACKNOWLEDGE:客戶端確認(rèn)模式。會(huì)話對(duì)象依賴(lài)于應(yīng)用程序?qū)Ρ唤邮盏南⒄{(diào)用一個(gè)acknowledge()方法。一旦這個(gè)方法被調(diào)用,會(huì)話會(huì)確認(rèn)最后一次確認(rèn)之后所有接收到的消息。這種模式允許應(yīng)用程序以一個(gè)調(diào)用來(lái)接收,處理并確認(rèn)一批消息。注意:在管理控制臺(tái)中,如果連接工廠的Acknowledge Policy(確認(rèn)方針)屬性被設(shè)置為"Previous"(提前),但是你希望為一個(gè)給定的會(huì)話確認(rèn)所有接收到的消息,那么就用最后一條消息來(lái)調(diào)用acknowledge()方法。
DUPS_OK_ACKNOWLEDGE:允許副本的確認(rèn)模式。一旦接收方應(yīng)用程序的方法調(diào)用從處理消息處返回,會(huì)話對(duì)象就會(huì)確認(rèn)消息的接收;而且允許重復(fù)確認(rèn)。在需要考慮資源使用時(shí),這種模式非常有效。注意:如果你的應(yīng)用程序無(wú)法處理重復(fù)的消息的話,你應(yīng)該避免使用這種模式。如果發(fā)送消息的初始化嘗試失敗,那么重復(fù)的消息可以被重新發(fā)送。
NO_ACKNOWLEDGE:不確認(rèn)模式。不確認(rèn)收到的消息是需要的。消息發(fā)送給一個(gè)NO_ACKNOWLEDGE 會(huì)話后,它們會(huì)被WebLogic 服務(wù)器立即刪除。在這種模式下,將無(wú)法重新獲得已接收的消息,而且可能導(dǎo)致下面的結(jié)果:1. 消息可能丟失;和(或者)另一種情況:2. 如果發(fā)送消息的初始化嘗試失敗,會(huì)出現(xiàn)重復(fù)消息被發(fā)送的情況。
MULTICAST_NO_ACKNOWLEDGE:IP組播下的不確認(rèn)模式,同樣無(wú)需確認(rèn)。發(fā)送給一個(gè)MULTICAST_NO_ACKNOWLEDGE會(huì)話的消息, 會(huì)共享之前所述的NO_ACKNOWLEDGE 確認(rèn)模式一樣的特征。這種模式支持希望通過(guò)IP 組播方式進(jìn)行消息通信的應(yīng)用程序,而且無(wú)需依賴(lài)會(huì)話確認(rèn)提供的服務(wù)質(zhì)量。注意:如果你的應(yīng)用程序無(wú)法處理消息的丟失或者重復(fù),那么你應(yīng)該避免使用這種模式。如果發(fā)送消息的初始化嘗試失敗的話,重復(fù)的消息可能會(huì)被再次發(fā)送。
注:在上表的5 種確認(rèn)模式中,AUTO_ACKNOWLEDGE ,DUPS_OK_ACKNOWLEDGE 和
CLIENT_ACKNOWLEDGE 是JMS 規(guī)范定義的,NO_ACKNOWLEDGE 和MULTICAST_NO_ACKNOWLEDGE是WebLogic JMS 提供的。
三. 配置JMS
1. 創(chuàng)建連接工廠
(1) 啟動(dòng)WebLogic Server8.1,登錄控制臺(tái),選中JMS Connection Factories節(jié)點(diǎn),點(diǎn)擊右邊的" Configure a new JMS Connection Factory...";
(2) 填寫(xiě)連接工廠的名稱(chēng)SendJMSFactory和JNDI名稱(chēng)SendJMSFactory,點(diǎn)擊"Create";
(3) 勾上"myserver",將SendJMSFactory應(yīng)用到myserver;
2. 定義后備存儲(chǔ)
(1) 選中JMS Stores節(jié)點(diǎn),點(diǎn)擊右邊的" Configure a new JMS Connection Factory...";
(2) 填寫(xiě)文件后備存儲(chǔ)的名稱(chēng)SendFileStore和目錄Directionary E:\BEA\user_projects\domains\mydomain\sendfilestore,點(diǎn)擊"Create".
3. 創(chuàng)建JMS服務(wù)器
(1) 選中JMS Servers節(jié)點(diǎn),點(diǎn)擊右邊的" Configure a new JMSServer...";
(2) 填寫(xiě)JMS服務(wù)器的名稱(chēng)SendJMSServer和Paging Store設(shè)為" SendFileStore",點(diǎn)擊"Create";
(3) Target選中"myserver",將SendJMSServer應(yīng)用到myserver.
4. 創(chuàng)建消息隊(duì)列
(1) 展開(kāi)"SendJMSServer"節(jié)點(diǎn),點(diǎn)擊" Configure a new JMS Queue...";
(2) 填寫(xiě)消息隊(duì)列的名稱(chēng)SendJMSQueue和JNDI名稱(chēng)SendJMSQueue,點(diǎn)擊"Create";
四. JMS應(yīng)用程序
一個(gè) JMS 應(yīng)用程序由下列元素組成:
JMS 客戶機(jī)。 用 JMS API 發(fā)送和接收消息的 Java 程序。
非 JMS(Non-JMS)客戶機(jī)。 認(rèn)識(shí)到這一點(diǎn)很重要 - 舊的程序經(jīng)常成為整個(gè) JMS 應(yīng)用程序的一部分,而且它們的包含應(yīng)該在設(shè)計(jì)時(shí)預(yù)先考慮。
消息。 在 JMS 和非 JMS 客戶機(jī)之間交換的消息的格式和內(nèi)容是 JMS 應(yīng)用程序設(shè)計(jì)所必須考慮的部分。
JMS 供應(yīng)商。供應(yīng)商必須提供特定于其 MOM 產(chǎn)品的具體的實(shí)現(xiàn)。
受管對(duì)象。 消息傳遞系統(tǒng)供應(yīng)商的管理員創(chuàng)建了一個(gè)對(duì)象,它獨(dú)立于供應(yīng)商專(zhuān)有的技術(shù)。包括連接工廠ConnectionFactory和目的Destination。
一種典型的 JMS 程序需要經(jīng)過(guò)下列步驟才能開(kāi)始消息產(chǎn)生和使用:
通過(guò) JNDI 查找 ConnectionFactory。
通過(guò) JNDI 查找一個(gè)或多個(gè) Destination。
用 ConnectionFactory 創(chuàng)建一個(gè) Connection。
用 Connection 創(chuàng)建一個(gè)或多個(gè) Session。
用 Session 和 Destination 創(chuàng)建所需的 MessageProducer 和 MessageConsumer。
啟動(dòng) Connection。
下面利用上面配置的JMS資源演示點(diǎn)對(duì)點(diǎn)消息發(fā)送和接收的過(guò)程。
五. 設(shè)計(jì)消息發(fā)送端
1. 使用的JMS資源
服務(wù)器URL: t3://localhost:80
連接工廠: SendJMSFactory
隊(duì)列: SendJMSQueue
2. 設(shè)計(jì)步驟
初始化JNDI Tree
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
return new InitialContext(env);
lookup ConnectionFactory
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
lookup Destination
queue = (Queue) ctx.lookup(queueName);
用 ConnectionFactory 創(chuàng)建Connection
qcon = qconFactory.createQueueConnection();
用 Connection 創(chuàng)建一個(gè)Session
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
用 Session 和 Destination 創(chuàng)建MessageProducer
qsender = qsession.createSender(queue);
啟動(dòng) Connection。
qcon.start();
發(fā)送消息
msg = qsession.createTextMessage();
msg.setText(message);
qsender.send(msg);
3. 源代碼
package jmssample;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/** This example shows how to establish a connection
* and send messages to the JMS queue. The classes in this
* package operate on the same JMS queue. Run the classes together to
* witness messages being sent and received, and to browse the queue
* for messages. The class is used to send messages to the queue.
*
* @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
*/
public class QueueSend
{
// Defines the JNDI context factory.
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
// Defines the JNDI provider url.
public final static String PROVIDER_URL=" t3://localhost:80";
// Defines the JMS connection factory for the queue.
public final static String JMS_FACTORY="SendJMSFactory";
// Defines the queue.
public final static String QUEUE="SendJMSQueue";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;
/**
* Creates all the necessary objects for sending
* messages to a JMS queue.
*
* @param ctx JNDI initial context
* @param queueName name of queue
* @exception NamingException if operation cannot be performed
* @exception JMSException if JMS fails to initialize due to internal error
*/
public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
}
/**
* Sends a message to a JMS queue.
*
* @param message message to be sent
* @exception JMSException if JMS fails to send message due to internal error
*/
public void send(String message) throws JMSException {
msg.setText(message);
qsender.send(msg);
}
/**
* Closes JMS objects.
* @exception JMSException if JMS fails to close objects due to internal error
*/
public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}
/** main() method.
*
* @param args WebLogic Server URL
* @exception Exception if operation fails
*/
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
QueueSend qs = new QueueSend();
qs.init(ic, QUEUE);
readAndSend(qs);
qs.close();
}
private static void readAndSend(QueueSend qs)
throws IOException, JMSException
{
BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
String line=null;
boolean quitNow = false;
do {
System.out.print("Enter message (\"quit\" to quit): ");
line = msgStream.readLine();
if (line != null && line.trim().length() != 0) {
qs.send(line);
System.out.println("JMS Message Sent: "+line+"\n");
quitNow = line.equalsIgnoreCase("quit");
}
} while (! quitNow);
}
private static InitialContext getInitialContext()
throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
return new InitialContext(env);
}
}
六. 設(shè)計(jì)消息接收端
1. 使用的JMS資源
服務(wù)器URL: t3://localhost:80
連接工廠: SendJMSFactory
隊(duì)列: SendJMSQueue
2. 設(shè)計(jì)步驟
初始化JNDI Tree
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
return new InitialContext(env);
lookup ConnectionFactory
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
lookup Destination
queue = (Queue) ctx.lookup(queueName);
用 ConnectionFactory 創(chuàng)建Connection
qcon = qconFactory.createQueueConnection();
用 Connection 創(chuàng)建一個(gè)Session
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
用 Session 和 Destination 創(chuàng)建MessageConsumer
qreceiver = qsession.createReceiver(queue);
設(shè)置監(jiān)聽(tīng)
qreceiver.setMessageListener(this);
啟動(dòng) Connection
qcon.start();
3. 源代碼
package jmssample;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* This example shows how to establish a connection to
* and receive messages from a JMS queue. The classes in this
* package operate on the same JMS queue. Run the classes together to
* witness messages being sent and received, and to browse the queue
* for messages. This class is used to receive and remove messages
* from the queue.
*
* @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
*/
public class QueueReceive implements MessageListener
{
// Defines the JNDI context factory.
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
// Defines the JNDI provider url.
public final static String PROVIDER_URL=" t3://localhost:80";
// Defines the JMS connection factory for the queue.
public final static String JMS_FACTORY="SendJMSFactory";
// Defines the queue.
public final static String QUEUE="SendJMSQueue";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private Queue queue;
private boolean quit = false;
/**
* Message listener interface.
* @param msg message
*/
public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage)msg).getText();
} else {
msgText = msg.toString();
}
System.out.println("Message Received: "+ msgText );
if (msgText.equalsIgnoreCase("quit")) {
synchronized(this) {
quit = true;
this.notifyAll(); // Notify main thread to quit
}
}
} catch (JMSException jmse) {
jmse.printStackTrace();
}
}
/**
* Creates all the necessary objects for receiving
* messages from a JMS queue.
*
* @param ctx JNDI initial context
* @param queueName name of queue
* @exception NamingException if operation cannot be performed
* @exception JMSException if JMS fails to initialize due to internal error
*/
public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qcon.start();
}
/**
* Closes JMS objects.
* @exception JMSException if JMS fails to close objects due to internal error
*/
public void close()throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}
/**
* main() method.
*
* @param args WebLogic Server URL
* @exception Exception if execution fails
*/
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
QueueReceive qr = new QueueReceive();
qr.init(ic, QUEUE);
System.out.println("JMS Ready To Receive Messages (To quit, send a \"quit\" message).");
// Wait until a "quit" message has been received.
synchronized(qr) {
while (! qr.quit) {
try {
qr.wait();
} catch (InterruptedException ie) {}
}
}
qr.close();
}
private static InitialContext getInitialContext()
throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
return new InitialContext(env);
}
}
七. 測(cè)試消息發(fā)送和接收
1. 設(shè)置WebLogic Classpath;
2. 轉(zhuǎn)到發(fā)送接收程序目錄編譯文件;
3. 執(zhí)行接受程序;
4. 打開(kāi)另一窗口,執(zhí)行發(fā)送程序;
5. 輸入發(fā)送消息"quit",接收程序結(jié)束.