首先給出一段XML格式文本信息:
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
??? <book>
??????? <title lang="eng">Harry Potter</title>
<price>29.99</price>
??? </book>
??? <book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
??? </book>
</bookstore>
表達式???? 描述
節點名???? 選擇所有該名稱的節點集
/????????????? 選擇根節點
//???????????? 選擇當前節點下的所有節點
.????????????? 選擇當前節點
..???????????? 選擇父節點
@??????????? 選擇屬性
示例
表達式????????????????? 描述
bookstore???????????? 選擇所有bookstore子節點
/bookstore??????????? 選擇根節點bookstore
bookstore/book??? 在bookstore的子節點中選擇所有名為book的節點
//book?????????????????? 選擇xml文檔中所有名為book的節點
bookstore//book?? 選擇節點bookstore下的所有名為book為節點
//@lang???????????????? 選擇所有名為lang的屬性
斷言
在方括號中[],用來更進一步定位選擇的元素
表達式???????????????????????????????????????????? 描述
/bookstore/book[1]????????????????????????? 選擇根元素bookstore的book子元素中的第一個(注意: IE5以上瀏覽器中第一個元素是0)
/bookstore/book[last()]??????????????????? 選擇根元素bookstore的book子元素中的最后一個
/bookstore/book[last()-1]???????????????? 選擇根元素bookstore的book子元素中的最后第二個
/bookstore/book[position()<3]???????? 選擇根元素bookstore的book子元素中的前兩個
//title[@lang]??????????????????????????????????? 選擇所有擁有屬性lang的titile元素
//title[@lang='eng']????????????????????????? 選擇所有屬性值lang為eng的title元素
/bookstore/book[price>35.00]???????? 選擇根元素bookstore的book子元素中那些擁有price子元素且值大于35的
/bookstore/book[price>35.00]/title?? 選擇根元素bookstore的book子元素中那些擁有price子元素且值大于35的title子元素
選擇位置的節點
通配符????? 描述
*??????????????? 匹配所有元素
@*???????????? 匹配所有屬性節點
node()?????? 匹配任何類型的節點
示例
表達式??????????????????? 描述
/bookstore/*??????????? 選擇根元素bookstore的下的所有子元素
//*??????????????????????????? 選擇文檔中所有元素
//title[@*]???????????????? 選擇所有擁有屬性的title元素
使用操作符“|”組合選擇符合多個path的表達式
posted @
2009-11-02 20:55 jadmin 閱讀(122) |
評論 (0) |
編輯 收藏
一個后臺應用程序,使用了Spring+iBatis框架。
有這樣的需求,要求程序啟動后,要一直駐留內存,而不能因為出現數據庫連接失效、“閃動”、或者網線斷了而掛起,因為沒有人值守程序,并且當網絡故障、數據庫故障、配置參數等故障排除后,程序能根據修復的新狀態繼續執行。
實現方式:以前使用Linux操作系統的shell腳本定時檢測,但是俺不會寫shell腳本。
于是有了下面的實現方式:
????????public static voidmain(String[] args) {
????????????????while(true) {
????????????????????????try{
???????????????????????????????? ctx = ApplicationContextUtil.getApplicationContext();
???????????????????????????????? IssuePlan issuePlan = (IssuePlan) ctx.getBean("issuePlan");
???????????????????????????????? issuePlan.execute();
???????????????????????? }catch(Throwable e) {
???????????????????????????????? log.error("網絡視頻節目分發程序啟動發生了嚴重錯誤!", e);
????????????????????????????????try{
???????????????????????????????????????? Thread.sleep(pause_timespan * 1000L);
???????????????????????????????? }catch(InterruptedException e1) {
???????????????????????????????? }
???????????????????????? }
???????????????? }
???????? }
這種方式運行良好,每次因為嚴重錯誤都會重新初始化Spring的ApplicationContext。這樣,整個程序的運行就是:一直執行任務,有任務就執行,沒任務休息一段時間,有錯誤等待一段時間重試,沒錯誤繼續。
issuePlan.execute(); 是核心的后臺任務執行者,這個方法在正常情況下是不會退出的,寫法是while(true)邏輯,只有當發生一些嚴重錯誤會導致此方法發生異常退出。
?
posted @
2009-10-01 16:05 jadmin 閱讀(148) |
評論 (0) |
編輯 收藏
Ehcache緩存回收策略
posted @
2009-09-05 00:33 jadmin 閱讀(135) |
評論 (0) |
編輯 收藏
1.Cache Hit and Cache Miss
當使用者第一次向數據庫發出查詢數據的請求的時候,數據庫會先在緩沖區中查找該數據,如果要訪問的數據恰好已經在緩沖區中(我們稱之為Cache Hit)那么就直接用緩沖區中讀取該數據.
反之如果緩沖區中沒有使用者要查詢的數據那么這種情況稱之為Cache Miss,在這種情況下數據庫就會先從磁盤上讀取使用者要的數據放入緩沖區,使用者再從緩沖區讀取該數據.
很顯然從感覺上來說Cache Hit會比Cache Miss時存取速度快.
2. LRU(最近最少使用算法) and MRU(最近最常使用算法)
所謂的LRU(Least recently used)算法的基本概念是:當內存的剩余的可用空間不夠時,緩沖區盡可能的先保留使用者最常使用的數據,換句話說就是優先清除”較不常使用的數據”,并釋放其空間.之所以”較不常使用的數據”要用引號是因為這里判斷所謂的較不常使用的標準是人為的、不嚴格的.所謂的MRU(Most recently used)算法的意義正好和LRU算法相反.
下面我們通過Oracle 9i Cache中對LRU和MRU的使用來看一下兩者在緩沖區工作機制中的作用和區別:
???? 在Oracle 9i中有LRU List的概念: 我們可以把LRU List想象成是一連串的緩沖區集合,兩端分別是LRU端和MRU端, 當數據庫從磁盤上讀取數據放入緩沖區時,系統必須先確定緩沖區中有free buffers,這個時候Oracle 9i會掃描LRU List,掃描的基本原則是:
1.???? 從LRU端到MRU端;
2.???? 當掃描到free buffer或已掃描的緩沖區數目超過臨界值時,就會停止掃描動作;
????? 如果在掃描過程順利的在LRU List中找到了free buffer,那么Oracle 9i就把從磁盤讀出的數據寫到free buffer中然后把free buffer加到LRU List的MRU端.
????? 那如果掃描過程沒有在LRU List中找到free buffer怎么辦?當然是從LRU List的LRU端開始清除緩沖區,如此一來就可以騰出新的空間了.
????? 下圖就是一個例子:
????????? 使用者查詢數據A,初始的時候LRU List中沒有數據A,于是Oracle 9i到磁盤讀取A,然后放到LRU List的MRU端,使用者再從LRU List中讀取數據A,同理對于B,C…當LRU List滿了以后,如果使用者查詢N,此時N不在LRU List中而且LRU List中已經沒有free buffer了,此時Oracle 9i就開始從LRU端淘汰A以騰出空間存放N.
????????????????????? 圖 1
我們再來看另外一種情況:
??? 在State 3之后,恰好使用者持續的查詢A—這將會導致A一直被放置在靠近MRU端的緩沖區,結果將如圖State m’所示,你會發現圖2的State m’與圖1的State m緩沖區存放的數據完全一樣但是存放位置不一樣.此時LRU List滿了,如果再放N的時候LRU List`淘汰的是B,因為A的查詢率高于B,所以LRU List讓A在緩沖區中呆上較長的時間而先淘汰掉”較不常用的”的B.
???????????????????????????? 圖 2
posted @
2009-09-05 00:27 jadmin 閱讀(160) |
評論 (0) |
編輯 收藏
[A] 每次讀入的字節數不同
[B] 前者帶有緩沖,后者沒有
[C] 前者是塊讀寫,后者是字節讀寫
[D] 二者沒有區別,可以互換使用
結果:[C]
posted @
2009-09-03 21:29 jadmin 閱讀(808) |
評論 (0) |
編輯 收藏
比如現在有一人員表(表名:peosons) 若想將姓名、身份證號、住址這三個字段完全相同的記錄查詢出來
select p1.* from persons p1,persons p2
where p1.idp2.id and p1.cardid = p2.cardid and p1.pname = p2.pname and p1.address = p2.address 可以實現上述效果.
幾個刪除重復記錄的SQL語句
1.用rowid方法
2.用group by方法
3.用distinct方法
1.用rowid方法
據據oracle帶的rowid屬性,進行判斷,是否存在重復,語句如下:
查數據:
???? select * from table1 a where rowid !=(select?? max(rowid)
???? from table1 b where a.name1=b.name1 and a.name2=b.name2......)
刪數據:
??? delete?? from table1 a where rowid !=(select?? max(rowid)
???? from table1 b where a.name1=b.name1 and a.name2=b.name2......)
2.group by方法
查數據:
select count(num), max(name) from student --列出重復的記錄數,并列出他的name屬性
group by num
having count(num) >1 --按num分組后找出表中num列重復,即出現次數大于一次
刪數據:
delete from student
group by num
having count(num) >1
這樣的話就把所有重復的都刪除了。
3.用distinct方法 -對于小的表比較有用
create table table_new as?? select distinct *?? from table1 minux
truncate table table1;
insert into table1 select * from table_new;
查詢及刪除重復記錄的方法大全
1、查找表中多余的重復記錄,重復記錄是根據單個字段(peopleId)來判斷
select * from people
where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)
2、刪除表中多余的重復記錄,重復記錄是根據單個字段(peopleId)來判斷,只留有rowid最小的記錄
delete from people
where peopleId in (select peopleId from people group by peopleId?? having count(peopleId) > 1)
and rowid not in (select min(rowid) from people group by peopleId having count(peopleId )>1)
3、查找表中多余的重復記錄(多個字段)
select * from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
4、刪除表中多余的重復記錄(多個字段),只留有rowid最小的記錄
delete from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)
5、查找表中多余的重復記錄(多個字段),不包含rowid最小的記錄
select * from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)
(二)
比方說
在A表中存在一個字段“name”,
而且不同記錄之間的“name”值有可能會相同,
現在就是需要查詢出在該表中的各記錄之間,“name”值存在重復的項;
Select Name,Count(*) From A Group By Name Having Count(*) > 1
如果還查性別也相同大則如下:
Select Name,sex,Count(*) From A Group By Name,sex Having Count(*) > 1
(三)
方法一
declare @max integer,@id integer
declare cur_rows cursor local for select 主字段,count(*) from 表名 group by 主字段 having count(*) >; 1
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
delete from 表名 where 主字段 = @id
fetch cur_rows into @id,@max
end
close cur_rows
set rowcount 0
方法二
"重復記錄"有兩個意義上的重復記錄,一是完全重復的記錄,也即所有字段均重復的記錄,二是部分關鍵字段重復的記錄,比如Name字段重復,而其他字段不一定
重復或都重復可以忽略。
1、對于第一種重復,比較容易解決,使用
select distinct * from tableName
就可以得到無重復記錄的結果集。
如果該表需要刪除重復的記錄(重復記錄保留1條),可以按以下方法刪除
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
發生這種重復的原因是表設計不周產生的,增加唯一索引列即可解決。
2、這類重復問題通常要求保留重復記錄中的第一條記錄,操作方法如下
假設有重復的字段為Name,Address,要求得到這兩個字段唯一的結果集
select identity(int,1,1) as autoID, * into #Tmp from tableName
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID
select * from #Tmp where autoID in(select autoID from #tmp2)
最后一個select即得到了Name,Address不重復的結果集(但多了一個autoID字段,實際寫時可以寫在select子句中省去此列)
(四)
查詢重復
select * from tablename where id in (
select id from tablename
group by id
having count(id) > 1
)
posted @
2009-09-03 16:50 jadmin 閱讀(160) |
評論 (0) |
編輯 收藏
原題如下:用1、2、2、3、4、5這六個數字,用java寫一個程序,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"與"5"不能相連。
解題思路:
很明顯,這是一個遞歸算法。我們可以排列將這6個數按從小到大的順序排一下,如果是1,2,3,4,5,6,那么會有1*2*3*4*5*6=6!=720個遞增的數。但如果是1,2,2,3,4,5,那么在這720個數中一定會有相同的數對出現(由于在這6個數中只有兩個數兩同,也就是說,如果有重復的數,那么一定是一對數,如122345會出現兩次)。
排列的基本規則是分步進行。也就是說,要排列上面6個數,首先應該選擇第一個數,這第一個數可以選擇這6個數中的任意一個,如選擇1.第二步是選擇第二個數,這第二個數不能再選擇已經選過的數,如1.因此,它只能從后面5個數中選擇。如選擇2。以此類推。
我們也可以在程序中模擬這一過程。源程序如下:
public class test1 {
???? private int[] numbers = new int[] { 1, 2, 3, 3, 4, 5 };
???? public int n;
???? private String lastResult = "";
???? private boolean validate(String s) {
????????? if (s.compareTo(lastResult) <= 0)
?????????????? return false;
????????? if (s.charAt(2) == '4')
?????????????? return false;
????????? if (s.indexOf("35") >= 0 || s.indexOf("53") >= 0)
?????????????? return false;
????????? return true;
???? }
???? public void list(String index, String result) {
????????? for (int i = 0; i < numbers.length; i++) {
?????????????? if (index.indexOf(i + 48) < 0) {
????????????????????? String s = result + String.valueOf(numbers[i]);
????????????????????? if (s.length() == numbers.length) {
?????????????????????????? if (validate(s)) {
??????????????????????????????? System.out.println(s);
??????????????????????????????? lastResult = s;
??????????????????????????????? n++;
?????????????????????????? }
????????????????????????? break;
????????????????????? }
????????????????????? list(index + String.valueOf(i), s);
?????????????? }
????????? }
???? }
???? public static void main(String[] args) {
????????? test1 t = new test1();
????????? t.list("", "");
????????? System.out.println("總數:" + t.n);
???? }
}
其中list函數是這個算法的核心函數。index參數表示已經選擇過的數,用numbers數組的索引表示。如index="012",表示numbers的前三個數已經被選擇,也表示應該選擇第四個數了,而這第四個數應該從后三個數中選擇。result參數表示臨時的數字組合(這個數字組合最多是5個數字,因為,如果到了6個數字,就表示已經有一個結果產生了)。在默認情況下index和result的值都是""。
在validate中使用了 if (s.compareTo(lastResult) <= 0)進行判斷,由于按這種方法進行排列,如果這6個數是遞增給出的,那么排列的結果一定是遞增的,但上述的6個數其中第2和第3個位置上都是2,因此,如果出現了上一個結果不小于當前結果的情況,一定是有重復了,因此,要將這部分數過濾出去。
使用1, 2, 2, 3, 4, 5的測試結果
122345
122543
123245
123254
123425
123452
125234
125243
125423
125432
132245
132254
132425
132452
132524
132542
142325
... ...
... ...
542313
542331
543123
543132
543213
543231
543312
543321
總數:118
使用1, 3, 3, 3, 4, 5的測試結果
133345
313345
315433
331345
331543
333145
333154
333415
333451
343315
345133
433315
451333
513334
513343
513433
541333
543133
543313
543331
總數:20
posted @
2009-09-03 01:39 jadmin 閱讀(95) |
評論 (0) |
編輯 收藏
作用域將對Bean的生命周期和創建方式產生影響.
singleton??????????? 在spring IOC容器中僅存在一個Bean實例,Bean以單實例的方式存在.
prototype??????????? 每次從容器中調用Bean時,都返回一個新的實例,即每次調用getBean()時,相當于執行new XxxBean()的操作.
request?????????????? 每次HTTP請求都會創建一個新的Bean,該作用域僅適用于webApplicationContext環境.
session?????????????? 同一個HTTP session共享一個Bean,不同HTTP session使用不同的Bean,該作用域僅適用于webApplicationContext環境.
globalSession?? 同一個全局session共享一個Bean,一般用于portlet應用環境,該作用域僅適用于webApplicationContext環境.
在低版本的spring中,由于只有兩個Bean作用域,所以采用singleton="true|false"的配置方式,spring2.0為了向后兼容,依舊支持這種配置方式.不過,spring2.0推薦采用新的配置方式:scope="<作用域類型>"
-------------------------------------------------
singleton作用域
spring以容器的方式提供天然的單實例模式功能,任何POJO無須編寫特殊的代碼僅通過配置就可以了.
注意:spring將Bean的默認作用域定為singleton.
singleton例:
<bean id="car" class="com.baobaotao.scope.Car" scope="singleton"/>
<bean id="boss1" class="com.baobaotao.scope.Boss">
<property name="car" ref="car"/>
</bean>
Car Bean聲明為singleton(因為默認是singleton,所以可以不顯式指定).
在默認情況下,spring的ApplicationContext容器在啟動時,自動實例化所有singleton的Bean并緩存于容器中.
雖然啟動時會花費一些時間,但帶來兩個好處:首先對Bean提前的實例化操作會及早發現一些潛在的配置問題.
其次Bean以緩存的方式保存,當運行時使用到該Bean時就無須再實例化了,加快了運行效率.如果用戶不希望在容
器啟動時提前實例化singleton的Bean,可以通過lazy-init屬性進行控制:
<bean id="boos1" class="com.baobaotao.scope.Boss" lazy-init="true">
<property name="car" ref="car"/>
</bean>
lazy-init="true"的Bean在某些情況下依舊會提前實例化:如果該Bean被其它需要提前實例化的Bean引用到,
spring也將忽略延遲實例化的設置.
-------------------------------------------------
prototype作用域
采用scope="prototype"指定非單實例作用域Bean,請看:
<bean id="car" class="com.baobaotao.scope.Car" scope="prototype"/>
<bean id="boss1" class="com.baobaotao.scope.Boss">
<property name="car" ref="car"/>
</bean>
<bean id="boss2" class="com.baobaotao.scope.Boss">
<property name="car" ref="car"/>
</bean>
boss1,boss2所引用的都是一個獨立的Car實例.
在默認情況下,spring容器在啟動時不實例化prototype的Bean.此外,spring容器將prototype的Bean交給調用
者后,就不再管理它的生命周期.
-------------------------------------------------
web應用環境相關的Bean作用域
如果用戶使用spring的webApplicationContext,則可以使用另外3種Bean的作用域:request,session和globalSession.不過
在使用這些作用域之前,首先必須在web容器中進行一些額外的配置,在高版本的web容器中,則可以利用HTTP請求監聽器進行配置:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
細心的朋友可能有一個疑問:在介紹webApplicationContext初始化時,我們已經通過ContextLoaderListener將web容器與
spring容器整合,為什么這里又要引入一個額外的RequestContextListener以支持Bean的另外3個作用域呢?
在整合spring容器時使用ContextLoaderListener,它實現了ServletContextListener監聽器接口,ServletContextListener
只負責監聽web容器啟動和關閉的事件.而RequestContextListener實現ServletRequestListener監聽器接口,該監聽器監聽
HTTP請求事件,web服務器接收的每一次請求都會通知該監聽器.
spring容器啟動和關閉操作由web容器的啟動和關閉事件觸發,但如果spring容器中的Bean需要request,session,globalsession
作用域的支持,spring容器本身就必須獲得web容器的HTTP請求事件,以HTTP請求的事件"驅動"Bean作用域的控制邏輯.
request作用域
顧名思義,request作用域的Bean對應一個HTTP請求和生命周期,考慮下面的配置:
<bean name="car" class="com.baobaotao.scope.Car" scope="request"/>
這樣,每次HTTP請求調用到car Bean時,spring容器創建一個新的Car Bean,請求處理完畢后,銷毀這個Bean.
session作用域
假設將以上car的作用域調整為session類型:
<bean name="car" class="com.baobaotao.scope.Car" scope="session"/>
這樣配置后,car Bean的作用域橫跨整個HTTP session,session中所有HTTP請求都共享同一個Car Bean,當HTTP Session結束后,實例
才被銷毀.
globalSession作用域
下面的配置片斷將car的作用域設置為了globalSession:
<bean name="loginController" class="com.baobaotao.scope.Car" scope="globalSession"/>
globalSession作用域類似于session作用域,不過僅在portlet的web應用中使用.Portlet規范定義了全局Session概念,它被組成portlet
web應用的所有子portlet共享.如果不在Portlet web應用環境下,globalSession自然等價于session作有域了.
posted @
2009-08-31 14:48 jadmin 閱讀(144) |
評論 (0) |
編輯 收藏
如
15 = 15
15 = 7 + 8
15 = 4 + 5 + 6
15 = 1 + 2 + 3 + 4 + 5
首先考慮一般的形式,設n為被劃分的正整數,x為劃分后最小的整數,如果n有一種劃分,那么
結果就是x,如果有兩種劃分,就是x和x x + 1, 如果有m種劃分,就是 x 、x x + 1 、 x x + 1 x + 2 、... 、x x + 1 x + 2 ... x + m - 1
將每一個結果相加得到一個公式(i * x + i * (i - 1) / 2) = n,i為當前劃分后相加的正整數個數。
滿足條件的劃分就是使x為正整數的所有情況。
如上例,當i = 1時,即劃分成一個正整數時,x = 15, 當i = 2時, x = 7。
當x = 3時,x = 4, 當x = 4時,4/9,不是正整數,因此,15不可能劃分成4個正整數相加。
當x = 5時,x = 1。
Java代碼
public static int split(int n) {
?? int m = 0, x, t1, t2;
?? for (int i = 1; (t1 = i * (i - 1) / 2) < n; i++) {
??? t2 = (n - t1);
??? x = t2 / i;
??? if (x <= 0)
???? break;
??? if ((n - t1) % i == 0) {
???? System.out.print(x + " ");
???? for (int j = 1; j < i; j++) {
????? System.out.print(x + j + " ");
???? }
???? System.out.println();
???? m++;
??? }
?? }
?? return m;
}
posted @
2009-08-29 02:28 jadmin 閱讀(107) |
評論 (0) |
編輯 收藏
private static int numOfZero(int n) {
?? int count = 0;
?? int data = 1;
?? for (int i = 1; i <= n; i++) {
??? data = data * i;
??? while (data % 10 == 0) {
???? count++;
???? data = data / 10;
??? }
??? data = data % 10;// 只保留個位數字,因其它位數字對0的個數無影響
?? }
?? return count;
}
posted @
2009-08-21 00:45 jadmin 閱讀(94) |
評論 (0) |
編輯 收藏