derby官方:http://db.apache.org/derby/
derby學習資料1:http://www.oschina.net/code/snippet_12_71
derby學習資料2:http://hotpepper.javaeye.com/blog/237831
以下內容來自互連網,非個人所總結。
http://jerryqiu.javaeye.com/blog/640263Derby資料庫是一個純用Java實現的記憶體資料庫,屬於Apache的一個開源項目。由於是用Java實現的,所以可以在任何平台上運行;另外一個特點是體積小,免安裝,只需要幾個小jar包就可以運行了。
Derby資料庫有兩種運行模式:
1) 內嵌模式。Derby資料庫與應用程式共用同一個JVM,通常由應用程式負責啟動和停止,對除啟動它的應用程式外的其它應用程式不可見,即其它應用程式不可訪問它;
2) 網路模式。Derby資料庫獨佔一個JVM,做為伺服器上的一個獨立進程運行。在這種模式下,允許有多個應用程式來訪問同一個Derby資料庫。
在Apache上,Derby有4種發布包,這裡以bin發布包為例。bin發布包中含有包含了執行derby資料庫工具、設定derby資料庫環境的指令檔、Demo、jar檔案等。1、 安裝Derby資料庫
只需要從Derby官方網站下載Derby的zip或者tar包,解壓就可以了。這裡以db-derby-10.4.1.3-bin版本為例,解壓後得到以下目錄:
1) bin目錄,包含了一些工具指令碼和裝置環境的指令碼;
2) demo目錄,包含了一些執行個體程式;
3) docs目錄,包含了Derby的文檔;
4) javadoc目錄,包含了Derby的API文檔;
5) lib目錄,包含了Derby資料庫的jar檔案;
6) test目錄,Derby的一些測試jar包;
2、 使用Derby指令碼
Derby提供了幾個指令碼來操作Derby資料庫,在使用這些指令碼前,你必須先設定好Derby的運行環境。
下面的例子都是在命令列下設定環境變數,這些設定都是臨時的,如果你新開一個命令列視窗,則需要重新設定一遍,如果想要使環境變數永久生效,可以在我的電腦中進行設定。
首先設定好DERBY_HOME這個環境變數,為DERBY_HOME指定你的derby目錄,假如你的derby解壓到了E:/ db-derby-10.4.1.3-bin目錄下,則可以在命令列中如下設定:
set DERBY_HOME=E:/ db-derby-10.4.1.3-bin
將DERBY_HOME/bin目錄添加到PATH環境變數中:
set path=%DERBY_HOME%/bin;%PATH%
這樣可以簡化你稍後在命令列中的輸入,否則你每次都必須使用指令碼的全路徑或者你必須到DERBY_HOME/bin目錄中才能執行指令碼。
最後需要Derby的jar包添加到classpath環境變數中,在DERBY_HOME%/bin目錄中提供了幾個指令碼用於設定classpath,以簡化你手工在classpath中添加jar包的麻煩:
1) setEmbeddedCP。當使用內嵌模式來運行Derby時,可以使用該指令碼來設定。該指令碼將derby.jar和derbytools.jar添加到環境變數中;
2) setNetworkServerCP。當使用網路模式來運行Derby時,用該指令碼來設定Derby服務端的classpath變數。該指令碼將derbynet.jar添加到環境變數中;
3) setNetworkClientCP。當使用網路模式來運行Derby時,用該指令碼來設定Derby用戶端的classpath變數。該指令碼將derbyclient.jar和derbytools.jar添加到環境變數中。
一般只有當你通過derbyrun.jar來運行Derby工具時才會使用這些指令碼。
Derby提供了三個工具指令碼:1)sysinfo;2)ij;3)dblook。運行這三個指令碼時,如果你沒有設定classpath環境變數,這些指令碼會自動進行設定。
1) sysinfo
使用sysinfo可以顯示你的Java環境資訊和Derby的版本資訊。使用方法就是在命令列下直接輸入:
sysinfo.bat
2) dblook
使用dblook可以將全部或者部分資料庫的DDL定義匯出到控制台或者檔案中。使用方法:
dblook.bat –d <sourceDBUrl> [Options]
3) ij
使用ij工具來進行資料庫互動,執行SQL指令碼,如查詢、增刪改、建立表等等。在命令列下輸入:
ij.bat
即可啟動ij工具,然後就可以開始執行SQL指令碼了。當要退出ij工具時,在命令列下輸入
exit;
即可。
3、 使用ij指令碼
1) 運行內嵌模式的Derby資料庫
在命令列中輸入ij.bat後啟動ij工具。然後通過如下命令建立資料庫,並與資料庫建立串連:
connect ‘jdbc:derby:firstdb;create=true’;
通過connect命令可以與指定資料庫建立串連,通過一個JDBC URL來指定與哪個資料庫建立串連。ij命令是不區分大小寫。
參數中jdbc:derby是Derby資料庫的驅動協議;firstdb是資料庫命,由於沒有指定路徑,資料庫將會被建立在當前你命令列下所在的目錄下;create=true表示如果資料庫不存在,則建立該資料庫;“;”是ij命令的終止符。
當資料庫建立成功時,Derby會在當前你命令列下所在的目錄下建立一個與資料庫命一致(這裡是firstdb)的目錄,其中存放了資料庫的檔案。
與資料庫連接上後,就可以開始執行SQL指令碼了,如建立一個表格:
create table firsttable(id int primary key, name varchar(20));
然後插入記錄:
insert into firsttable values(1, ‘Hotpepper’);
也可以執行查詢:
select * from firsttable;
也可以通過run命令來執行sql檔案:
run 'E:/derby/demo/programs/toursdb/ToursDB_schema.sql';
最後通過exit;來退出ij工具。
你可以在當前你命令列下所在的目錄中找到一個derby.log的記錄檔,derby在其中記錄的資料庫啟動、關閉的資訊。
2) 運行網路模式的Derby資料庫
這種模式下,需要使用兩個控制台視窗,一個用於啟動Derby資料庫服務端,另一個做為訪問Derby資料庫的用戶端。
可以通過DERBY_HOME/bin目錄下的startNetworkServer.bat來啟動Derby資料庫服務端,只需要在命令列中輸入:
startNetworkServer.bat
資料庫就啟動了,啟動成功會在控制台輸出如下資訊:
已使用基本伺服器安全性原則安裝了安全管理程式。
Apache Derby Network Server - 10.4.1.3 - (648739) 已啟動並且已準備好 2008-09-06
00:38:12.540 GMT 時在連接埠 1527 上接受串連
在另一個控制台使用ij命令訪問Derby資料庫服務端,在輸入ij.bat啟動ij工具後,通過如下命令建立與服務端的串連,並建立一個資料庫:
connect 'jdbc:derby://localhost:1527/seconddb;create=true';
參數中的資料庫命部分和內嵌模式不同,這裡使用了“//localhost:1527/”,訪問網路模式的URL需要指定伺服器的IP地址和連接埠,其它的就和內嵌模式一樣了。
與服務端串連上後,就可以開始執行SQL指令碼了,如建立一個表格:
create table firsttable(id int primary key, name varchar(20));
然後插入記錄:
insert into firsttable values(1, ‘Hotpepper’);
也可以執行查詢:
select * from firsttable;
也可以通過run命令來執行sql檔案:
run 'E:/derby/demo/programs/toursdb/ToursDB_schema.sql';
最後通過exit;來退出ij工具
4、 在Java應用程式中訪問Derby資料庫
使用Java代碼訪問Derby資料庫與訪問其它資料庫的區別如下:
1) JDBC驅動的不同;
2) 資料庫連接URL的不同;
3) 在訪問內嵌模式資料庫時,需要顯示關閉資料庫。
下面分別執行個體訪問內嵌模式和網路模式Derby資料庫的代碼
1) 訪問內嵌模式Derby資料庫
String driver = “org.apache.derby.jdbc.EmbeddedDriver”;
String url = “jdbc:derby:firstdb;create=true”;
Connection conn;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url);
}catch(Exception e) {
……
}finally {
……
DriverManager.getConnection("jdbc:derby:;shutdown=true");
}
建立好串連後,其它的資料操作,如查詢、更新資料都和其它資料庫一樣,這裡不詳述。有一點需要注意,通過Java應用程式訪問內嵌模式Derby資料庫時,應用程式有責任需要在程式結束時關閉Derby資料庫,如上面代碼finally中的
DriverManager.getConnection("jdbc:derby:;shutdown=true");
shutdown參數用於關閉Derby資料庫,如果url中指定了資料庫命,則只會關閉指定的資料庫,而不會關閉整個Derby資料庫。資料庫關閉成功時,Derby會拋出一個錯誤碼為XJ015和一個08006的異常表示關閉成功,應用程式可以不處理這兩個異常。
2) 訪問網路模式Derby資料庫
網路模式和內嵌模式的不同出在於:
A. 資料庫連接URL的不同;
B. 應用程式退出時無效關閉Derby資料庫;
C. 資料庫驅動的不同;
String driver = “org.apache.derby.jdbc.ClientDriver”;
String url = “jdbc:derby: //localhost:1527/firstdb;create=true”;
Connection conn;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url);
}catch(Exception e) {
……
}
由於網路模式下,Derby資料庫做為一個獨立啟動並執行資料庫,可以被多個應用程式所訪問,所以應用程式在運行結束時不應該關閉Derby資料庫。5、 使用derbyrun.jar
通過derbyrun.jar也可以使用上面提到的sysinfo、ij、dblook三個指令碼的功能,在使用derbyrun.jar前,除了DERBY_HOME環境變數外,你必須顯示設定好classpath環境變數,可以通過上面提到的setEmbeddedCP、setNetworkServerCP、setNetworkClientCP幾個指令碼來設定,具體使用哪個指令碼取決於你如何使用Derby資料庫。
可以通過java –jar %DERBY_HOME%/lib/ derbyrun.jar來運行derbyrun中的工具:
1) 使用sysinfo。java –jar %DERBY_HOME%/lib/ derbyrun.jar sysinfo
2) 使用ij。java –jar %DERBY_HOME%/lib/ derbyrun.jar ij
3) 使用dblook。java –jar %DERBY_HOME%/lib/ derbyrun.jar dblook
6、新安裝了 JDK 6 的程式員們也許會發現,除了傳統的 bin、jre 等目錄,JDK 6 新增了一個名為 db 的目錄。這便是 Java 6 的新成員:Java DB。這是一個純 Java 實現、開源的資料庫管理系統(DBMS),源於 Apache 軟體基金會(ASF)名下的項目 Derby。它只有 2MB 大小,對比動輒上 G 的資料庫來說可謂袖珍。但這並不妨礙 Derby 功能齊備,支援幾乎大部分的資料庫應用所需要的特性。更難能可貴的是,依託於 ASF 強大的社區力量,Derby 得到了包括 IBM 和 Sun 等大公司以及全世界優秀程式員們的支援。這也難怪 Sun 公司會選擇其 10.2.2 版本納入到 JDK 6 中,作為內嵌的資料庫。這就好像為 JDK 注入了一股全新的活力:Java 程式員不再需要耗費大量精力安裝和設定資料庫,就能進行安全、易用、標準、並且免費的資料庫編程。在這一章中,我們將初窺 Java DB 的世界,來探究如何使用它編寫出功能豐富的程式。
Hello, Java DB:內嵌模式的 Derby
既然有了內嵌(embedded)的資料庫,就讓我們從一個簡單的範例開始,試著使用它吧。這個程式做了大多數資料庫應用都可能會做的操作:在 DBMS 中建立了一個名為 helloDB 的資料庫;建立了一張資料表,取名為 hellotable;向表插入入了兩條資料;然後,查詢資料並將結果列印在控制台上;最後,刪除表和資料庫,釋放資源。
public class HelloJavaDB {
public static void main(String[] args) {
try { // load the driver
Class.forName("org.apache.derby.jdbc.隨後,我們在命令列(本例為 Windows 平台,當然,其它系統下稍作改動即可)下鍵入以下命令:
清單 2. 運行 HelloJavaDB 命令
java –cp .;%JAVA_HOME%dblibderby.jar HelloJavaDB
圖 1. HelloJavaDB 程式的執行結果
上述的程式和以往沒什麼區別。不同的是我們不需要再為 DBMS 的配置而勞神,因為 Derby 已經自動地在目前的目錄下建立了一個名為 helloDB 的目錄,來物理地儲存資料和日誌。需要做的只是注意命名問題:在內嵌模式下驅動的名字應為 org.apache.derby.jdbc.EmbeddedDriver;建立一個新資料庫時需要在協議後加入 create=true。另外,關閉所有資料庫以及 Derby 的引擎可以使用以下代碼:
清單 3. 關閉所有資料庫及 Derby 引擎
DriverManager.getConnection("jdbc:derby:;shutdown=true");
如果只想關閉一個資料庫,那麼則可以調用:
清單 4. 關閉一個資料庫
DriverManager.getConnection("jdbc:derby:helloDB;shutdown=true ");
這樣,使用嵌入模式的 Derby 維護和管理資料庫的成本接近於 0。這對於希望專心寫代碼的人來說不失為一個好訊息。然而有人不禁要問:既然有了內嵌模式,為什麼大多數的 DBMS 都沒有採取這樣的模式呢?不妨做一個小實驗。當我們同時在兩個命令列視窗下運行 HelloJavaDB 程式。結果一個的結果與剛才一致,而另一個卻出現了錯誤, 2 所示。
圖 2. 內嵌模式的局限
錯誤的原因其實很簡單:在使用內嵌模式時,Derby 本身並不會在一個獨立的進程中,而是和應用程式一起在同一個 JAVA 虛擬機器(JVM)裡運行。因此,Derby 如同應用所使用的其它 jar 檔案一樣變成了應用的一部分。這就不難理解為什麼在 classpath 中加入 derby 的 jar 檔案,我們的樣本程式就能夠順利運行了。這也說明了只有一個 JVM 能夠啟動資料庫:而兩個跑在不同 JVM 執行個體裡的應用自然就不能夠訪問同一個資料庫了。
鑒於上述的局限性,和來自不同 JVM 的多個串連想訪問一個資料庫的需求,下一節將介紹 Derby 的另一種模式:網路伺服器(Network Server)。
網路伺服器模式
如上所述,網路伺服器模式是一種更為傳統的用戶端/伺服器模式。我們需要啟動一個 Derby 的網路伺服器用於處理用戶端的請求,不論這些請求是來自同一個 JVM 執行個體,還是來自於網路上的另一台機器。同時,用戶端使用 DRDA(Distributed Relational Database Architecture)協議串連到伺服器端。這是一個由 The Open Group 倡導的資料庫互動標準。圖 3 說明了該模式的大體結構。
由於 Derby 的開發人員們努力使得網路伺服器模式與內嵌模式之間的差異變小,使得我們只需簡單地修改清單 1 中的程式就可以實現。如 清單 5所示,我們在 HelloJavaDB 中增添了一個新的函數和一些字串變數。不難看出,新的代碼只是將一些在 上一節中特別指出的字串進行了更改:驅動類為 org.apache.derby.jdbc.ClientDriver,而串連資料庫的協議則變成了 jdbc:derby://localhost:1527/。這是一個類似 URL 的字串,而事實上,Derby 網路的用戶端的串連格式為:jdbc:derby://server[:port]/databaseName[;attributeKey=value]。在這個例子中,我們使用了最簡單的本地機器作為伺服器,而連接埠則是 Derby 預設的 1527 連接埠。
圖 3. Derby 網路伺服器模式架構
清單 5. 網路伺服器模式下的 HelloJavaDB
public class HelloJavaDB {
public static String driver = "org.apache.derby.jdbc.Embedded當然,僅僅有用戶端是不夠的,我們還需要啟動網路伺服器。Derby 中控制網路伺服器的類是 org.apache.derby.drda.NetworkServerControl,因此鍵入以下命令即可。如果想瞭解 NetworkServerControl 更多的選項,只要把 start 參數去掉就可以看到協助資訊了。關於網路伺服器端的實現,都被 Derby 包含在 derbynet.jar 裡。
清單 6. 啟動網路伺服器
java -cp .;"C:Program FilesJavajdk1.6.0dblibderby.jar";
"C:Program FilesJavajdk1.6.0dblibderbynet.jar"
org.apache.derby.drda.NetworkServerControl start
相對應的,網路用戶端的實現被包含在 derbyclient.jar 中。所以,只需要在 classpath 中加入該 jar 檔案,修改後的用戶端就可以順利地讀取資料了。再一次嘗試著使用兩個命令列視窗去串連資料庫,就能夠得到正確的結果了。如果不再需要伺服器,那麼使用 NetworkServerControl 的 shutdown 參數就能夠關閉伺服器。
更多
至此,文章介紹了 Java SE 6 中的新成員:Java DB(Derby),也介紹了如何在內嵌模式以及網路伺服器模式下使用 Java DB。當然這隻是淺嘗輒止,更多進階的選項還需要在 Sun 和 Derby 的文檔中尋找。在這一章的最後,我們將簡單介紹幾個 Java DB 的小工具來加快開發速度。它們都位於 org.apache.derby.tools 包內,在開發過程中需要擷取資訊或者測試可以用到。
• ij:一個用來運行 SQL 指令碼的工具;
• dblook:為 Derby 資料庫作模式提取(Schema extraction),產生 DDL 的工具;
• sysinfo:顯示系統以及 Derby 資訊的工具類;Driver";
public static String protocol = "jdbc:derby:";
public static void main(String[] args) {
// same as before
}
private static void parseArguments(String[] args) {
if (args.length == 0 || args.length > 1) {
return;
}
if (args[0].equalsIgnoreCase("derbyclient")) {
framework = "derbyclient";
driver = "org.apache.derby.jdbc.ClientDriver";
protocol = "jdbc:derby://localhost:1527/";
}
}
}
EmbeddedDriver").newInstance();
System.out.println("Load the embedded driver");
Connection conn = null;
Properties props = new Properties();
props.put("user", "user1"); props.put("password", "user1");
//create and connect the database named helloDB
conn=DriverManager.getConnection("jdbc:derby:helloDB;create=true", props);
System.out.println("create and connect to helloDB");
conn.setAutoCommit(false);
// create a table and insert two records
Statement s = conn.createStatement();
s.execute("create table hellotable(name varchar(40), score int)");
System.out.println("Created table hellotable");
s.execute("insert into hellotable values('Ruth Cao', 86)");
s.execute("insert into hellotable values ('Flora Shi', 92)");
// list the two records
ResultSet rs = s.executeQuery(
"SELECT name, score FROM hellotable ORDER BY score");
System.out.println("namettscore");
while(rs.next()) {
StringBuilder builder = new StringBuilder(rs.getString(1));
builder.append("t");
builder.append(rs.getInt(2));
System.out.println(builder.toString());
}
// delete the table
s.execute("drop table hellotable");
System.out.println("Dropped table hellotable");
rs.close();
s.close();
System.out.println("Closed result set and statement");
conn.commit();
conn.close();
System.out.println("Committed transaction and closed connection");
try { // perform a clean shutdown
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException se) {
System.out.println("Database shut down normally");
}
} catch (Throwable e) {
// handle the exception
}
System.out.println("SimpleApp finished");
}
}
更多資料,參見:http://www.javaeye.com/wiki/topic/237831
下面代碼可以直接運行:
Code:
- package ttwork.derby;
-
- import java.sql.Connection;
-
- import java.sql.DriverManager;
-
- import java.sql.PreparedStatement;
-
- import java.sql.ResultSet;
-
- import java.sql.Statement;
-
- public class DerbyTest {
- static Connection conn;
- public static void main(String[] args) {
- String driver = "org.apache.derby.jdbc.EmbeddedDriver";
- String connectionURL = "jdbc:derby:myDatabase;create=true";
- String createString = "CREATE TABLE Employee2 (NAME VARCHAR(32) NOT NULL, ADDRESS VARCHAR(50) NOT NULL)";
- try {
- Class.forName(driver);
- } catch (java.lang.ClassNotFoundException e) {
- e.printStackTrace();
- }
- try {
- conn = DriverManager.getConnection(connectionURL);
- Statement stmt = conn.createStatement();
- stmt.executeUpdate(createString);
- PreparedStatement psInsert = conn
- .prepareStatement("insert into Employee2 values (?,?)");
- psInsert.setString(1, "123");
- psInsert.setString(2, "321");
- psInsert.executeUpdate();
- Statement stmt2 = conn.createStatement();
- ResultSet rs = stmt2.executeQuery("select * from Employee2");
- int num = 0;
- while (rs.next()) {
-
- System.out.println(++num + ": Name: " + rs.getString(1)
- + "/n Address" + rs.getString(2));
- }
- rs.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }