先說下CVSNT的用戶驗證方式,CVSNT的用戶驗證方式分兩種:Windows系統用戶與CVSNT用戶共存的混合驗證方式,及CVSNT用戶 單一驗證方式,默認工作在混合驗證方式下,當然使用單一驗證方式對用戶的管理肯定比較方便一點,因此下面的配置就是圍繞該方式進行的。各個資源庫所使用的 驗證方式及用戶配置由其目錄下CVSROOT里的配置文件決定,其中有幾個比較重要的文件。
控制CVSNT的驗證工作方式的就是config文件,注意該文件最前面的兩行:
#Set this to `no" if pserver shouldn"t check system users/passwords
#SystemAuth=yes
第二行就是我們要修改的內容,默認狀態是被注釋掉的,SystemAuth有兩個值yes和no:
yes:pserver將使用Windows系統用戶和CVSNT用戶來共同驗證(若CVSNT用戶未定義,則用Windows系統用戶來進行驗證),默認為yes,CVSNT用戶在后面將要介紹的passwd文件中定義。
no:只使用CVSNT用戶來進行驗證。
該文件可以在客戶端進行修改,因此我們可以將其checkout出來將第二行改為SystemAuth=no,并commit到CVSNT上就可以啟用單一驗證方式了,注意啟用單一驗證方式后原來的Windows系統用戶將變為無效,因此要注意執行該步驟的時機。
2、 admin文件
該文件保存CVSNT管理員用戶列表,內容很簡單,形式如下:
User1
User2
User3
每一行定義一個管理 員用戶,默認時沒有該文件,但你可以在客戶端自己添加并add上去,再commit到CVSNT上,但是光有這個文件還是不會生效的,還要將其添加到 checklist文件中,使CVSNT能夠讀取該文件的內容,在checklist中添加文件列表的格式為:
[空格]文件名 出錯信息
其中文件名前的空格必須要有的,不然會出錯。
我們可以先添加admin文件到CVSNT中,再修改checklist文件commit,就可以使admin文件生效了。
3、passwd文件
服務器工作在CVSNT用戶單一驗證方式下的時候,這個文件定義了CVSNT的用戶信息,這里面保存著用戶名,用戶密碼,以及別名信息。默認狀態下 沒有該文件,但是我們可以在CVSNT還工作在混合驗證方式下時,用系統管理員登錄,通過添加用戶命令來讓CVSNT自動建立一個passwd文件。
添加用戶的命令的示例:
cvs passwd –r administrator –a cvsadmin
之后系統提示輸入密碼,輸入后服務器會新建一個passwd文件。
該文件的內容很簡單,形式如下:
cvsadmin:fqr1fS4gDghrt:administrator
kid:aTXRfS31Bm6JA
mystique:Yna4QcXz9dEqd
以第一行為例:cvsadmin為用戶名,fqr1fS4gDghrt為CVS使用UNIX標準加密函數對密碼進行加密后的結果,administrator為該用戶的別名,當使用混合驗證方式時對應Windows系統用戶名。
注意:這個文件是不能在客戶端進行修改的,不能checkout出來。
4、group文件
該文件定義CVSNT中組信息,同組里的用戶擁有一樣的權限,對組權限的修改和對用戶權限的修改一樣。
group文件的內容為
administrators:cvsadmin kid mystique
users:User1 User2 User3
可以看到該文件的內容也很簡單,組名:用戶名,多個用戶名之間用空格隔開。
Group文件可以在客戶端修改,不用修改checkoutlist這個文件,系統會自動使其生效。
作為組里面的特定成員可以賦給特定的權限。
了解了以上內容,下面我說一下我自己的配置步驟,我沒有使用WinCVS進行操作,是直接使用命令行進行修改的,覺得這樣思路比較清晰:
1、添加系統變量CVSROOT=E:/CVSNT/Repository,并把E:CVSNT加入到系統Path路徑。
2、進入命令提示符,因為此時為混合驗證模式,可以不用不用登陸直接進行checkout。可以建立一個工作目錄,在該目錄下進行操作,我這里為E:/CVSNT/Works。
檢出CVSROOT目錄:
cvs co CVSROOT
3、添加CVSNT系統管理員用戶,此時會提示設置用戶密碼:
cvs passwd –r administrator –a cvsadmin
4、修改CVSROOT訪問權限:
cd CVSROOT
cvs chown cvsadmin //更改所有者為cvsadmin
cvs chacl default:n //默認權限為n
cvs chacl cvsadmin:rwc //添加cvsadmin
5、修改config文件,按上面的方法修改后commit:
cvs ci
6、此時單一驗證方式已經啟用了,也就是只能使用剛才添加的cvsadmin進行登錄,此時可以把CVSNT控制面板上的Use local users for pserver authentication instead of domain users關掉。登錄前還要改一下系統變量CVSROOT,關閉命令提示符窗口,修改CVSROOT為:
:pserver:cvsadmin@192.168.0.1:4021/CVSNT/Repository
這里的192.168.0.1是服務器的IP地址,/CVSNT/Repository就是前面設置Repository時設置的Name,可以改為你機器上的配置。修改系統變量之后以下的步驟在任何與服務器相連的機器上進行,當然該機器上應該有CVSNT的可執行文件。
7、如果為了避免出現錯誤,先重啟一下CVSNT服務器,再啟動命令提示符來到E:/CVSNT/Works,因為已經啟用單一驗證方式,先要進行登錄。
cvs login
輸入密碼,此時就是以cvsadmin登錄了。
8、添加admin文件,首先將CVSROOT檢出,在CVSROOT下新建admin文件,內容為
cvsadmin
執行命令:
cvs add admin
cvs ci
9、修改checklist文件,在該文件末尾添加一行:
[空格]admin error message
注意:admin前的空格不能少。
執行命令:
cvs ci
經過以上步驟,可以說用戶配置已經基本完成了,CVSNT可以很好的工作在單一驗證方式下。進一步的管理可使用以下命令:
添加用戶: cvs passwd -a username,使用時不必理會需要添加別名的提示。
修改用戶權限:cvs chacl username:r|w|c|n,(r:Read w:write c:control n:none)
要添加組管理,只需同添加admin步驟一樣,按照格式要求新建group文件即可。
如果還有不清楚的可以看看自帶的文檔,說得還是比較詳細的。
一、什么是CVS?
CVS――Concurrent Versions System并行版本系統;
是一個標準的版本控制系統;
對代碼進行集中管理;
記錄代碼所有的更改歷史;
提供協作開發的功能;
支持多人同時CheckOut與合并。
以客戶端/服務器模式工作,所有的用戶都在客戶端進行CVS操作,而所有命令的執行都在CVS服務器端進行。
二、CVS基本概念
1.設置環境變量。
set CVSROOT=:pserver:xxx@192.168.0.226:e:/cvsroot set CVSROOT=:pserver:xxx@ansi.3322.org:e:/cvsroot
$cd $cvs?? co?? account/src/common
$cvs co account
3.提交修改的文件到CVS版本庫中:
$cvs?? ci?? <filename>
$cvs?? ci <回車>
4.提交新增加的目錄或文件到CVS版本庫中:
$cvs?? add?? <dirname> $cvs?? ci?? <dirname> $cvs?? add?? <filename> $cvs?? ci?? <filename>
5.刪除目錄及文件,需先刪除目錄下的文件
$rm?? <filename> $cvs?? remove?? <filename> $cvs?? ci?? <filename>
$cd .. $cvs up –P
6.查看文件狀態
$cvs status <filename>
$ cvs st ffun.c ================================================================= File: ffun.c???????????? Status: Up-to-date ??? Working revision:???? 1.1????? Wed Nov?? 6 11:29:04 2002 ??? Repository revision: 1.1????? /szunicom/dev/billing/src/preproc/CDMA/ffun.c,v ??? Sticky Tag:?????????? (none) ??? Sticky Date:????????? (none) ??? Sticky Options:?????? (none)
Up-to-date
:表明你的工作拷貝是最新的.Locally added
:表明使用了"add"命令增加了該文件,但還沒有"commit"Locally Removed
:表明你使用了"remove"命令,但還沒有"commit"Unkown
:CVS不知道關于這個文件的情況.例如,你創建了一個新文件,而沒有使用"add"命令$cvs ci <filename>
。7.查看工作拷貝和倉庫中最后版本之間的修改
$ cvs diff src.c
8.查看指定的兩個版本之間的修改
$ cvs diff -r 1.1 -r 1.2 <filename>
9.版本回退(取出以前的某個版本)
有兩種方式:
一是只把某一版本的文件輸出到標準輸出上:
$cvs up –p –r <版本號> <filename>
另一種是將輸出到標準輸出的結果重定向到文件中:
$cvs up –p –r <版本號> <filename> > <filename>
$cvs up –p –r 1.2 abc.c > abc.c
cvs ci cvs commit: Examining . cvs commit: sticky tag `1.2' for file `abc.c' is not a branch cvs [commit aborted]: correct above errors first!
解決辦法兩種方式:
1、修改CVS/Entries文件,將以下黃色標記部分刪除即可。
$cd CVS $ vi E* /abc.c/1.2/Tue Dec 17 13:33:06 2002//T1.2
2、使用$cvs up –A abc.c命令來消除附著標簽,但是該命令是將1.2版本與最新版本進行了合并,還需對abc.c進行修改再重新提交。
10.如何恢復已經刪除的文件或目錄:
1. 在執行了【Remove】命令之后恢復文件。 ◇ 【Ctrl+L】直接輸入命令cvs add xxxxx,或執行【Add Selection】界面操作。 ◇ 這樣就可以直接恢復還未提交的刪除文件。
2. 在執行了【Commit】命令之后恢復文件。 ◇ 只能用【Ctrl+L】直接輸入命令cvs add xxxxx,這時會得到一個空的文件。 ◇ 選中這個空文件,執行【Update】操作,得到這個文件的實體。 ◇ 再次選中這個文件,執行【Commit】操作,得到這個文件最新版本。
3. 由于CVS系統中本質上不會刪除任何目錄,因此,談不上對目錄的恢復,但是CVS系統默認情況下是要在用戶本機上(如:YCW2000)要刪除空目錄,因此,可以用如下方法得到已被刪除的空目錄:cvs checkout -p xxx,也可以在Admin=>Preference的【Globals】頁面進行設置。
=============================================================================
CVS是一個C/S系統,多個開發人員通過一個中心版本控制系統來記錄文件版本,從而達到保證文件同步的目的。工作模式如下:
CVS服務器(文件版本庫)
/ | \ (版 本 同 步)
/ | \
開發者1 開發者2 開發者3
CVS(Concurrent Version System)版本控制系統是一種GNU軟件包,主要用于在多人開發環境下的源碼的維護。實際上CVS可以維護任意文檔的開發和使用,例如共享文件的編輯修改,而不僅僅局限于程序設計。CVS維護的文件類型可以是文本類型也可以是二進制類型。CVS用Copy-Modify-Merge(拷貝、修改、合并)變化表支持對文件的同時訪問和修改。它明確地將源文件的存儲和用戶的工作空間獨立開來,并使其并行操作。CVS基于客戶端/服務器的行為使其可容納多個用戶,構成網絡也很方便。這一特性使得CVS成為位于不同地點的人同時處理數據文件(特別是程序的源代碼)時的首選。
所有重要的免費軟件項目都使用CVS作為其程序員之間的中心點,以便能夠綜合各程序員的改進和更改。這些項目包括GNOME、KDE、THE GIMP和Wine等。
CVS的基本工作思路是這樣的:在一臺服務器上建立一個源代碼庫,庫里可以存放許多不同項目的源程序。由源代碼庫管理員統一管理這些源程序。每個用戶在使用源代碼庫之前,首先要把源代碼庫里的項目文件下載到本地,然后用戶可以在本地任意修改,最后用CVS命令進行提交,由CVS源代碼庫統一管理修改。這樣,就好象只有一個人在修改文件一樣,既避免了沖突,又可以做到跟蹤文件變化等。
CVS是并發版本系統(Concurrent Versions System)的意思,主流的開放源碼網絡透明的版本控制系統。CVS對于從個人開發者到大型,分布團隊都是有用的:
它的客戶機/服務器存取方法使得開發者可以從任何因特網的接入點存取最 新的代碼。它的無限制的版本管理檢出(check out:注1)的模式避免了通常的因為排它 檢出模式而引起的人工沖突。 它的客戶端工具可以在絕大多數的平臺上使用。
CVS被應用于流行的開放源碼工程中,象Mozilla,GIMP,XEmacs,KDE,和GNOME等。 那么它到底怎么樣?
你可能會說,它非常棒,但是對于 "我"來說它能做什么?首先,基本的 :一個版本控制系統保持了對一系列文件所作改變的歷史記錄。對于一個開發者來說,那就意味著在你對一個程 序所進行開發的整個期間,能夠跟蹤對其所作的所有改動的痕跡。對你來說,有沒有出現過由于在令行上 按錯鍵而導致一天的工作都白費的情況呢?版本控制系統給了你一個安全的網絡。
版本控制系統對任何人都有用,真的。(畢竟,誰不愿意使用一個安全的 網絡呢?)但是它們經常被軟件開發團隊使用。在團隊中工作的開發者需要能夠調整他們的各自的修改;一個集 中式版本控制系統允許那樣做。
代碼集中的配置
個人開發者希望一個版本控制系統的安全網絡能夠運行在他們的本地的 一臺機器上。然而,開發團隊需要一個集中的服務器,所有的成員可以將服務器作為倉庫來訪問他們的代碼。在 一個辦公室中,沒有問題 --只是將倉庫連到本地網絡上的一臺服務器上就行了。對于開放源碼項目...噢, 還是沒有問題,這要感謝因特網。CVS內建了客戶機/服務器存取方法,所以任何一個可以連到因特網上的開發 者都可以存取在一臺CVS服務器上的文件。
調整代碼
在傳統的版本控制系統中,一個開發者檢出一個文件,修改它,然后將 其登記回去。檢出文件的開發者擁有對這個文件修改的排它權。沒有其它的開發者可以檢出這個文件 -- 并且只 有檢出那個文件的開發者可以登記(check in:注2)所做的修改。(當然對于管理員有很多方法可以超越這個 限制。)
想一下排它的檢出可能會如何工作:Bob的兄弟檢出 foo.java以便加入 注釋,寫好代碼后他什么也沒做。然后他去吃午飯了。Bob吃完午飯后,發現他的老板所指給他的一個bug在 foo.java里。他試圖檢出 foo.java ... 但是版本控制系統不允許他這樣做,因為他的兄弟已經把它檢出了。Bob不 得不等著他的兄弟吃完午飯回來(在這個 "好"日子用了兩個小時),他才可以修正bug。
在一個大型的開放源碼工程中,因為開發者可能在任意的時區工作得很 晚,給予一個開發者阻止任意地方的其它開發者繼續處理任意文件的能力很明顯示無法運轉。他們最終將因為不 能夠在他們想要的時候開展項目而感到厭煩。
CVS通過它的無限制的檢出模式解決了這個問題。檢出一個文件并不給定 開發者對那個文件的排它權。其它的開發者也可以對其檢出,進行他們自己的修改,并且將其登記回去。
"等一下!"你可能會說。"但是后面的登記不是會覆蓋前面的嗎?"回答 是不會。詳細地回答就是當多個開發者對同一個文件作了修改CVS會檢測,并且自動合并那些改變。
哇噢。自動的?不用擔心 -- CVS 會很小心,并且將會自動合并那些只 要不是對代碼的同一行所作的改動。如果CVS不能安全的處理這些改動,開發者將不得不手工合并它們。 從此去往何處?
到現在為止,你已經毫不猶豫地著迷于CVS 的潛力,并且急不可待地想 開始。第一步就是去得到 適合你的平臺的CVS軟件。安裝CVS通常就是將其從你下載的壓縮包中解開這么一件 事。配置CVS 可能要小心一些,它非常依賴于你使用的平臺和你的CVS代碼倉庫的存放地。CVShome.org存放了大 量的CVS 文檔:
《Introduction to CVS》 Jim Blandy所寫的一篇很棒地在線介紹。我也推薦《 Open Source Development with CVS》 Karl Fogel寫的。你可以讀一下我寫的關 于它的評論在OpenAvenue VOX上。Karl已 經將書中關于CVS的部分置于GPL許可證之下;這篇文檔在Karl的站點上以多種文檔格式提供。
《The Cederqvist》 -- 由Per Cederqvist所編寫的CVS手冊 -- 是一個關于CVS信息的全面資料。
有大量的可用在許多平臺上CVS 附加工具,它們給 CVS增加了功能或使得CVS更容易使用。
?????? SWT-"Standard Widget Toolkit",它是一個Java平臺下開放源碼的Native GUI組件庫,也是Eclipse平臺的UI組件之一。從功能上來說,SWT與AWT/SWING是基本等價的。SWT以方便有效的方式提供了便攜式的(即Write Once,Run Away)帶有本地操作系統觀感的UI組件。
?????? 由于widget系統的固有復雜性以及平臺之間微妙的差異,即使在理想情況下,能夠達到工業標準的跨平臺的widget類庫也是很難編寫和維護的。最早的AWT組件現在被認為是樣貌丑陋的,而且存在很多問題;SWING組件雖然也是缺點多多,但是隨著JDK版本的不斷升高,它仍在不斷進行著改進。我認為,SWT在功能上與AWT/SWING不相伯仲,但是組件更為豐富,平臺表現穩定,BUG也相對較少。如果你的應用程序真的需要在多個平臺上運行,需要更為美觀的界面,又不那么依賴于其他基于AWT/SWING的圖形庫,那么SWT或許是一個比AWT/SWING更好的選擇。
=========================================
為什么要使用SWT?
SWT是一個IBM開發的跨平臺GUI開發工具包。至于為什么IBM要費勁自己另起爐灶開發一個GUI工具包,而不是使用Sun現有的由AWT, Swing, Java 2D, Java 3D等構成的Java GUI框架,那就說來話長了。(記得在一個BBS上讀過一個關于SWT起源的調侃類的帖子)。
在SWT之前,Sun已經提供了一個跨平臺GUI開發工具包AWT (Abstract Windowing Toolkit)。雖然AWT框架也使用的是原生窗口部件(native widgets),但是它一直未能突破LCD問題。LCD問題導致了一些主要平臺特征的遺失。如果你不明白的話(其實我也沒明白),換句話說,如果平臺A有窗口部件(widgets)1–40,而平臺B有窗口部件(widgets)20–25,那么跨平臺的AWT框架只能提供這兩個窗口部件集的交集。
為解決這個問題,Sun又創建了一個新的框架。這個框架不再使用原生窗口部件,而是使用仿真窗口部件(emulated widgets)。這個方法雖然解決了LCD問題,并且提供了豐富的窗口部件集,但是它也帶來了新的問題。例如,Swing應用程序的界面外觀不再和原生應用程序的外觀相似。 雖然在JVM中這些Swing應用程序已經得到了最大程度的性能改善,但是它們還是存在著其原生對應物所不具有的性能問題。并且,Swing應用程序消耗太多的內存,這樣Swing不適于一些小設備,如PDA和移動電話等。
IBM進行了嘗試以徹底解決AWT和Swing框架帶來的上述問題。最終,IBM創建了一個新的GUI庫,這就是SWT。SWT框架通過JNI來訪問原生窗口部件。如果在宿主(host)平臺上無法找到一個窗口部件,SWT就會自動地模擬它。
=====================================
Tags:java,rcp,jface,swt,ibm,eclipse,ui,gui
在JDK環境配置好的情況下,進行如下操作:
1.先下載最新版Derby數據庫
下載地址:http://db.apache.org/derby/
本人下載的是:db-derby-10.3.1.4-bin.zip
2.將db-derby-10.3.1.4-bin.zip解壓到一目錄下,我這里是才C:\Derby\db-derby-10.3.1.4-bin
3.查看“系統屬性”——“高級”——“環境變量”,在“系統變量”下面新建變量“DERBY_INSTALL”,值為第2步的路徑值C:\Derby\db-derby-10.3.1.4-bin
4.在CLASSPATH里增加“%DERBY_INSTALL%\lib\derby.jar;%DERBY_INSTALL%\lib\derbytools.jar;”內容
5.進入Derby安裝目錄“%DERBY_INSTALL%\frameworks\embedded\bin”,雙擊運行文件setEmbeddedCP.bat
6.測試Derby數據庫環境是否配置成功,打開命令提示符窗口,輸入信息“java org.apache.derby.tools.sysinfo”,如出現諸如下面的信息:
C:\Documents and Settings\Administrator>java org.apache.derby.tools.sysinfo
------------------ Java 信息 ------------------
Java 版本:??????? 1.5.0_12
Java 供應商:????? Sun Microsystems Inc.
Java 主目錄:????? C:\Program Files\Java\jdk1.5.0_12\jre
Java 類路徑:????? .;C:\Program Files\Java\jdk1.5.0_12\lib;C:\Program Files\Java
\jdk1.5.0_12\lib\dt.jar;C:\Program Files\Java\jdk1.5.0_12\lib\tools.jar;C:\Derby
\db-derby-10.3.1.4-bin\lib\derby.jar;C:\Derby\db-derby-10.3.1.4-bin\lib\derbytoo
ls.jar;C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\msbase.jar
;C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\mssqlserver.jar;
C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\msutil.jar;C:\Pro
gram Files\MySQL\mysql-connector-java-5.0.7-bin.jar;C:\Program Files\Apache Soft
ware Foundation\Tomcat 5.5\common\lib\servlet-api.jar;C:\Program Files\Libs\dom4
j-1.6.1.jar
OS 名:??????????? Windows XP
OS 體系結構:????? x86
OS 版本:????????? 5.1
Java 用戶名:????? Administrator
Java 用戶主目錄:C:\Documents and Settings\Administrator
Java 用戶目錄:??? C:\Documents and Settings\Administrator
java.specification.name: Java Platform API Specification
java.specification.version: 1.5
--------- Derby 信息 --------
JRE - JDBC: J2SE 5.0 - JDBC 3.0
[C:\Derby\db-derby-10.3.1.4-bin\lib\derby.jar] 10.3.1.4 - (561794)
[C:\Derby\db-derby-10.3.1.4-bin\lib\derbytools.jar] 10.3.1.4 - (561794)
------------------------------------------------------
----------------- 語言環境信息 -----------------
當前語言環境: [中文/中國 [zh_CN]]
找到支持的語言環境:[cs]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[de_DE]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[es]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[fr]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[hu]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[it]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[ja_JP]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[ko_KR]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[pl]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[pt_BR]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[ru]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[zh_CN]
???????? 版本:10.3.1.4 - (561794)
找到支持的語言環境:[zh_TW]
???????? 版本:10.3.1.4 - (561794)
------------------------------------------------------
Derby數據庫環境已經基本配置好了
本文作者:曦勤
要用開源數據庫Derby了,下面先轉篇入門級的文章,學習學習!
數據庫做為數據持久化存儲的重要手段怎么強度都不過分,但傳統的數據庫都比較龐大,需要安裝配置等,對于一些比較輕量級的應用來說有點象殺雞用牛刀一樣.
Derby做為一個開源的、純Java數據庫引起了越來越多的關注,它源自IBM的CloudScape,現在成了大名鼎鼎的Apache基金會的開源項目。Apache一項是開源項目的領導者,從他們手里出去的東西都很不錯,在此感謝一下這些無私奉獻的人們。
Derby做為嵌入式數據庫的一個方便之處就是對數據庫的一切操控都可以在Java程序代碼中實現,并且它非常的小,幾個jar文件總共才2M多,非常輕巧,非常便于我們程序的移植。下面說一步步的來說明一下怎樣使用。
首先,從http://db.apache.org/derby/下載Derby的最新版本,直接解壓到本地,然后設置程序運行的環境變量。
在win2000/xp中“我的電腦”--》右鍵--》屬性--》環境變量--》變量--》添加
1.設置JAVA_HOME
2.設置DERBY_INSTALL(一定要是這個名字,否則可能無法正常運行),值為解壓的目錄
環境變量設置好了之后,我們就可以著手寫第一個測試程序了。
和使用其它的數據庫一樣,首先加載數據庫驅動:
Class.forName("org.apachy.derby.jdbc.EmbeddedDriver");
然后我們創建一個數據庫:
Connection conn=DriverManager.getConnection("jdbc.derby.derbyDB;create=true","user","pwd");
在上面的Url中指定create=true,則創建一個新的數據庫。
得到連接之后,我們就可以象訪問其它數據庫一樣,進行相關操作了。
Statement st=conn.createStatement();
st.execute("create table test1(id int,name varchar(20));
st.execute("insert into test1 values(1,'sinboy')");
st.execute("inert into test1 values(2,'Tom')");
ResultSet rs=st.executeQuery("select * from test1");
while(rs.next){
?? System.out.println("id:"+rs.getInt(1)+" name:"+rs.getString(2));
}
rs.close();
st.close();
conn.commit();
conn.close();
Derby的最大好處應該還是小巧、純Java、好移植,比較適全小量的數據存儲。
做項目時,經常遇到要把數據庫的內容放到javascript里。不管是單個字符串(String),還是集合(array)。javascript不能直接從數據庫拿東西。所以只得借助一些其他條件。比如在頁面上的標簽里放id,name 之類的標志。
假如:
1,獲取字符串:
user.getName() 是一條單個的記錄。
<div id=a><%=user.getName() %></div>
那么javascript很容易獲取 : var jsa=???? document.getElementById("a").innerText; (注:innerHTML也可以獲取。)
2,獲取集合,數組:
<form name="form1">
?????? <table>
????????????????? <%
???? Mgr mgr=new Mgr();
???? ArrayList list=mgr.getonebbs();
???? for(int i=0;i<list.size();i++)
???? {
?????? Ext role=(Ext)list.get(i);
????? %>
?????????????? <tr>
?????????????? <td id="cid<%=i %>"><%=role.getId()%></td>
?????????????? <td id="cname<%=i %>"><%=role.getName()%></td>
?????????????? <td id="cpass<%=i %>"><%=role.getPass()%></td>
?????????????? <td id="ctel<%=i %>"><%=role.getTel()%></td>
?????????????? </tr>
??????????? <%
????? }%>
???? <input type="hidden" value="<%=list.size() %>" name="hid" >
????? </table>
</form>
javascript獲取:
???????? var cc = document.getElementById("hid").value; //首先獲取長度,下面循環輸出
????????? var a=new Array();
??????????? var b=new Array();
????????????? var c=new Array();
??????????????? var d=new Array();
????????? var myData=new Array();
??????? for(var j=0;j<cc;j++)
??????? {
????????? a[j]= document.getElementById("cid"+j).innerText;
????????? b[j]= document.getElementById("cname"+j).innerText;
????????? c[j]= document.getElementById("cpass"+j).innerText;
????????? d[j]= document.getElementById("ctel"+j).innerText;
?????????????????? //????? alert(a+" "+b+" "+c+" "+d+" ");???? //測試
?????????????????? myData[j] =???? [a[j],b[j],c[j],d[j]] ;???
??????? }
這樣就把數組放到myData中去了。
3,總結:
先把輸出放到jsp頁面上,?????????????? //也就是把數據查詢出來
然后在js里面獲取jsp上的數據,???? //通過document.獲取。 單個,循環。
然后放到string 或者 array里面。//OK
反正感覺多做了2步似的,繞了個圈,不過沒辦法,人家都是這樣做的。。。
How to clone:
1. Implement the Cloneable interface, and
2. Redefine the clone method with the public access modifier.
Cloneable:
The Cloneable interface is one of a handful of tagging interfaces that Java provides.A tagging interface has no methods; its only purpose is to allow the use of instanceof in a type inquiry:
if (obj instanceof Cloneable) . . .
We recommend that you do not use this technique in your own programs.
Shallow copy:
Even if the default (shallow copy) implementation of clone is adequate, you still need to implement the Cloneable interface, redefine clone to be public, and call super.clone(). Here is an example:
class Employee implements Cloneable
{
?? // raise visibility level to public, change return type
?? public Employee clone() throws CloneNotSupportedException
?? {
????? return super.clone();
?? }
?? . . .
}
Deep copy:
class Employee implements Cloneable
{
?? . . .
?? public Object clone() throws CloneNotSupportedException
?? {
????? // call Object.clone()
????? Employee cloned = (Employee) super.clone();
????? // clone mutable fields
????? cloned.hireDay = (Date) hireDay.clone()
????? return cloned;
?? }
}
1 The clone method of the Object class threatens to throw a CloneNotSupportedException—it does that whenever clone is invoked on an object whose class does not implement the Cloneable interface. Of course, the Employee and Date class implements the Cloneable interface, so the exception won't be thrown.
2
public Employee clone()
{
?? try
?? {
????? return super.clone();
?? }
?? catch (CloneNotSupportedException e) { return null; }
?? // this won't happen, since we are Cloneable
}
This is appropriate for final classes. Otherwise, it is a good idea to leave the tHRows specifier in place. That gives subclasses the option of throwing a CloneNotSupportedException if they can't support cloning.
Use clone:
public static void main(String[] args) {
???? try {
??????? Employee original = new Employee("John Q. Public", 50000);
??????? original.setHireDay(2000, 1, 1);
??????? Employee copy = original.clone();
??????? copy.raiseSalary(10);
??????? copy.setHireDay(2002, 12, 31);
??????? System.out.println("original=" + original);
??????? System.out.println("copy=" + copy);
??? }
??? catch (CloneNotSupportedException e) {
??????? e.printStackTrace();
??? }
}
1。list方法。?? 將 Enumeration 類型轉換成list類型
2。swap方法。方便的調換一個list中的兩個元素的位置。
3。lastIndexOfSubList方法。從一個list中從后面開始查找另外一個list第一次出現的位置。
4。rotate方法。在一個list中,順序移動每一個元素的位置到指定的位置。
5。replaceAll方法。用指定的元素替換一個list中所用匹配的元素。
6。indexOfSubList方法。從一個list中從前面開始查找另外一個list第一次出現的位置。
示例程序:
import java.util.*;
class TestCollections {
public static void main(String[] args) {
TestCollections t = new TestCollections();
t.testList();
}
public void testList() {
Vector v = new Vector();
v.add("a");
v.add("b");
Enumeration e = v.elements() ;
List l = Collections.list(e);
System.out.println(l);
}
public void testSwap() {
List l = new ArrayList();
l.add("t");
l.add("a");
l.add("n");
l.add("k");
l.add("s");
System.out.println(l);
Collections.swap(l,1,3);
System.out.println(l);
}
public void testLastIndexOfSubList() {
List l = new ArrayList();
l.add("a");
l.add("b");
l.add("c");
l.add("d");
l.add("e");
l.add("a");
l.add("b");
l.add("c");
l.add("d");
l.add("e");
List l2 = new ArrayList();
l2.add("b");
l2.add("c");
l2.add("d");
int result = Collections.lastIndexOfSubList(l,l2);
if(result != -1) {
?? System.out.println("!!! " + result + ". Found from " + l + " with " + l2);
} else {
?? System.out.println("!!! Not found from " + l + " with " + l2);
}
List l3 = new ArrayList();
l3.add("b");
l3.add("d");
l3.add("d");
result = Collections.lastIndexOfSubList(l,l3);
if(result != -1) {
?? System.out.println("!!! " + result + ". Found from " + l + " with " + l3);
} else {
?? System.out.println("!!! Not found from " + l + " with " + l3);
}
}
public void testRotate() {
List l = new ArrayList();
l.add("t");
l.add("a");
l.add("n");
l.add("k");
l.add("s");
System.out.println(l);
Collections.rotate(l,1);
System.out.println(l);
//
?? l = new ArrayList();
l.add("t");
l.add("a");
l.add("n");
l.add("k");
l.add("s");
System.out.println(l);
Collections.rotate(l,-4);
System.out.println(l);
?? l = new ArrayList();
l.add("a");
l.add("b");
l.add("c");
l.add("d");
l.add("e");
System.out.println(l);
Collections.rotate(l.subList(1, 4), -1);
System.out.println(l);
}
public void testReplaceAll() {
List l = new ArrayList();
l.add("t");
l.add("a");
l.add("n");
l.add("a");
l.add("s");
System.out.println(l);
boolean b = Collections.replaceAll(l,"a","hello");
System.out.println(l);
System.out.println(b);
// not found
b = Collections.replaceAll(l,"a","hello");
System.out.println(b);
}
public void testIndexOfSubList() {
List l = new ArrayList();
l.add("a");
l.add("b");
l.add("c");
l.add("d");
l.add("e");
List l2 = new ArrayList();
l2.add("b");
l2.add("c");
l2.add("d");
int result = Collections.indexOfSubList(l,l2);
if(result != -1) {
?? System.out.println("!!! " + result + ". Found from " + l + " with " + l2);
} else {
?? System.out.println("!!! Not found from " + l + " with " + l2);
}
List l3 = new ArrayList();
l3.add("b");
l3.add("d");
l3.add("d");
result = Collections.indexOfSubList(l,l3);
if(result != -1) {
?? System.out.println("!!! " + result + ". Found from " + l + " with " + l3);
} else {
?? System.out.println("!!! Not found from " + l + " with " + l3);
}
}
}
如果你的很多時間是用來敲純文本,寫程序或HTML,那么有效地使用一個好的編輯器能節省你不少時間。這篇文章里的指導和提示將有助于你更快工作,更少犯錯誤。
文中采用開源文本編輯器Vim(Vi IMproved)說明有效編輯的思想,但這些思想也適用于其他編輯器。擇合適的編輯器只是有效編輯的第一步,對于哪個編輯器更好的討論將占很大地方,這里就不提了。如果你不知道該用哪個編輯器,或者對現在所使用的不太滿意,不妨試試Vim;你是不會失望的。
第一部分:編輯一個文件
快速定位
編輯中大部分時間是花費在閱讀、查錯和尋找應該進行編輯的地方上,而不是插入新文字或進行修改。在文件中不斷定位(navigate)是經常要做的,所以最好學會如何快速地進行。
你常會搜尋文檔中的一些文字。或者找出包含特定詞或詞組的行。你當然可以使用搜尋命令 /pattern,不過還有更聰明的方法:
* 如果你看到一個特定詞,想看看其他地方是不是出現過同樣的詞,可以使用* 命令。它將對光標所指的詞進行搜尋。
* 如果設置了 ' incsearch' 選項,Vim將在你正在輸入搜尋模式的時候就顯示搜尋的結果(而不是等到你敲了回車之后)。這能夠使你更快地找出拼寫錯誤。
* 如果設置了 ' hlsearch' 選項,Vim將使用黃色背景對搜尋結果進行高亮顯示。你可以對搜尋的結果一目了然。應用在程序代碼中可以顯示變量的所有引用。你甚至不需要移動鼠標就能看到所有的搜尋結果。
對于結構化的文檔,快速定位的辦法就更多了。Vim提供專門針對C程序(以及C++、Java等等)的特殊命令:
* 使用 %可以從開始括號跳到對應的關閉括號。或者從 ``#if'' 跳到對應的 ``#endif''。事實上, % 可以完成許多對應項之間的跳轉。可以用來檢查if()和{}結構是否平衡。
* 使用 [{可以在代碼段(block)中跳回到段起始的 ``{``。
* 使用 gb 可以從引用某個變量的地方跳轉到它的局部聲明。
定位的方法當然不止這些。關鍵是你需要知道有這些命令。你也許會說不可能學會所有命令 — Vim里有成百個定位命令,有的很簡單,有的很聰明 — 這需要幾星期的學習。不過,你不必如此;你只需要了解自己的編輯特點,然后掌握相關的定位命令就可以了。
可以采取三個基本步驟:
1. 在你進行編輯的時候,注意那些重復進行的操作。
2. 找出能快速進行這些操作的編輯命令。閱讀文檔,問問朋友,或者看看其他人是如何做的。
3. 進行練習,知道熟練為止。
讓我們通過以下這個例子說明一下:
1. 你發現在寫C程序時,經常要查找函數定義。你目前使用 * 命令對函數名進行搜尋,但得到的往往是函數的引用而不是函數定義。你覺得一定會有更好的辦法。
2. 讀過一篇快速參考以后,你發現關于定位標記的說明,里面說明了如何定位函數定義,這正是你要找的!
3. 你試著生成了一個標記文件,使用Vim自帶的ctags程序。你學會了使用CTRL-] 命令,發現這省了不少事。為了更方便,你在 Makefile 里加入了幾行以自動生成標記文件。
當你使用以上三個步驟時,有幾點需要注意的地方:
* ``我只想完成任務,不想去讀那些文檔來找新的命令。''。如果你真的是這么想的,那么你將永遠停留在計算的石器時代。有些人編寫什么都用Notepad,卻總不明白為什么其他人總能用他一半的時間成任務。
* 不要過分。如果你總為一點小事也要去找完美的命令,你就沒法集中精力到你本要完成的任務上了。只要找出那些耗費過多時間的操作,然后使用相關的命令直到熟練就可以了。這以后你就能集中精力到自己的文檔上了。
下面這些章節給出了大多數人遇到的操作。你仿照它們在實際工作中使用
三個基本步驟
不要敲兩次
我們所使用的字詞集合是有限的。既使是詞組和句子也不過是有限的幾個。對于程序來說更是如此。很明顯,你不想把同樣的東西敲上兩遍。
你經常會想把一個詞替換成另一個。如果是全文件替換,你可以使用:s (substitute)命令。如果只是幾個位置需要被替換,一個快速辦法是使用 * 命令找出下一個詞,使用 cw 來進行替換。然后敲n 找到下個詞,再用 . 重復 cw 命令。
. 命令重復上一個改變。這里的改變是插入、刪除或替換操作。能夠重復進行操作是個極為強大的機制。如果好好使用它,那么你大部分的編輯工作可能只不過是敲幾下 . 的事。小心不要在兩次重復之間做其他修改,因為這將改變你要重復的操作。如果確實需要如此,可以使用 m 命令記住要修改的位置,等重復操作進行完畢之后再回過頭來修改它。
有些函數名和變量名可能很難敲。你能準確無誤地輸入``XpmCreatePixmapFromData''么?Vim的自動補齊機制能給你省不少事。它查看你正在編輯的文件以及#include文件,你可以只敲入``XpmCr'',然后使用CTRL-N 命令讓Vim把它補齊為``XpmCreatePixmapFromData''。這不但節省了輸入時間,而且減少了輸入的錯誤。
如果你有同樣的詞組或句子需要輸入多次,還有個更簡單的辦法。Vim可以進行錄制宏。使用 qa 命令開始在'a'寄存器里錄制宏。然后正常地輸入編輯命令,最后用 q 退出錄制狀態。如果你想重復所錄制的命令,只需執行 @a 命令。Vim總共提供26個這樣的宏寄存器。
使用宏錄制功能可以記錄各種操作,不只限于插入操作。如果你想重復一些東西,不妨一試。
需要注意的是記錄的命令會被原封不動地重復執行。在進行定位時簡單的重復宏操作可能不是你想要的結果。比如對于一個詞這里可能需要左移4個字符,在下個地方可能就要左移5個字符。所以必須定位到合適的位置再重復進行宏操作。
如果你要重復的命令很復雜,把它們一次敲進去會很困難。這時你可以寫一個腳本或宏。這常被用于建立代碼模板;比如,一個函數頭。你想做得多聰明就可以做得多聰明。
知錯就改
編輯時經常會出錯。無人能免。關鍵是快速發現并進行改正。編輯器應該提供這方面的支持,不過你必須告訴它什么是對什么是錯。
你可能常常會重復同樣的錯誤,你的手指所做的并非是你要它做的。可以使用縮寫(abbreviation)進行修正。下面是一些例子:
* :abbr Lunix Linux
* :abbr accross across
* :abbr hte the
這些詞會在編輯時被自動改正。
同樣的機制也可以用于對很長的詞語進行縮寫。特別適用于輸入那些你覺得很難敲的詞,它可以避免出錯。比如:
* :abbr pn pinguin
* :abbr MS Mandrake Software
但有時候你想要的正是那些縮寫,比如想插入``MS''。所以縮寫中最好使用那些不會出現在文中的詞。
Vim提供了一個很聰明的高亮機制,一般用于程序的語法高亮,不過也可以用來查錯。
語法高亮會使用顏色顯示注釋。這聽上去不是什么特別重要的功能,不過一旦用起來就會發現這其實很有用。你能夠快速地發現那些沒有高亮卻本應作為注釋的文字(可能是因為忘了敲注釋符)。也可以發現一些被錯誤當成注釋的代碼(可能是因為忘了敲``*/'')。這些錯誤在黑白方式下是很難被發現的,浪費了不少調試時間。
語法高亮也可以用來查找不匹配的括號。一個未被匹配的``)''會被亮紅色背景加以標識。你可以使用 % 命令他們是被如何匹配的,然后把``(''或``)''插入到合適的位置。
另一類常犯的錯誤也很容易發現,比如把 ``#include <stdio.h>''敲成了``#included <stdio.h>''。在黑白方式下這是很難發現的,但在語法高亮下則能很快發現``include''能被高亮而``included''沒有。
再看一個更復雜的例子:對于英文文本你可以定義一個所要使用的詞的長列表。所有未在表中出現的詞都可能是錯誤,并進行高亮顯示。可以定義幾個用于編輯詞表的宏。這正是字處理器的拼寫檢查功能。Vim中是靠一些腳本來實現的,你也可以對它進行定制:比如,只對注釋中的文字進行拼寫檢查。
第二部分:編輯多個文件
文件總是成幫結伙
人們很少只編輯一個文件。一般需要順序或同時編輯一些相關的文件。你應該利用編輯器使多文件編輯工作更為高效地。
上面提到的標識(tag)機制也支持跨文件搜尋。一般做法是為項目的所有文件生成標識文件,然后在項目的所有文件中搜尋函數、結構、類型(typedef)等的定義。這比手工搜尋要快捷的多;我瀏覽一個程序要做的第一件事便是建立標識文件。
另一個強大的功能是使用 :grep 命令對一組文件進行模式搜尋。Vim把搜尋結果做成一個列表,然后跳到第一個結果。使用 :cn 命令跳到下一個結果。如果你想改變一個函數調用的、參數個數,那么這個功能會很有用。
頭文件里有很多有用的信息。然而要知道一個聲明出現在哪個頭文件中卻需要花不少時間。Vim能夠理解頭文件,能夠從中找到你需要的東西。把光標移動到函數名下,然后敲 [I:Vim就會顯示出一個頭文件中該函數名的所有匹配。
如果你想得到更詳細的結果,可以直接跳到聲明中。一個類似的命令可以用于檢查你所使用的頭文件是否正確。
你可以把Vim的編輯區域進行分隔,用來編輯不同的文件。你可以對兩個或多個文件進行比較,或者進行拷貝/粘貼。有許多命令用于打開關閉窗口,文件間跳轉,暫時隱藏文件等等。可以再使用上面提到的三個基本步驟選擇合適的命令進行學習。
多窗口還有更多的用法。預覽標識(preview-tag)就是個很好的例子。它打開一個特殊的預覽窗口,光標還保留在你正在編輯的文件中。預覽窗口中可以是光標所指函數的聲明。如果你移動光標到另一個名字下,停留一兩秒,預覽窗口中就會顯示那個名字的定義。名字還可以是頭文件中聲明的結構或函數。
讓我們一起來工作
編輯器可以編輯文件。e-mail程序可以收發消息。操作系統可以運行程序。每個程序都有它自己的任務,而且應該做好。如果能讓程序一同工作,那么就會實現很強大的功能。
舉個簡單的例子:選擇一個列表中的結構化的文字,并對它進行排序:!sort。這將使用外部命令``sort''來過濾文件。容易吧?排序功能是可以添加到編譯器中的。不過看一下``man sort''就知道它有很多選項。它可能用了一個極為精巧的排序算法。你還打算把它加到編輯器中么?更何況還有其他不少過濾程序。編輯器可能會變得很大。
Unix精神的一個體現就是提供獨立的程序,各自做好自己的任務,然后組合起來完成更大的任務。不幸的是,許多編輯器不能很好地和其他程序一起工作,比如,你不能包Netscape的郵件編輯器換成其他編輯器。這樣你只能使用那個不順手的程序。另一個趨勢是在編輯器里提供所有的功能,Emacs就是個代表(有人說Emacs其實是個操作系統,只是可以用來編輯文件)。
Vim盡力和其他程序集成,但這需要經過斗爭。目前Vim已經可以作為MS-Developer Studio和Sniff的編輯器。一些e-mail程序(比如Mutt)也支持外部編輯器。和Sun Workshop的集成工作正在進行中。總的來說這個領域還有待提高。將來我們會有一個大于其各部分總和的系統。
文本結構化
你可能經常會遇到有一些結構的文本,這些結構可能同于那些現有命令所支持的結構。這樣你不得不利用那些底層的``磚頭''創建你自己的宏和腳本。這里說明的就是這類更復雜的東西。
有個簡單的辦法可以加速編輯-編譯-修改這個循環。Vim提供 :make 命令,用于進行編譯,并且獲取錯誤輸出,把你帶到發生錯誤的地方進行修正。如果你使用了另一個編譯器,那么錯誤就無法被Vim獲得。如果不想自己動手,可以修改' errorformat'選項。告訴Vim錯誤是什么樣子,以及如何從中獲得文件名和行號。它支持復雜的gcc錯誤信息,所以應該也能支持其他編譯器。
有時處理一個新的文件類型只需要設置幾個選項或寫一些宏。比如,為了在man手冊中進行跳轉,你可以寫一個宏獲取光標下的詞,清除緩沖區,然后讀入新的man手冊。這是簡單而高效的參照(cross-reference)方法。
使用三個基本步驟,你可以更有效地處理各種結構化文件。只需要想想你想對文件采取的操作,然后找到相應的命令去用就是了。就這么簡單,你只要去做就成了。
第三部分:磨刀
養成習慣
要學會開車必須下功夫。這是不是你只騎自行車的原因么?當然不是,你會發現你必須花時間來獲得所需的技術。文本編輯也不例外。你需要學習新的命令,并使用它直至成為習慣。
另一方面,你不應該試圖學習編輯器提供的每個命令。這是徹底的浪費時間。大多數人只需要學習10%到20%的命令就足夠工作了。但是每個人所需要的命令都各不相同。你需要不斷學習,找出那些可以自動完成的重復操作。如果你只做一次操作,而且以后也不會再去做,那么就不需要進行優化。是如果你發現你在過去的一小時中重復了好幾遍同樣的操作,那么就有必要查看一下手冊,看看能否更快速地完成。或者寫一個宏來做。如果是是個不小的任務,比如對一類文本進行對齊,你需要閱讀一下新聞組或看看Internet上是不是有人已經解決了同樣的問題。
最根本的步驟是最后的那一個。你可能能夠找到一個重復性的任務,找到一個不錯的作法,可過了一個周末就徹底忘了自己是怎么做的了。這不成。你必須重復你的作法直到爛熟于胸。只有這時你才真正獲得了你需要的高效。一次不要學得太多。一次只試一些工作得很好的方法。對于那些不常用的技巧,你可能只需要把它記下來,留待以后查閱。總之,如果抱著這樣的目標,你的編輯技能就會更加有效。
最后需要指出的是,如果人們忽略了以上幾點會發生什么:我仍然可以看到有人盯著屏幕看上半天,用兩個指頭敲幾下,然后繼續抬頭看著屏幕,還抱怨自己太累.. 把十個指頭都用上!這不光更快,還不累。每天抽出一個小時練習一下指法,只要幾星期就足夠了。
后記
書名得益于Stephen R. Covey所著的那本暢銷書《高效人的七種習慣》(``The 7 habits of highly effective people'')。
關于作者
Bram Moolenaar是Vim的主要作者。他編寫了Vim核心功能,并采納了許多開發者提供的代碼。他的e-mail地址是:Bram@Moolenaar.net