(文章本人原創(chuàng),若轉(zhuǎn)載請注明出處)
下面看一下一些具體的實現(xiàn),先看一下Sender接口的commitData方法的MySql實現(xiàn),即SenderMySqlImp類:
public void commitData(String path, String file) {
......
Connection connect = null;
try {
//根據(jù)配置由Helper來確定是否用連接池,這只調(diào)用getConnection()即可
connect = Helper.getConnection();
connect.setAutoCommit(false);
FileInputStream fis = new FileInputStream(path + file);
//insert語句,有三個參數(shù)分別為id,image,filename字段。
ps = connect.prepareStatement(sql.toString());
ps.setString(1, UUID.randomUUID().toString());
//將圖片文件流化,用jdbc直接寫到數(shù)據(jù)庫
ps.setBinaryStream(2, fis, fis.available());
ps.setString(3, file);
ps.executeUpdate();
connect.commit();
count++;
Logger.writeLog("已處理文件數(shù):"+count+",時間:"+new java.util.Date());
} catch (Exception e) {
........
}
很簡單吧,其實就是用Stream來做,另外在網(wǎng)上可以找到有關(guān)Oracle上傳blob的實現(xiàn),一般都是先insert一條記錄,blob字段用empty_blob()函數(shù)插入一個空數(shù)據(jù),然后再取出這個blob字段,最后按字節(jié)寫入blob,具體參考SenderOracleImp類吧。個人感覺還是在mysql的這個效率高些并且看起來簡單了很多。
然后來看看使用線程池的ProcessMulti類:
public class ProcessMulti implements Process{
private String path;
private Vector<String> files = new Vector<String>();
private Properties prop;
ProcessMulti() {
prop = ConfigMgr.getProperties(); //取config.properties中配置信息
this.path = prop.getProperty("path");
this.files = Helper.getFiles(prop.getProperty("filetype"), this.path);
}
public void doProcess() {
//正如前面兩篇所說,這里是線程池構(gòu)建器,傳入相關(guān)參數(shù)
BlobSenderThreadPool tpe = new BlobSenderThreadPool(Integer
.valueOf(prop.getProperty("corePoolSize")), Integer
.valueOf(prop.getProperty("maxPoolSize")), Integer.valueOf(prop
.getProperty("keepAliveTime")), TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(Integer.valueOf(prop
.getProperty("maxPoolSize"))),
new BlobSenderThreadPool.DiscardPolicy(), files.size());
Logger.writeLogForce("開始處理
." + new java.util.Date());
for (int i = 0; i < this.files.size(); i++) {
//向線程池提交要處理的任務(wù),線程池根據(jù)其配置進行處理
//Helper.getSender()會根據(jù)配置取得支持mysql或是oracel的寫入方法
tpe.execute(new Runner(path, files.get(i), Helper.getSender()));
Logger.writeLog("已提交第" + (int)(i+1) + "個文件" + ",時間為:"
+ new java.util.Date());
}
//可以在這里寫一個打印輸出,實際上程序很快就執(zhí)行完上面的for,運行到這里,但是處理并沒有完成,
//主程序好像職業(yè)經(jīng)理人,他的工作就是分配任務(wù)給下屬,自已就完成工作了,但下屬們還要接著忙活呵呵...
System.out.println("任務(wù)已分配...");
}
//線程池類
class BlobSenderThreadPool extends ThreadPoolExecutor {
volatile int planTask;//計劃任務(wù),即計劃要寫的文件數(shù)
public BlobSenderThreadPool(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler, int planTask) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
this.planTask = planTask;
}
@Override
//當(dāng)某個線程處理完時會調(diào)用此方法
protected void afterExecute(Runnable r, Throwable t) {
Logger.writeLog("當(dāng)前已完成任務(wù)數(shù):" + (int)(this.getCompletedTaskCount()+1)
+ "計劃任務(wù)數(shù):" + planTask);
//若已處理完任務(wù)和計劃的任務(wù)數(shù)相同說明所有線程已完成處理,終止線程池處理
if ((this.getCompletedTaskCount()+1)== planTask)
this.terminated();
super.afterExecute(r, t);
}
@Override
protected void terminated() {
Logger.writeLogForce("所有任務(wù)已完成 ,處理結(jié)束時間===>>" + new java.util.Date());
System.exit(0);
}
}
//要使用線程進行處理,類要實現(xiàn)Runable接口
class Runner implements Runnable {
String file;
String path;
Sender sender;
Runner(String path, String file, Sender sender) {
this.file = file;
this.path = path;
this.sender = sender;
}
//Runer的實例會被傳入線程池,線程被運行時會調(diào)用run方法
public void run() {
sender.commitData(path, file);
}
}
posted @
2009-03-21 10:40 依然Fantasy 閱讀(622) |
評論 (0) |
編輯 收藏
(文章本人原創(chuàng),若轉(zhuǎn)載請注明出處)
在實際當(dāng)中的情況是系統(tǒng)數(shù)據(jù)庫中需要上傳大量照片到數(shù)據(jù)庫中,數(shù)據(jù)量比較大,且不能在界面中通過操作逐個上傳,要批量自動進行。其實起來也比較簡單直接利用線程池將照片數(shù)據(jù)讀取成流再存入BLOB字段即可。但是在實現(xiàn)后些功能后又進入了一些改造,實現(xiàn)了線程池、單線程、是否使用用連接池、不同數(shù)據(jù)庫等不同的配置,這樣在不同配置下可以觀察到程序性能的不同。并且經(jīng)過設(shè)計切換這些配置不需要修改程序。

使用DbAccess接口的getConnect()取得數(shù)據(jù)庫連接,DbImp和DbPoolingImp實現(xiàn)了不使用連接池和使用連接池的兩個版本。Sender接口的commitData()用來把BLOB數(shù)據(jù)寫到數(shù)據(jù)庫中,因為不同數(shù)據(jù)庫可能寫法有點不同所以這里SenderMySqlImp和SenderOracleImp分別是Mysql和Oracle的實現(xiàn)。Process接口的doProcess()是開始進行處理的方法,無論是單線程還是多線程。因此ProcessMulti和ProcessSingle是分別使用線程池以及單線程處理的類。ConfigMgr用于取得config.properties文件內(nèi)配置信息,Logger是日志類,Helper中匯集了一些共用的靜態(tài)方法。最后DataSender是主程序的類:)
posted @
2009-03-21 10:25 依然Fantasy 閱讀(306) |
評論 (0) |
編輯 收藏
(文章本人原創(chuàng),若轉(zhuǎn)載請注明出處)
在JDK1.5提供了一個線程池ThreadPoolExecutor,可以處理用戶提交過來的線程。如果把要處理的任務(wù)比作蓋一個大樓,那么每一個建筑工人就相當(dāng)于一個線程,那么這個ThreadPoolExecutor就好像包工頭,它來控制蓋這個大樓需要多少個工人,何時招進新工人,何時辭退已經(jīng)長時間沒有事做的工人,等等此類事務(wù)。也就是說用戶程序不斷提交新的線程,ThreadPoolExecutor執(zhí)行提交線程的同時會控制目前總共同時執(zhí)行的線程數(shù),銷毀已執(zhí)行完閑置的線程等控制行為,保留最少閑置線程數(shù),并且可以配置不同的處理策略。
為什么要使用線程池呢,這與數(shù)據(jù)庫連接池的原理有點相仿,線程的創(chuàng)建是需要成本的,包括服務(wù)器CPU和內(nèi)存資源,由于多線程是并行運行,程序運行過程中可能有的線程已經(jīng)完成自身處理任務(wù),處于閑置狀態(tài),如果在這種情況下再不斷創(chuàng)建新任務(wù)就是在浪費服務(wù)器資源,此時應(yīng)該盡量使用先前創(chuàng)建的好的并且是處理閑置狀態(tài)的線程來處理新任務(wù),而線程池就可以有效的對此進行自動化管理,當(dāng)然這個管理是可以由用戶配置的。
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
這是線程池的構(gòu)建器,用戶程序通過這個構(gòu)建器傳參數(shù),corePoolSize是線程池中核心線程數(shù),運行的線程數(shù)不能少于這個核心線程數(shù),否則就新建線程。maximumPoolSize是充許最大的線程數(shù)。keepAliveTime設(shè)置除核心線程外其它線程的空閑時間,超過這個時間線程就自動終止。unit是指的keepAliveTime的時間單位。BlockingQueue接口按生產(chǎn)則消費者算法設(shè)計的一個線程池內(nèi)部處理線程隊列的接口,有三種實現(xiàn)SynchronousQueue、LinkedBlockingQueue和ArrayBlockingQueue,在實際運行程序時可以根據(jù)這三種實現(xiàn)得到不同的性能,比如有的實現(xiàn)可能在有新任務(wù)來時不新建線程,而是將其加入等待隊列,等有線程運行完時再分配給其使用。具體實現(xiàn)還是參看它們的JDK文檔吧,這里站在使用的角度它們是可以調(diào)整運行性能的開關(guān)。當(dāng)最大線程和工作隊列容量都達到最大值時,再提交給線程池新任務(wù)就會被拒絕,此時線程池會調(diào)用RejectedExecutionHandler 接口進行處理,具體實現(xiàn)有四種策略。我們只需要選用其中一種在構(gòu)建ThreadPoolExecutor時傳入即可。具體四種實現(xiàn)還是參看JDK文檔吧。關(guān)于ThreadPoolExecutor的JDK文檔。至此控制線程池運作的幾個參數(shù)都從構(gòu)建器中傳入了。
posted @
2009-03-19 22:26 依然Fantasy 閱讀(846) |
評論 (0) |
編輯 收藏
google了一篇不錯的例子,加了點注解,這樣看起來更方便了:)
Oracle不像SQLServer那樣在存儲過程中用Select就可以返回結(jié)果集,而是通過Out型的參數(shù)進行結(jié)果集返回的。實際上是利用REF CURSOR
--procedure返回記錄集:
----------------------聲明一個Package--------------
CREATE OR REPLACE PACKAGE pkg_test
AS
TYPE myrctype IS REF CURSOR;
PROCEDURE get (p_id NUMBER, p_rc OUT myrctype); --Package中聲明名為get 的Procedure(只有接口沒內(nèi)容)
END pkg_test;
--------------------------------------------------------
-----------------聲明Package Body,即上面Package中的內(nèi)容,包括Procedure get---------------------
CREATE OR REPLACE PACKAGE BODY pkg_test
AS
PROCEDURE get (p_id NUMBER, p_rc OUT myrctype)
IS
sqlstr VARCHAR2 (500);
BEGIN
IF p_id = 0 THEN
OPEN p_rc FOR
SELECT ID, NAME, sex, address, postcode, birthday
FROM student;
ELSE
sqlstr :=
'select id,name,sex,address,postcode,birthday
from student where id=:w_id'; --w_id是個參數(shù),
--以下 p_rc是個REF CURSOR游標(biāo)類型,而且是OUT型參數(shù),即可返回一個記錄集了。USING p_id就是替換上面SQL中:w_id值拉:)
OPEN p_rc FOR sqlstr USING p_id;
END IF;
END get;
END pkg_test;
--function返回記錄集的例子,原理和上面相同,而是用function的return值來返回記錄集。
函數(shù)返回記錄集:
建立帶ref cursor定義的包和包體及函數(shù):
CREATE OR REPLACE
package pkg_test as
/* 定義ref cursor類型
不加return類型,為弱類型,允許動態(tài)sql查詢,
否則為強類型,無法使用動態(tài)sql查詢;
*/
type myrctype is ref cursor;
function get(intID number) return myrctype;
end pkg_test;
/
CREATE OR REPLACE
package body pkg_test as
--函數(shù)體
function get(intID number) return myrctype is
rc myrctype; --定義ref cursor變量
sqlstr varchar2(500);
begin
if intID=0 then
--靜態(tài)測試,直接用select語句直接返回結(jié)果
open rc for select id,name,sex,address,postcode,birthday from student;
else
--動態(tài)sql賦值,用:w_id來申明該變量從外部獲得
sqlstr := 'select id,name,sex,address,postcode,birthday from student where id=:w_id';
--動態(tài)測試,用sqlstr字符串返回結(jié)果,用using關(guān)鍵詞傳遞參數(shù)
open rc for sqlstr using intid;
end if;
return rc;
end get;
end pkg_test;
posted @
2009-01-13 21:55 依然Fantasy 閱讀(1602) |
評論 (0) |
編輯 收藏
在ORACLE存儲過程中創(chuàng)建臨時表
存儲過程里不能直接使用DDL語句,所以只能使用動態(tài)SQL語句來執(zhí)行
--ON COMMIT DELETE ROWS 說明臨時表是事務(wù)指定,每次提交后ORACLE將截斷表(刪除全部行)
--ON COMMIT PRESERVE ROWS 說明臨時表是會話指定,當(dāng)中斷會話時ORACLE將截斷表。
CREATE OR REPLACE PROCEDURE temptest
(p_searchDate IN DATE)
IS
v_count INT;
str varchar2(300);
BEGIN
v_count := 0;
str:='drop table SETT_DAILYTEST';
execute immediate str;
str:='CREATE GLOBAL TEMPORARY TABLE SETT_DAILYTEST (
NACCOUNTID NUMBER not null,
NSUBACCOUNTID NUMBER not null)
ON COMMIT PRESERVE ROWS';
execute immediate str; ----使用動態(tài)SQL語句來執(zhí)行
str:='insert into SETT_DAILYTEST (select naccountid,nsubaccountid from sett_dailyaccountbalance)';
execute immediate str;
END temptest;
上面建立一個臨時表的存儲過程
下面是執(zhí)行一些操作,向臨時表寫數(shù)據(jù)。
CREATE OR REPLACE PROCEDURE PR_DAILYCHECK
(
p_Date IN DATE,
p_Office IN INTEGER,
p_Currency IN INTEGER,
P_Check IN INTEGER,
p_countNum OUT INTEGER)
IS
v_count INT;
BEGIN
v_count := 0;
IF p_Date IS NULL THEN
dbms_output.put_line('日期不能為空');
ELSE
IF P_Check = 1 THEN
insert into SETT_DAILYTEST (select naccountid,nsubaccountid from sett_dailyaccountbalance
where dtdate = p_Date);
select
count(sd.naccountid) into v_count
from sett_subaccount ss,sett_account sa,sett_dailytest sd
where sd.naccountid = sa.id and sd.nsubaccountid = ss.id and sa.id = ss.naccountid
AND sa.nofficeid = p_Office AND sa.ncurrencyid = p_Currency
and rownum < 2;
COMMIT;
p_countNum := v_count;
dbms_output.put_line(p_countNum);
END IF;
IF P_Check = 2 THEN
insert into SETT_DAILYTEST (select naccountid,nsubaccountid from sett_dailyaccountbalance
where dtdate = p_Date);
select
count(sd.naccountid) into v_count
from sett_cfsubaccount ss,sett_account sa,sett_dailytest sd
where sd.naccountid = sa.id and sd.nsubaccountid = ss.id and sa.id = ss.naccountid
AND sa.nofficeid = p_Office AND sa.ncurrencyid = p_Currency
and rownum < 2;
COMMIT;
p_countNum := v_count;
dbms_output.put_line(p_countNum);
END IF;
END IF;
END PR_DAILYCHECK;
posted @
2009-01-13 21:23 依然Fantasy 閱讀(17356) |
評論 (0) |
編輯 收藏
Oracle本身沒數(shù)組的概念,但是通過Oracle的Collections和Records類型可以模仿出單維數(shù)組和多維數(shù)組。
請參考<<Oracle PL/SQL Programming>> Chapter 11、Chapter 12。
---------------------- 單維數(shù)組 ------------------------
DECLARE
TYPE emp_ssn_array IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; ----注:聲明一個Collection
best_employees emp_ssn_array;
worst_employees emp_ssn_array;
BEGIN
best_employees(1) := '123456';
best_employees(2) := '888888';
worst_employees(1) := '222222';
worst_employees(2) := '666666';
FOR i IN 1..best_employees.count LOOP
DBMS_OUTPUT.PUT_LINE('i='|| i || ', best_employees= ' ||best_employees(i)
|| ', worst_employees= ' ||worst_employees(i));
END LOOP;
END;
---------------------- 多維數(shù)組 ------------------------
DECLARE
TYPE emp_type IS RECORD ---------注:聲明一個Record類型 emp_type
( emp_id employee_table.emp_id%TYPE, ----Record類型中的成員...
emp_name employee_table.emp_name%TYPE,
emp_gender employee_table.emp_gender%TYPE );
TYPE emp_type_array IS TABLE OF ----注:聲明一個Collection類型 emp_type_array ,其中元素為emp_type類型
emp_type INDEX BY BINARY_INTEGER;
emp_rec_array emp_type_array;
emp_rec emp_type;
BEGIN
emp_rec.emp_id := 300000000;
emp_rec.emp_name := 'Barbara';
emp_rec.emp_gender := 'Female';
emp_rec_array(1) := emp_rec;
emp_rec.emp_id := 300000008;
emp_rec.emp_name := 'Rick';
emp_rec.emp_gender := 'Male';
emp_rec_array(2) := emp_rec;
FOR i IN 1..emp_rec_array.count LOOP
DBMS_OUTPUT.PUT_LINE('i='||i
||', emp_id ='||emp_rec_array(i).emp_id
||', emp_name ='||emp_rec_array(i).emp_name
||', emp_gender = '||emp_rec_array(i).emp_gender);
END LOOP;
END;
-------------- Result --------------
i=1, emp_id =300000000, emp_name =Barbara, emp_gender = Female
i=2, emp_id =300000008, emp_name =Rick, emp_gender = Male
posted @
2009-01-13 21:07 依然Fantasy 閱讀(452) |
評論 (0) |
編輯 收藏
Oracle PL/SQL中如何使用%TYPE和%ROWTYPE (轉(zhuǎn)載)
1. 使用%TYPE
在許多情況下,PL/SQL變量可以用來存儲在數(shù)據(jù)庫表中的數(shù)據(jù)。在這種情況下,變量應(yīng)該擁有與表列相同的類型。例如,students表的first_name列的類型為VARCHAR2(20),我們可以按照下述方式聲明一個變量:
DECLARE
v_FirstName VARCHAR2(20);
但是如果first_name列的定義改變了會發(fā)生什么(比如說表改變了,first_name現(xiàn)在的類型變?yōu)閂ARCHAR2(25))?那就會導(dǎo)致所有使用這個列的PL/SQL代碼都必須進行修改。如果你有很多的PL/SQL代碼,這種處理可能是十分耗時和容易出錯的。
這時,你可以使用"%TYPE"屬性而不是將變量類型硬性編碼。
例如:
DECLARE
v_FirstName students.first_name%TYPE;
通過使用%TYPE,v_FirstName變量將同students表的first_name列的類型相同(可以理解為將兩者邦定起來)。
每次匿名塊或命名塊運行該語句塊以及編譯存儲對象(過程、函數(shù)、包、對象類和觸發(fā)器)時,就會確定該類型。
使用%TYPE是非常好的編程風(fēng)格,因為它使得PL/SQL更加靈活,更加適應(yīng)于對數(shù)據(jù)庫定義的更新。
2. 使用%ROWTYPE
2.1 PL/SQL記錄
PL/SQL記錄類型類似于C語言中的結(jié)構(gòu),是一種復(fù)合類型,是用戶自定義的。
記錄提供了一種處理獨立的但又作為一個整體單元相關(guān)的變量的機制。請看:
DECLARE
v_StudentID NUMBER(5);
v_FirstName VARCHAR2(20);
v_LastName VARCHAR2(20);
這3個變量在邏輯上是相互關(guān)聯(lián)的,因為他們指向students表中不同的字段。如果為這些變量聲明一個記錄類型,那么他們之間的關(guān)系就十分明顯,可作為一個單元進行處理。
DECLARE
/*Define a record type to hold common student informationi*/
TYPE t_StudentRecord IS RECORD(
StudentID NUMBER(5),
FirstName VARCHAR2(20),
LastName VARCHAR2(20);
/*Declare a variable of this type.*/
v_StudentInfo t_StudentRecord;
2.2 記錄賦值
可以用SELECT語句向記錄賦值,這將會從數(shù)據(jù)庫中檢索數(shù)據(jù)并將該數(shù)據(jù)存儲到記錄中。注意的是,記錄中字段應(yīng)該和查詢結(jié)果列表中的字段相匹配。
SELECT studentID,firstName,lastName
into v_StudentInfo
from students where studentID=32;
2.3 使用%ROWTYPE
在PL/SQL中將一個記錄聲明為具有相同類型的數(shù)據(jù)庫行的作法是很常見的。PL/SQL提供了%ROWTYPE運算符,使得這樣的操作更為方便。
例如:
DECLARE
v_RoomRecord rooms%ROWTYPE;
將定義一個記錄,該記錄中的字段將與rooms表中的列相對應(yīng)。
posted @
2009-01-07 08:38 依然Fantasy 閱讀(1492) |
評論 (2) |
編輯 收藏
周5手機不幸被盜,可惡的小偷,偷我的手機你就斷手?jǐn)嗄_吧。明天準(zhǔn)備聯(lián)系索愛和移動客服看是否能通過手機串碼把手機屏蔽,據(jù)說從技術(shù)角度講是可以行的通的,問題就是這種事手機運營商愿不愿意給做了。英國已經(jīng)有這種服務(wù)可以使被盜手機不能再被使用,不知道特色中國啥時能有這種真正特色的服務(wù)呢。
我的索愛W810聽音樂音質(zhì)超好,入耳式耳機也很棒,感覺比專業(yè)的魅族MP3還高一籌(主要魅族帶的耳機太爛,而且魅族音質(zhì)風(fēng)格有點假,特別配上自帶耳機后聽音樂塑料感極強)。w810音質(zhì)風(fēng)格基本上就是SONY早年CDWalkMan那種日系風(fēng)格,加上入耳式耳機低音很強。另外FM收音功能也很不錯,信號很好,這個我也是和魅族的MP3對比過的,同樣環(huán)境下FM收音信號也強一些,相對由于信號弱造成的背景噪音小一些,加上聲音渲染修飾的好,不會有由于信號不好造成的刺耳聲。W810的拍照功能也不錯,拍的照片,特別是白天光線好時,拍出來的照片基本上可以冒充數(shù)碼相機的了。總之,用了一年,感覺W810最大缺點就是短信有容量限制,我基本上半個月就得清一回收件箱。個人認為w810作為手機來用是比不上NOKIA的好用,但是隨身聽、拍照功能的確很好,估計索愛的W系列基本也都是這樣。哎可惜現(xiàn)在連個尸體都沒留下..懷念呀.....
w810
平時忙沒時間逛商店,周6到濱江道溜達了一圈,據(jù)賣手機的服務(wù)員說,天語手機銷量已經(jīng)能和NOKIA有的一拼了,想想一年多前還是名不見經(jīng)傳,世界變化快呀。由于之前在淘寶上看過價格了,所以無論哪款手機門店里的價格基本上沒法接受了。現(xiàn)在消費觀念已不同從前了(有可能被全球經(jīng)濟危機嚇得呵呵~),基本上2000元以上的手機就不看了,找了幾款什么索愛M600i、880i以及夏新E78...最后還是回發(fā)現(xiàn)干麻不買個NOKIA智能機的呢,我在W810前就是用的NOKIA6630呀,當(dāng)時感覺智能機很強大很DIY。最后發(fā)現(xiàn)淘寶上N72行貨價格已經(jīng)掉到1300左右(剛出時得有三四千了),還給開發(fā)票和全國聯(lián)保,OMG超值,就是它了.....
沒想到那個賣家別看信用值不高,東西相對便宜,服務(wù)態(tài)度到是超好,基本上算是送了個1GB卡,周日拍周一晚上就收到貨了,一看包裝寫著是空運...東西也不錯,開封后機器沒有任何問題,還有正規(guī)發(fā)票。有的信用值不高的賣家估計是想薄利多銷招攬客戶吧,不像有的幾個鉆或者是大皇冠的賣家,買個東西好像還不是很熱情的樣子,也有可能是客戶多忙不過來了。
說說N72,基實和我在w810之前用過的6630沒啥太多區(qū)別,都是NOKIA S60系統(tǒng),就是外形小了一點,薄了一點點,內(nèi)存大了些,這回是1GB存儲卡、攝像頭由130萬變成200萬,多了FM收音功能,操作系統(tǒng)版本新了些。我基本上當(dāng)它是新版6630用,呵呵~
值得一提的是,NOKIA的耳機一般音質(zhì)像地攤貨,這回的也一樣,打開包裝原配的耳機就扔到了一邊,我用NOKIA的AD-15轉(zhuǎn)換器(一種NOKIA專用耳機轉(zhuǎn)接器,外加功率放大功能的小東西)接上我的森海塞耳PX200,呵呵~~音質(zhì)超爽,幾乎已超越了W810的音質(zhì),但是另一種風(fēng)格不像是日系隨身聽低音很悶的那種。但是很奇怪如果接SonyE888音質(zhì)就不怎么地,費解中..。自此以后又可以下載S60各種應(yīng)用軟件、游戲、MP3播放軟件....重回NOKIA的智能DIY世界......也許哪天花幾百搞個藍牙GPS定位器,裝個地圖軟件,就可以實現(xiàn)手機GPS定位了。
n72 6630
posted @
2008-10-13 22:59 依然Fantasy 閱讀(403) |
評論 (0) |
編輯 收藏
用一個已不寫程序的朋友的話說,現(xiàn)在Java世界里真是讓人眼花繚亂,不僅對于新手,就算是過去熟悉Servlet、JSP,EJB的programmer,估計要完全搞明白現(xiàn)在的‘新生態(tài)架構(gòu)’也不是很容易。從N多年前的‘一次編譯到處運行’到后來的EJB,再到現(xiàn)在的Spring、Hibernate、Webwork、JSF等諸多表現(xiàn)層、數(shù)據(jù)層,以及支持MVC、AOP的框架,再加上JDK1.5后加入的泛型等新功能,如果是一直以Servlet,JSP、JDBC或是EJB開發(fā)的話,現(xiàn)在突然接觸到這些東西真是要學(xué)習(xí)一陣了。最近在看《越獄》,想起一個并不恰當(dāng)?shù)谋扔鳎盟埔粋€服刑30年的老家伙,有一天終于刑滿釋放,結(jié)果出來后卻發(fā)現(xiàn)外面的世界早已不是他所想的那樣了。。。
還好我們對于這些變化早有準(zhǔn)備,最快的學(xué)習(xí)方法莫過于直接針對一個系統(tǒng)進行源碼分析、學(xué)習(xí)、剝離出其中用到的技術(shù)方面,然后嘗試用于我們自已的項目或產(chǎn)品中去。用google、baidu很快就把焦點定位在了一個開源的網(wǎng)上社區(qū)http://www.laoer.com/?即天乙社區(qū),我們關(guān)心的是技術(shù)架構(gòu),它用的是Struts+Spring+Hibernate,struts1.x版本雖然比起JSF、Tapestry、Webwork以及Webwork和Struts合并的Struts2.x,strtus1.x并不是很先進,但這套源碼的成熟度和這個架構(gòu)的使用率一定很高,N多項目都在用這種架構(gòu),況且3者結(jié)合其中必有玄機,還是有的學(xué)了:)
粗看了一下這套系統(tǒng)的架構(gòu)以及源碼,大約理了一下思路,打算根據(jù)源碼中用到的技術(shù),按幾個方面去研究,圍繞社區(qū)系統(tǒng)中的應(yīng)用,再寫幾篇文章就當(dāng)是一種成果吧。
????????主要有以下幾方面:
Struts與Spring集成應(yīng)用
?????????Hibernate與Spring的集成應(yīng)用
????????OSCache的應(yīng)用(這里主要用于緩存POJO)
??????? Intecepter即攔截器的應(yīng)用
??????? Ajax的應(yīng)用以及Prototype
??????? 。。。。
???????
posted @
2007-03-13 16:09 依然Fantasy 閱讀(1841) |
評論 (3) |
編輯 收藏