Apache Derby

Apache Derby是Apache軟件基金會所研發的開放源碼資料庫管理系統；由於Derby是一個純Java程式，因此只需要操作系統支援Java虛擬機，Derby便可執行。

**特性**
Derby是特別地為Java環境進行優化，Derby本身不僅是一個純Java程式，而且Derby在執行用戶的SQL程式時，能夠把SQL編譯成Java bytecode並以系統的Java虛擬機執行。由於SQL程式轉成的Java bytecode能被JIT動態翻譯，因此Derby可能比傳統的資料庫管理系統更佳的性能。
其他特性包括：- 支援主從架構或 嵌入環境- 多線程- ACID- Java數據庫連接（JDBC）- 低系統需求：約佔2 MB的硬盤空間，壓縮後更只是600KB  

**商業的版本**
 Cloudscape － IBM的Derby版本。- Java DB － 昇陽電腦自Java 6把Derby包括於JDK。

**安裝**
下載解壓後，只需要配置好相關的環境變量：
#建立DERBY_HOME，值例：D:\db-derby-10.10.2.0-bin  
#在Path加入：%DERBY_HOME%\bin  
#在CLASSPATH加入：%DERBY_HOME%\lib\derby.jar;%DERBY_HOME%\lib\derbyclient.jar;%DERBY_HOME%\lib\derbytools.jar;%DERBY_HOME%\lib\derbynet.jar - derby.jar 是引擎庫。對嵌入式是必須的；對客戶/服務器模式，服務器端必須此庫 - derbytools.jar 是Derby工具庫，如ij, dblook, import/export- derbyoptionaltools.jar- derbynet.jar 通過網絡服務器連接Derby（非嵌入方式） - derbyclient.jar: 網絡客戶端啟動程序- derbyrun.jar: 執行jar文件用於簡便地啟動Derby工具或服務器。需要與其他jar文件在同一目錄下
**java -jar %DERBY_HOME%\lib\derbyrun.jar ij -p propertiesfile sql_script
**java -jar %DERBY_HOME%\lib\derbyrun.jar sysinfo -cp ... -cp help
**java -jar %DERBY_HOME%\lib\derbyrun.jar dblook arg* (or no arguments for usage)
**java -jar %DERBY_HOME%\lib\derbyrun.jar server arg* (or no arguments for usage)

**使用**
sysinfo或java org.apache.derby.tools.sysinfo  查看安裝信息版本
啟動derby的網絡服務器，默認監聽127.0.0.1的1527端口，可以修改監聽的IP和PORT
java org.apache.derby.drda.NetworkServerControl start -p 1388  #指定端口
或者
startNetworkServer -h myhost -p 1388   #指定ip和端口
或者
java -jar derby/lib/derbyrun.jar server start
dblook工具是一個Data Definition Language (DDL)生成工具，可以卸載（dump）所有或部分用戶指定的DDL到一個文件或控制檯。
啟動JDBC客戶端工具ij，可以執行SQL腳本或者交互式查詢：
ij或java org.apache.derby.tools.ij 或 java -jar derby/lib/derbyrun.jar ij -p ij.properties
ij命令行參數：
ij -Dij.connection.mynetconnection=jdbc:derby://myserver:1527/mydb -Dij.user=me -Dij.password=nocansay
也可以創建一個名為ij.properties，用於默認連接數據庫：
ij.driver=org.apache.derby.jdbc.ClientDriver
ij.protocol=jdbc:derby://localhost:1527/
ij.database=COREJAVA;create=true
或者先設置環境變量：
set DERBY_OPTS=-Dij.protocol=jdbc:derby://localhost/ date=20220427102732 
在ij客戶端工具內部，不區分大小寫，每條命令都應以分號結尾。
連接數據庫並在必要時創建數據庫：
connect 'jdbc:derby:mydb;create=true;user=test;password=test';   //創建/連接嵌入式數據庫,
//如果只寫數據庫名則會在當前目錄下創建數據庫目錄
//也可以指定其他位置進行創建"jdbc:derby:d:/a/b/userDB;create=true;user=test;password=test"
connect 'jdbc:derby://host:1527/dbname;create=true';    //創建/鏈接網絡數據庫
查看ij的命令：
help;
運行sql文件：
run 'D:/derby/demo/ToursDB_schema.sql'  RunResultOutput.txt；
斷開數據庫連接（並停止內嵌模式數據庫）
disconnect;
退出客戶端：
exit ;
關閉數據庫服務器：
java -jar derby/lib/derbyrun.jar server shutdown
命令行當前目錄中derby.log日誌文件，derby在其中記錄的數據庫啟動、關閉的信息。
Java程序訪問Derby數據庫：
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class EmbeddedDerbyTester {
public static void main(String args) {
String driver = "org.apache.derby.jdbc.EmbeddedDriver";//在derby.jar裡面
String dbName="EmbeddedDB";
String dbURL = "jdbc:derby:"+dbName+";create=true";//create=true表示當數據庫不存在時就創建它
try {            
Class.forName(driver);
Connection conn = DriverManager.getConnection(dbURL);//啟動/連接嵌入式數據庫
Statement st = conn.createStatement();
st.execute("create table foo (FOOID INT NOT NULL,FOONAME VARCHAR(30) NOT NULL)");//創建foo表
st.executeUpdate("insert into foo(FOOID,FOONAME) values (1,'chinajash')");//插入一條數據
ResultSet rs = st.executeQuery("select * from foo");//讀取剛插入的數據
while(rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
System.out.println("id="+id+";name="+name);
}
} catch(Exception e){
e.printStackTrace();
}
}
}
啟動Derby網絡服務器的Java程序：
package test;
import java.io.PrintWriter;
import java.sql.DriverManager;
import org.apache.derby.drda.NetworkServerControl;
public class NetworkServerDerbyTester {
public static void main(String args) {
String driver = "org.apache.derby.jdbc.ClientDriver";//在derbyclient.jar裡面
String dbName="NetworkDB";
String connectionURL = "jdbc:derby://localhost:1527/" + dbName + ";create=true";
try {
/                啟動Derby網絡服務器,默認端口是1527,也可以通過運行
/frameworks/NetworkServer/bin/startNetworkServer.bat
來啟動Derby網絡服務器；如果是Unix,用startNetworkServer
*/
NetworkServerControl derbyServer = new NetworkServerControl();//NetworkServerControl類在derbynet.jar裡面
PrintWriter pw = new PrintWriter(System.out);//用系統輸出作為Derby數據庫的輸出
derbyServer.start(pw);//啟動Derby服務器
Class.forName(driver);
DriverManager.getConnection(connectionURL);
//do something here..........
derbyServer.shutdown();//關閉Derby服務器
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

**Schema實現**
Apache Derby數據庫（即Java DB）的任何connection的當前schema，默認是對應於該用戶名的一個schema。如果無用戶名被提供，那麼當前用戶名與當前schema缺省是APP。
但即使當前schema被設置為用戶名，這個schema仍然可能不存在。一個schema只能被創建：通過CREATE SCHEMA語句顯式創建或者創建一個對象（例如表等）來隱式創建。
APP schema總是存在，不需要創建。
如果你的程序試圖訪問當前schema但該schema下沒有創建任何對象，就會遇到“schema not exists”錯誤。

**註釋**

**參見**
 Berkeley DB Java Edition - 另一純Java資料庫管理系統。

**外部連結**
   Derby官方網站date=20120706161125 -   Cloudscape官方網站-   Java DB官方網站 date=20120513203304 -   Apache Derby 項目資源 (IBM) date=20161111210954