Contents
- 1 Derbyとは
- 2 サーバー構築
- 3 ローカル開発環境の構築
- 4 設定
- 5 運用
- 6 ツール
- 7 その他
- 8 アプリケーション開発
- 9 SQL
- 10 Derbyについて
- 11 パフォーマンスチューニング
Derbyとは
Derby(Apache Derby)とは100% Pure JavaのRDBMSである。
トランザクション等のRDBとして求められる機能一般は実装されている。
JDKにもバンドルされており、こちらはJava DBと呼ばれるが、基本的に同じものである。
最新のものを特別求めないのならこちらを使用しても問題ない。
Windows版のJDKにも同梱されており、実行できる。
DBサーバとしてネットワーク越しに使用もできるが、Javaアプリケーションに組み込んで使用することもできる。
主流な使用方法はこの組み込みの方である。
各種URL
サーバー構築
構築環境
- Derby
10.13.1.1
- OS
CentOS 7.3
- JAVA
1.8.0_131
OS設定
ネットワーク
固定IPアドレス割り当て
次のファイルを編集する
# ifcfg-loはループバックインタフェースであるため、触らない vi /etc/sysconfig/network-scripts/ifcfg-<インタフェース名>
以下では例として192.168.0.51/24を割り当てた
BOOTPROTO=static ONBOOT=yes IPADDR=192.168.0.51 NETMASK=255.255.255.0 NETWORK=192.168.0.0 GATEWAY=192.168.0.1
ネットワークを再起動する
systemctl restart network
ip addressコマンドにより、インタフェースが有効になっていることを確認する
これによりホストマシンなどからSSHでログイン可能となる
firewalld
Derbyのデフォルトポートである、TCP/1527を開ける。
接続元IPアドレス制限は行わない。
※CentOS7.2以前のCentOS7場合はfirewalldのバージョン場古く、下記を実行できない。アップデートすること。
yum update firewalld -y
- 現在ルールが定義されていないか確認
firewall-cmd --permanent --info-service=derby
- 新しいルールを定義
firewall-cmd --new-service=derby --permanent firewall-cmd --service=derby --add-port=1527/tcp --permanent
- ルールが定義されていることを確認
firewall-cmd --permanent --info-service=derby
- 現在ルールが適用されていないことを確認する
firewall-cmd --list-services --zone=public --permanent | sed -e "s/ /\n/g" | grep derby
- ルールを適用する
firewall-cmd --add-service=derby --zone=public --permanent
- ルールが適用されていることを確認する
firewall-cmd --list-services --zone=public --permanent | sed -e "s/ /\n/g" | grep derby
- 設定を再読み込みして反映させる
firewall-cmd --reload
IPを制限する場合
特定のIPアドレスからのみ接続可能に設定する場合は以下のようにする。
- 既にアクセス制限が設定されていないか確認
firewall-cmd --list-services --zone=public --permanent | sed -e "s/ /\n/g" | grep derby
- 現在サービスが定義されていないか確認
firewall-cmd --permanent --info-service=derby
- 新しいサービスを定義
firewall-cmd --new-service=derby --permanent firewall-cmd --service=derby --add-port=1527/tcp --permanent
- サービスが定義されていることを確認
firewall-cmd --permanent --info-service=derby
- 管理ゾ-ンが定義されていないか確認
firewall-cmd --permanent --info-zone=admin
- 管理ゾ-ンを定義
firewall-cmd --permanent --new-zone=admin
- 管理ゾ-ンが定義されていることを確認
firewall-cmd --permanent --info-zone=admin
- 接続元IPアドレス、接続先サービスを追加する
firewall-cmd --permanent --zone=admin --add-source=<IPアドレス> firewall-cmd --permanent --zone=admin --add-service=derby
- 管理ゾ-ンが適切に定義されていることを確認する
firewall-cmd --permanent --info-zone=admin
- 出力
[root@derby ~]# firewall-cmd --permanent --info-zone=admin admin (active) target: default icmp-block-inversion: no interfaces: sources: XXX.XXX.XXX.XXX services: derby ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
- 出力
- firewalldシステムを再起動して設定を反映させる
systemctl restart firewalld
- IPアドレスを変更する場合
- 現在のIPアドレスを確認する
firewall-cmd --permanent --zone=admin --list-sources
- IPアドレスを削除する
firewall-cmd --permanent --zone=admin --remove-source=<IPアドレス>
- IPアドレスを追加する
firewall-cmd --permanent --zone=admin --add-source=<IPアドレス>
- 現在のIPアドレスを確認する
firewall-cmd --permanent --zone=admin --list-sources
- firewalldシステムを再起動して設定を反映させる
systemctl restart firewalld
- 現在のIPアドレスを確認する
ホスト名
ホスト名としてderbyを設定する
hostname derby.corp # 再起動しても有効にする echo derby.corp > /etc/hostname
再ログインすることで有効になる。
Java環境の構築
DerbyのサーバではDerbyのみを動作させ、アプリケーションサーバ機能は持たせないので、JDKではなくJREをインストールする。
Derby自体もJDKに付属のものではなく、公式ページから最新のものをダウンロードして使用する。
ダウンロード
公式Webページ:http://www.oracle.com/technetwork/java/javase/downloads/index.html
今回は2017/05/09時点の最新版「JRE8u131」をダウンロードする。
展開するだけで使用できる圧縮版(jre-8u131-linux-x64.tar.gz)をダウンロードする。
ダウンロードの前に「Accept License Agreement」ラジオボタンにチェックを入れること。
ダウンロードの際はページに記載のハイパーリンク(http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jre-8u131-linux-x64.tar.gz)から
wgetしようとすると、エラーが発生するので、一旦PCでダウンロードを試み、それをキャンセル。
その際ダウンロードを行おうとしたURL(http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jre-8u131-linux-x64.tar.gz?AuthParam=XXXXXのようになる)をコピーし、そこから改めてwgetする。
※PCにダウンロードしてSCP転送でもよい
インストール
tar xzfv jre-*.tar.gz* rm -f jre-*.tar.gz* mv jre* /usr/local/ ln -s /usr/local/jre* /usr/local/jre
環境変数
環境変数を設定し、パスを通す。
export JAVA_HOME=/usr/local/jre export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
これによって「java」コマンドが実行できるようになったので、確認する。
java -version
- 実行例
[root@derby ~]# java -version java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-XXX) Java HotSpot(TM) 64-Bit Server VM (build XXXXXX, mixed mode)
更に再起動・再ログインしても自動で設定されるようにbashrcに設定を追加する。
echo "" >> /etc/bashrc echo "# JAVA ENVIRONMENT VARIABLE" >> /etc/bashrc echo export JAVA_HOME=/usr/local/jre >> /etc/bashrc echo export PATH=\$JAVA_HOME/bin:\$PATH >> /etc/bashrc echo export CLASSPATH=.:\$JAVA_HOME/lib/tools.jar:\$JAVA_HOME/lib/dt.jar >> /etc/bashrc
Derbyの構築
ダウンロード
ダウンロードページから最新のものをダウンロードする。
今回ダウンロードするバージョンのリンクはこちら。
wget http://ftp.riken.jp/net/apache//db/derby/db-derby-10.13.1.1/db-derby-10.13.1.1-bin.tar.gz
インストール
インストールは展開して任意の場所に配置するだけである。
tar xzfv db-derby-*.tar.gz rm -f db-derby-*.tar.gz mv db-derby* /usr/local/`ls | grep db-derby-* | sed -e "s/db-\|-bin.*//g"` ln -s /usr/local/*derby* /usr/local/derby cd /usr/local/derby
インストール確認
インストールできているか確認する。
bin/sysinfo
このコマンドを実行した際、インストールしたJavaとDerbyのバージョンが
表示されているか確認しておく。
- 実行例
[root@derby ~]# bin/sysinfo ------------------ Java Information ------------------ Java Version: 1.8.0_131 Java Vendor: Oracle Corporation Java home: /usr/local/jre1.8.0_131 Java classpath: /usr/local/derby/lib/derby.jar:/usr/local/derby/lib/derbynet.jar:/usr/local/derby/lib/derbytools.jar:/usr/local/derby/lib/derbyoptionaltools.jar:/usr/local/derby/lib/derbyclient.jar:.:/usr/local/jre/lib/tools.jar:/usr/local/jre/lib/dt.jar OS name: Linux OS architecture: amd64 OS version: 3.10.0-514.el7.x86_64 Java user name: root Java user home: /root Java user dir: /root java.specification.name: Java Platform API Specification java.specification.version: 1.8 java.runtime.version: 1.8.0_131-b11 --------- Derby Information -------- [/usr/local/db-derby-10.13.1.1-bin/lib/derby.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbytools.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbynet.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbyclient.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbyoptionaltools.jar] 10.13.1.1 - (1765088) ------------------------------------------------------ ----------------- Locale Information ----------------- Current Locale : [English/United States [en_US]] Found support for locale: [cs] version: 10.13.1.1 - (1765088) Found support for locale: [de_DE] version: 10.13.1.1 - (1765088) Found support for locale: [es] version: 10.13.1.1 - (1765088) Found support for locale: [fr] version: 10.13.1.1 - (1765088) Found support for locale: [hu] version: 10.13.1.1 - (1765088) Found support for locale: [it] version: 10.13.1.1 - (1765088) Found support for locale: [ja_JP] version: 10.13.1.1 - (1765088) Found support for locale: [ko_KR] version: 10.13.1.1 - (1765088) Found support for locale: [pl] version: 10.13.1.1 - (1765088) Found support for locale: [pt_BR] version: 10.13.1.1 - (1765088) Found support for locale: [ru] version: 10.13.1.1 - (1765088) Found support for locale: [zh_CN] version: 10.13.1.1 - (1765088) Found support for locale: [zh_TW] version: 10.13.1.1 - (1765088) ------------------------------------------------------ ------------------------------------------------------
環境変数の追加
環境変数を設定して簡単に使えるようにしておく。
export DERBY_HOME=/usr/local/derby export PATH=$DERBY_HOME/bin:$PATH
次回ログイン時にも設定されるようにする。
echo "" >> /etc/bashrc echo "# DERBY ENVIRONMENT VARIABLE" >> /etc/bashrc echo "export DERBY_HOME=$DERBY_HOME" >> /etc/bashrc echo "export PATH=\$DERBY_HOME/bin:\$PATH" >> /etc/bashrc
不要ファイルの削除
ドキュメントなど、サーバの実行に不要なファイルは消しておく。
インストールされているファイル
存在するファイルは以下
- KEYSファイル
Derbyの各開発者のPGP鍵集。
Derby開発者と連絡を取る際に使用する。
- NOTICEファイル
ライセンス条項や注意点など。
- binディレクトリ
この配下にツール各種が入っている。
- docsディレクトリ
ドキュメント。HTMLとPDFが含まれる。
このディレクトリとindex.htmlをWEBサーバの公開ディレクトリに配置すれば、
Derbyの使用に関するドキュメントを参照できる。
- javadocディレクトリ
Derbyのjavadoc。
- testディレクトリ
Derby自体をテストするためのプログラムとその説明書。
Derbyを自身で改修したときに使用する。
- LICENSEファイル
Apache Licenseについて。
- RELEASE-NOTES.htmlファイル
本バージョンに関してのHTML。
- demoディレクトリ
デモ用のデータベースが作成されている
- index.htmlファイル
ドキュメントのホームページ。
docsディレクトリと共にWEBサーバの公開ディレクトリに配置すれば、
Derbyの使用に関するドキュメントを参照できる。
- libディレクトリ
各種jarファイル。
- 組み込みライブラリ
組み込みモード、クライアントツールで使用する。
サーバモードのみ使用する場合は不要。
- derby.jar
- ツールライブラリ
組み込みモード、クライアントツールで使用する。
サーバモードのみ使用する場合は不要。
- derbyrun.jar
- derbytools.jar
- derbyoptionaltools.jar
- サーバライブラリ
サーバモードで使用する。
サーバモードを使用しない場合は不要。
- derbynet.jar
- クライアントライブラリ
クライアントモードで使用する。
クライアントモードを使用しない場合は不要。
- derbyclient.jar
- ロケールライブラリ
各種ロケール用のライブラリ。
基本の英語の他は日本語しか使用しない場合は、derbyLocale_ja_JP.jarのみあれば良い。
- derbyLocale_cs.jar
チェコ語 - derbyLocale_de_DE.jar
ドイツ語 - derbyLocale_es.jar
スペイン語 - derbyLocale_fr.jar
フランス語 - derbyLocale_hu.jar
ハンガリー語 - derbyLocale_it.jar
イタリア語 - derbyLocale_ja_JP.jar
日本語 - derbyLocale_ko_KR.jar
韓国語 - derbyLocale_pl.jar
ポーランド語 - derbyLocale_pt_BR.jar
ブラジル語(ブラジル向けポルトガル語) - derbyLocale_ru.jar
ロシア語 - derbyLocale_zh_CN.jar
簡易中国語 - derbyLocale_zh_TW.jar
中国語
- derbyLocale_cs.jar
- データベースサーバ管理のWEBアプリケーション
- derby.war
削除の実行
- まとめて削除
rm -f bin/*.bat rm -f bin/*CP rm -rf docs rm -rf javadoc rm -rf index.html ls lib/derbyLocale_* -1 | grep -v JP | xargs rm -f rm -f lib/derby.war rm -rf test rm -rf demo rm -f \ KEYS \ LICENSE \ NOTICE \ RELEASE-NOTES.html
- 個別に削除
- Windows用バッチファイル
rm -f bin/*.bat
- Windows用バッチファイル
- 環境変数設定用スクリプト
rm -f bin/*CP
- ドキュメント
rm -rf docs rm -rf javadoc rm -rf index.html
- 外国語用ライブラリ
ls lib/derbyLocale_* -1 | grep -v JP | xargs rm -f
- データベースサーバ管理のWEBアプリケーション
rm -f lib/derby.war
- テスト
rm -rf test
- デモ
rm -rf demo
- その他
rm -f \ KEYS \ LICENSE \ NOTICE \ RELEASE-NOTES.html
- 削除完了後
上記を全て削除すると以下のようになる。
[root@derby derby]# ll * bin: total 48 -rwxr-xr-x 1 root root 5835 Oct 16 2016 NetworkServerControl -rwxr-xr-x 1 root root 5774 Oct 16 2016 dblook -rwxr-xr-x 1 root root 5910 Oct 16 2016 ij -rwxr-xr-x 1 root root 5841 Oct 16 2016 startNetworkServer -rwxr-xr-x 1 root root 5844 Oct 16 2016 stopNetworkServer -rwxr-xr-x 1 root root 5823 Oct 16 2016 sysinfo lib: total 4448 -rw-r--r-- 1 root root 3230946 Oct 16 2016 derby.jar -rw-r--r-- 1 root root 123478 Oct 16 2016 derbyLocale_ja_JP.jar -rw-r--r-- 1 root root 587986 Oct 16 2016 derbyclient.jar -rw-r--r-- 1 root root 272410 Oct 16 2016 derbynet.jar -rw-r--r-- 1 root root 82426 Oct 16 2016 derbyoptionaltools.jar -rw-r--r-- 1 root root 9635 Oct 16 2016 derbyrun.jar -rw-r--r-- 1 root root 230344 Oct 16 2016 derbytools.jar
設定ファイルの用意
サーバ用設定ファイルを用意しておく。
空のままでも良いが、設定変更する場合はこのファイルを編集する。
touch derby.properties
NetworkServerControlスクリプトのリンク作成
サーバとして利用する際、NetworkServerControlスクリプトを中心に使用するのだが、NetworkServerControlという名前は長く、大文字が混在しているので、キーボードから入力しづらい。
その為、簡単な名前のリンクを作成する。
derbyという名前のリンクにする場合。
cd bin ln -s NetworkServerControl derby cd ../
NetworkServerControlスクリプトの変更
NetworkServerControlスクリプトは実行時のカレントディレクトリを起点としてログファイルの生成、設定ファイルの読み込みなどを行う。
いずれのディレクトリにおいても$DERBY_HOMEディレクトリが起点となるように変更する。
更に、JVMオプションを設定できるようにする。
sed -i -e "s/derby_exec_command=/cd \$DERBY_HOME\nexport DERBY_OPTS="\`cat env\`"\nderby_exec_command=/g" $DERBY_HOME/bin/derby2 echo > $DERBY_HOME/env
例えば初期メモリサイズを32MB、最大メモリサイズを64MBに制限したい場合は次のように設定する。
echo -Xms32M > $DERBY_HOME/env echo -Xmx64M >> $DERBY_HOME/env
ijスクリプトの変更
ij用のデフォルト設定ファイルを読み込むように変更する
ijスクリプトは実行時のカレントディレクトリをデータベースのストレージパスとして扱う。
その為、データベースを作成した時と異なるパスで再度ijでデータベースにアクセスしようとしてもアクセスできない。
いずれのディレクトリにおいても$DERBY_HOMEディレクトリが起点となるように変更する。
touch ij.properties sed -i -e "s/\$@\"/\$@ -p \$DERBY_HOME\/ij.properties\"/g" -e "s/derby_exec_command=/cd \$DERBY_HOME\nderby_exec_command=/g" bin/ij
SQL直接実行スクリプトの作成
DerbyにはLinuxコンソールから直接SQLを実行できず、毎回ijで一旦ログインしなければならない。
その為、Linuxコンソールから直接SQLを実行できるプログラムを作成する。
cat > bin/qtoderby << EOT ij <(echo "\$*") echo "" EOT chmod 744 bin/qtoderby
qtoderbyというプログラムが作成されたので、コマンドライン引数にSQLを指定して直接実行できるようになった。
ただし、適切にエスケープを行う必要がある。
Derby実行ユーザ作成
useradd --user-group --no-create-home --shell /sbin/nologin derby chown -R derby:derby /usr/local/derby*
- derbyユーザでの起動スクリプト作成
Derbyはユーザ名を指定して起動するオプションが存在しない。
その為、通常は次のようにsodoが必要になる。
sudo -b -E -u derby sh -c '/usr/local/derby/bin/derby start'
ただ、毎回打つのは面倒なのでスクリプトを作成する。
echo "sudo -b -E -u derby sh -c '/usr/local/derby/bin/derby start'" > bin/derbyStart chown derby:derby bin/derbyStart chmod 550 bin/derbyStart
これにより次のコマンドで、derbyユーザでDerbyを起動することができるようになる。
derbyStart
ただし、データベースファイルやログファイルのオーナーがderbyユーザでない場合、正常に動作しないので注意すること。
初期設定
環境によっては以下の設定は行うべきではない。ただし、あるとDerbyを使用しやすい設定である。
サーバ設定
デフォルトではIPv6のみでしか接続できないので、全てのIPv4アドレスを持つインタフェースへ接続を許可する。
cat > derby.properties << EOT derby.system.home=$DERBY_HOME derby.drda.host=0.0.0.0 derby.language.logQueryPlan=true derby.infolog.append=true EOT
ij設定
cat > ij.properties << EOT ij.protocol=jdbc:derby://127.0.0.1:1527/ ij.database = <メインで使用するデータベース>;create=true EOT
起動
derbyStart
接続確認を行う
ij --プロンプトが表示されたら実行する。 --データベース作成ができていれば正常に完了する。 show tables; --デフォルトデータベースのみが表示される。 exit;
Derbyを終了させる場合は以下を実行
derby shutdown
ローカル開発環境の構築
Derbyは組み込みモードでも使用でき、開発するアプリケーションから直接起動することができる。
インストール
jarファイルをダウンロードして所定のパスに配置する。
ライブラリには通常バージョンとDerby開発者向けの開発バージョンが存在する。
Derbyの起動プログラムサンプル
/* Derby - Class SimpleNetworkServerSample Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ import java.io.BufferedReader; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.apache.derby.drda.NetworkServerControl; /** * In order for a database to be consistent, only one JVM is allowed * to access it at a time. The embedded driver is loaded when the Network Server * is started. Hence, the JVM that starts the Network Server can get an * embedded connection to the same database that Network Server is accessing * to serve the clients from other JVMs. This solution allows you to take * advantage of the performance benefits of the embedded driver as well as allow * for client connections from other JVMs to connect to the same database. * * * In particular, this sample program * 1) starts the Derby Network Server using a property and * also loads the embedded driver * 2) checks if the Derby Network Server is up and running * 3) creates the database 'NSSimpleDB' if not already created * 4) obtains an embedded database connection * 5) tests the database connection by executing a sample query * 6) allows for client connections to connect to the server until * the user decides to stop the server and exit the program * 7) closes the connections * 8) shuts down the Derby Network Server before exiting the program. * * Note: On running this program, there will be a NSSimpleDB database directory * created if not present already, and there will be a derby.log file which * contains messages from Derby. * * <P> * Usage: java SimpleNetworkServerSample * */ public class SimpleNetworkServerSample { /* * The database is located in the same directory where this program is being * run. Alternatively, you can specify the absolute path of the database location */ private static String DBNAME="NSSimpleDB"; public static void main (String[] args) throws Exception { Connection embeddedConn = null; try { startNetworkServer(); /* Can now spawn threads to do many things with embedded connections but allow others to connect via Network Server. But for sample purposes, an embedded connection will be obtained and a sample query executed before waiting for the user to give input to shut down the server. */ } catch (Exception e) { System.out.println("Failed to start NetworkServer: " + e); System.exit(1); } try { // get an embedded connection // Since the Network Server was started in this JVM, this JVM can get an embedded // connection to the same database that the Network Server // is accessing to serve clients from other JVMs. // The embedded connection will be faster than going across the // network embeddedConn = getEmbeddedConnection(DBNAME,"create=true;"); System.out.println("Got an embedded connection."); System.out.println("Testing embedded connection by executing a sample query "); // test connections by doing some work test(embeddedConn); // print how to connect to the network server using ij String howToConnect = ijUsage(); System.out.println(howToConnect); waitForExit(); } catch (SQLException sqle) { System.out.println("Failure making connection: " + sqle); sqle.printStackTrace(); } finally { if(embeddedConn != null) embeddedConn.close(); try { // shut down Derby Network Server DriverManager.getConnection("jdbc:derby:;shutdown=true"); } catch(SQLException se) { //ignore se } } } /** * Setting the derby.drda.startNetworkServer property to true, * either in the System properties as we do here or in * the derby.properties file, will cause the Network Server to * start as soon as Derby is loaded. * * To load Derby, we just need to load the embedded * driver with: * Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance(); * * Then we will test for a while and make sure it is up, before * we give up. * * Alternatively, the Network Server might be started from the command * line or from some other program. Note: only the JVM that starts * Network Server can make an embedded connection. */ public static void startNetworkServer() throws Exception { // Start the Network Server using the property // and then wait for the server to start by testing a connection startWithProperty(); waitForStart(); } /** * Start Derby Network Server using the property * derby.drda.startNetworkServer. This property can be set as a system property or * or in the derby.properties file. * Setting this property to true starts the Network Server when * Derby boots up. * The port at which the Derby Network Server listens can be changed * by setting the derby.drda.portNumber property. By default, the server starts * at port 1527. * Server output goes to derby.log. */ private static void startWithProperty() throws Exception { System.out.println("Starting Network Server"); System.setProperty("derby.drda.startNetworkServer","true"); // Booting Derby Class<?> clazz = Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); clazz.getConstructor().newInstance(); } /** * Tries to check if the Network Server is up and running by calling ping * If successful, it returns; otherwise, it tries for 50 seconds before giving up and throwing * an exception. * @throws Exception when there is a problem with testing if the Network Server is up * and running */ private static void waitForStart() throws Exception { // Server instance for testing connection org.apache.derby.drda.NetworkServerControl server = null; // Use NetworkServerControl.ping() to wait for the // Network Server to come up. We could have used // NetworkServerControl to start the server, but the property is // easier. server = new NetworkServerControl(); System.out.println("Testing if Network Server is up and running!"); for (int i = 0; i < 10 ; i ++) { try { Thread.currentThread().sleep(5000); server.ping(); } catch (Exception e) { System.out.println("Try #" + i + " " +e.toString()); if (i == 9 ) { System.out.println("Giving up trying to connect to Network Server!"); throw e; } } } System.out.println("Derby Network Server now running"); } /** * Used to return an embedded Derby connection. * The protocol used is "jdbc:derby:dbName" where dbName is the database name * @pre the Derby embedded JDBC driver must be loaded before calling * this method * Alternatively, if the Derby Network Server is started in this JVM, the embedded driver * org.apache.derby.jdbc.EmbeddedDriver is already loaded and it need not be loaded again. * @param dbName database name (ie location of the database) * @param attributes attributes for the database connection * (for example, create=true; * upgrade=true;) * @return returns embedded database connection * @throws Exception if there is any error */ public static Connection getEmbeddedConnection(String database,String attributes) throws Exception { String dbUrl = "jdbc:derby:"+database +";"+attributes; Connection conn = DriverManager.getConnection(dbUrl); return conn; } /** * Test a connection by executing a sample query * @param conn database connection * @throws Exception if there is any error */ public static void test(Connection conn) throws Exception { Statement stmt = null; ResultSet rs = null; try { // To test our connection, we will try to do a select from the system catalog tables stmt = conn.createStatement(); rs = stmt.executeQuery("select count(*) from sys.systables"); while(rs.next()) System.out.println("number of rows in sys.systables = "+ rs.getInt(1)); } catch(SQLException sqle) { System.out.println("SQLException when querying on the database connection; "+ sqle); throw sqle; } finally { if(rs != null) rs.close(); if(stmt != null) stmt.close(); } } /** * This method waits until the user presses Enter to stop the server * and eventually exit this program * Allows clients to continue to connect using client connections from other * JVMs to the Derby Network Server that was started in this program */ private static void waitForExit() throws Exception { System.out.println("Clients can continue to connect: "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Press [Enter] to stop Server"); in.readLine(); } /** * Returns a string with information as to how to connect to Derby Network Server */ private static String ijUsage() { String ijUsage = "\nWhile my app is busy with embedded work, "; ijUsage += "ij might connect like this:\n\n"; ijUsage += "\t$ java -Dij.user=me -Dij.password=pw -Dij.protocol=jdbc:derby://localhost:1527/ org.apache.derby.tools.ij\n"; ijUsage += "\tij> connect '" + DBNAME + "';\n\n"; return ijUsage; } }
設定
設定はシステムレベルの設定とデータベースレベルの設定、更に作成時永続設定が存在する。
- システムレベルの設定
Derbyサーバインスタンス全体で共有される設定
- データベースレベルの設定
個々のデータベース単位で反映される設定
- 作成時永続設定
データベースやテーブルなどを対象に、作成時に設定されていた内容が反映され、以降はその設定が永続的に有効となり、変更しても影響を受けない
また、各設定には起動時にのみ指定できる静的設定と、起動後も随時変更できる動的な設定がある。
設定方法
設定は設定ファイルに記述するほか、起動時オプションに指定したり、動的設定であれば、コネクションに書き出すことで設定変更が可能。
設定ファイル
Derbyのホームディレクトリに「derby.properties」という名前で作成することで、起動時に自動で読み込む。
- 設定ファイルを作成する
touch $DERBY_HOME/derby.properties
設定内容
ネットワークサーバ
受付インタフェース
https://db.apache.org/derby/docs/10.13/adminguide/radmindrdahost.html
- 設定値
derby.drda.host=<IPアドレス> | <ホスト名>
ホスト名を指定した場合、名前解決を行いIPアドレスに変換される。
すなわち、名前解決できないホスト名を指定した場合は、起動時にエラーが出て、起動できない。
以下のようなエラーが出力される。
Unable to find host: <ホスト名>.
コネクションへのログ出力
ネットワーク接続中のコネクションにログを出力するかどうか。
いずれの場合でもログファイルへの出力は行われる。
- 設定値
derby.drda.logConnections = [ true | false ]
- デフォルト
derby.drda.logConnections = false
ログ
ログの追記
ログファイルはデフォルトでは起動時に上書きされてしまうが、この設定を有効にすることで、既存のログファイルに追記させることができる。
- 設定値
derby.infolog.append = [ true | false ]
- デフォルト
derby.infolog.append = false
実行計画ログ出力
この設定を有効にすることで、クエリが実行されるたびに実行計画がログに出力される。
負荷がかかるが、チューニング等に役に立つ。ただし、OS名など冗長な情報も多い。
- 設定値
derby.language.logQueryPlan = [ true | false ]
- デフォルト
derby.language.logQueryPlan = false
- ログ出力例
Tue Aug 13 13:46:50 JST 2017: Booting Derby version The Apache Software Foundation - Apache Derby - 10.13.1.1 - (1765088): instance a816c00e-01 5d-e437-38be-000000c93980 on database directory /usr/local/db-derby-10.13.1.1-bin/test with class loader sun.misc.Launcher$AppClassLoader@4 554617c Loaded from file:/usr/local/db-derby-10.13.1.1-bin/lib/derby.jar java.vendor=Oracle Corporation java.runtime.version=1.8.0_131-b11 user.dir=/usr/local/db-derby-10.13.1.1-bin os.name=Linux os.arch=amd64 os.version=2.6.32-696.1.1.el6.x86_64 derby.system.home=/usr/local/derby Database Class Loader started - derby.database.classpath='' Tue Aug 13 13:47:13 JST 2017 Thread[main,5,main] (XID = 399), (SESSIONID = 1), select id from test where id=3 *** **** Index Scan ResultSet for TEST using index TEST_INDEX at read committed isolation level using instantaneous s hare row locking chosen by the optimizer Number of opens = 1 Rows seen = 1 Rows filtered = 0 Fetch Size = 16 constructor time (milliseconds) = 0 open time (milliseconds) = 0 next time (milliseconds) = 0 close time (milliseconds) = 0 next time in milliseconds/row = 0 scan information: Bit set of columns fetched={0} Number of columns fetched=1 Number of deleted rows visited=0 Number of pages visited=1 Number of rows qualified=1 Number of rows visited=2 Scan type=btree Tree height=-1 start position: >= on first 1 column(s). Ordered null semantics on the following columns: stop position: > on first 1 column(s). Ordered null semantics on the following columns: qualifiers: None optimizer estimated row count: 1.00 optimizer estimated cost: 5.15
ステートメントログ出力
この設定を有効にすることで、データベースで実行されるステートメント(実行単位)がログ出力される。
1クエリーが5ステートメントに分解されるなど、ログが多量に出る割には余り有用な情報は出力されない。
- 設定値
derby.language.logStatementText = [ true | false ]
- デフォルト
derby.language.logStatementText = false
- ログ出力例
Tue Aug 13 13:42:05 JST 2017 Thread[main,5,main] (XID = 397), (SESSIONID = 1), (DATABASE = test), (DRDAID = null) , Begin compiling prepared statement: select * from test :End prepared statement Tue Aug 13 13:42:05 JST 2017 Thread[main,5,main] (XID = 397), (SESSIONID = 1), (DATABASE = test), (DRDAID = null) , End compiling prepared statement: select * from test :End prepared statement Tue Aug 13 13:42:05 JST 2017 Thread[main,5,main] (XID = 397), (SESSIONID = 1), (DATABASE = test), (DRDAID = null) , Executing prepared statement: select * from test :End prepared statement Tue Aug 13 13:42:05 JST 2017 Thread[main,5,main] (XID = 397), (SESSIONID = 1), (DATABASE = test), (DRDAID = null) , Committing Tue Aug 13 13:42:05 JST 2017 Thread[main,5,main] (XID = 397), (SESSIONID = 1), (DATABASE = test), (DRDAID = null) , Committing
運用
起動
デフォルトの動作として、CentOSではIPv6が有効な場合、Java系のネットワークサーバプロダクトはデフォルトで受付インタフェースとしてIPv6のみを許可する。
また、IPv6を無効にした場合は受付インタフェースとしてループバックアドレスのみ許可する。
従って、Derby使用時にはIPv4アドレスで外部のホストから接続を許可したい場合、明示的に接続できるIPアドレスを指定しなければならない。
特定のインタフェースに割り当てられたIPアドレスを指定することで、そのIPアドレスを持つインタフェースのみ接続を許可することができる。
「0.0.0.0」を指定すれば、すべてのインタフェースで接続を許可することができる。
- 全てのIPアドレスで
startNetworkServer -h 0.0.0.0
- 外部向けインタフェースのIPv4アドレスのみ接続を受け付ける
startNetworkServer -h \ `ip address | grep "inet " | grep -v "127.0.0.1" | sed -e "s/^[^0-9]*//g" -e "s/\/.*//g"` &
起動時にサーバのホスト名に解決できないものを設定している場合次のようなWarningが出る。
※derbyというホスト名に設定した場合
Fri May 26 14:01:35 JST 2017 : Warning: UnknkownHostException: derby: derby: Name or service not known.
無視しても問題ないが、気になる場合、次のように設定してから起動する。
hostname localhost
または
hostname <自身のIPアドレス>
停止
stopNetworkServer -h \ `ip address | grep "inet " | grep -v "127.0.0.1" | sed -e "s/^[^0-9]*//g" -e "s/\/.*//g"`
トラブルシューティング
Derbyに接続できない
自作のプログラムから接続できない
エラーXSDB6(エラーXJ040)
- 状況
Derbyはネットワークサーバモードで使用している。
自作のプログラムからDBに接続しようとすると、以下のようなエラーが表示される。
ERROR XJ040: Failed to start database ‘データベース名’, see the next exception
for details.
ERROR XSDB6: Another instance of Derby may have already booted the
database /データベースパス.
- 解決策
ij等他のプログラムがDerbyを使用している場合、それを切断する。
他のプログラムがローカル接続している場合、この現象が起こるので、ネットワーク接続するようにする。
- 原因
これは他のJVMインスタンスまたはクラスローダーが既にこのデータベースを使用しているからである。
使用中の場合、データベースのディレクトリの中に「」というロックファイルが生成されているはず。
使用中のデータベースは他のJVMインスタンスまたはクラスローダーからは利用できないので、使用中の接続を切断する必要がある。
ネットワーク接続をしている場合は、一旦サーバプログラムが接続を受けて、そこからDerbyにアクセスするので複数の接続元からアクセス可能であるが、ネットワークサーバモード中にローカルアクセスすると、先にアクセスした方で占有される。
ネットワークサーバモードで使用するなら、ローカルアクセスはするべきではない。
ijから接続できない
エラーXSDB6(エラーXJ040)
- 状況
Derbyはネットワークサーバモードで使用している。
ijを使用してDBに接続しようとすると、以下のようなエラーが表示される。
ERROR XJ040: Failed to start database ‘データベース名’, see the next exception
for details.
ERROR XSDB6: Another instance of Derby may have already booted the
database /データベースパス.
- 解決策
他のプログラムから既に接続した場合、そのプログラムが終了し、切断していたとしてもDerbyはロックされたままである。
再起動するか、ijをネットワーク接続で利用する。
ネットワーク接続する場合、URL指定時にIPアドレスかホスト名を指定して、データベース名を指定する。
このように指定している場合、
jdbc:derby:/<DB名>
次のようにする。
jdbc:derby:<IPアドレス>:1527/<DB名>
- 原因
これは他のJVMインスタンスまたはクラスローダーが既にこのデータベースを使用しているからである。
使用中の場合、データベースのディレクトリの中に「」というロックファイルが生成されているはず。
使用中のデータベースは他のJVMインスタンスまたはクラスローダーからは利用できないので、使用中の接続を切断する必要がある。
ネットワーク接続をしている場合は、一旦サーバプログラムが接続を受けて、そこからDerbyにアクセスするので複数の接続元からアクセス可能であるが、ネットワークサーバモード中にローカルアクセスすると、先にアクセスした方で占有される。
ネットワークサーバモードで使用するなら、ローカルアクセスはするべきではない。
ツール
$DERBY_HOME/bin配下にインストールされている。
NetworkServerControl
[root@derby derby]# NetworkServerControl Fri May 26 15:04:54 JST 2017 : No command given. Usage: NetworkServerControl <commands> Commands: start [-h <host>] [-p <port number>] [-noSecurityManager] [-ssl <ssl mode>] shutdown [-h <host>][-p <port number>] [-ssl <ssl mode>] [-user <username>] [-password <password>] ping [-h <host>][-p <port number>] [-ssl <ssl mode>] sysinfo [-h <host>][-p <port number>] [-ssl <ssl mode>] runtimeinfo [-h <host>][-p <port number>] [-ssl <ssl mode>] logconnections { on|off } [-h <host>][-p <port number>] [-ssl <ssl mode>] maxthreads <max>[-h <host>][-p <port number>] [-ssl <ssl mode>] timeslice <milliseconds>[-h <host>][-p <port number>] [-ssl <ssl mode>] trace { on|off } [-s <session id>][-h <host>][-p <port number>] [-ssl <ssl mode>] tracedirectory <trace directory>[-h <host>][-p <port number>] [-ssl <ssl mode>]
- スクリプトの内容
#!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. if [ -n "$derby_common_debug" ] ; then set -x fi # OS specific support. $var _must_ be set to either true or false. cygwin=false; darwin=false; case "`uname`" in CYGWIN*) cygwin=true ;; Darwin*) darwin=true if [ -z "$JAVA_HOME" ] ; then JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home fi ;; esac if [ -z "$DERBY_HOME" -o ! -d "$DERBY_HOME" ] ; then ## resolve links - $0 may be a link to derby's home PRG="$0" progname=`basename "$0"` # need this for relative symlinks while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done DERBY_HOME=`dirname "$PRG"`/.. # make it fully qualified DERBY_HOME=`cd "$DERBY_HOME" && pwd` fi # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then [ -n "$DERBY_HOME" ] && DERBY_HOME=`cygpath --unix "$DERBY_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` fi # set DERBY_LIB location DERBY_LIB="${DERBY_HOME}/lib" if [ -z "$JAVACMD" ] ; then if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi else JAVACMD=`which java 2> /dev/null ` if [ -z "$JAVACMD" ] ; then JAVACMD=java fi fi fi if [ ! -x "$JAVACMD" ] ; then echo "Error: JAVA_HOME is not defined correctly." echo " We cannot execute $JAVACMD" exit 1 fi # set local classpath, don't overwrite the user's LOCALCLASSPATH=$DERBY_LIB/derby.jar:$DERBY_LIB/derbynet.jar:$DERBY_LIB/derbytools.jar:$DERBY_LIB/derbyoptionaltools.jar:$DERBY_LIB/derbyclient.jar # if CLASSPATH_OVERRIDE env var is set, LOCALCLASSPATH will be # user CLASSPATH first and derby-found jars after. # In that case, the user CLASSPATH will override derby-found jars # # if CLASSPATH_OVERRIDE is not set, we'll have the normal behaviour # with derby-found jars first and user CLASSPATH after if [ -n "$CLASSPATH" ] ; then # merge local and specified classpath if [ -z "$LOCALCLASSPATH" ] ; then LOCALCLASSPATH="$CLASSPATH" elif [ -n "$CLASSPATH_OVERRIDE" ] ; then LOCALCLASSPATH="$CLASSPATH:$LOCALCLASSPATH" else LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH" fi # remove class path from launcher -cp option CLASSPATH="" fi # For Cygwin, switch paths to appropriate format before running java # For PATHs convert to unix format first, then to windows format to ensure # both formats are supported. Probably this will fail on directories with ; # in the name in the path. Let's assume that paths containing ; are more # rare than windows style paths on cygwin. if $cygwin; then if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then format=mixed else format=windows fi DERBY_HOME=`cygpath --$format "$DERBY_HOME"` DERBY_LIB=`cygpath --$format "$DERBY_LIB"` if [ -n "$JAVA_HOME" ]; then JAVA_HOME=`cygpath --$format "$JAVA_HOME"` fi LCP_TEMP=`cygpath --path --unix "$LOCALCLASSPATH"` LOCALCLASSPATH=`cygpath --path --$format "$LCP_TEMP"` if [ -n "$CLASSPATH" ] ; then CP_TEMP=`cygpath --path --unix "$CLASSPATH"` CLASSPATH=`cygpath --path --$format "$CP_TEMP"` fi CYGHOME=`cygpath --$format "$HOME"` fi # add a second backslash to variables terminated by a backslash under cygwin if $cygwin; then case "$DERBY_HOME" in *\\ ) DERBY_HOME="$DERBY_HOME\\" ;; esac case "$CYGHOME" in *\\ ) CYGHOME="$CYGHOME\\" ;; esac case "$LOCALCLASSPATH" in *\\ ) LOCALCLASSPATH="$LOCALCLASSPATH\\" ;; esac case "$CLASSPATH" in *\\ ) CLASSPATH="$CLASSPATH\\" ;; esac fi # Readjust classpath for MKS # expr match if [ \( "`expr $SHELL : '.*sh.exe$'`" -gt 0 \) -a \( "$cygwin" = "false" \) ]; then LOCALCLASSPATH=`echo $LOCALCLASSPATH | sed -E 's/([\d\w]*):([\d\w]*)/\1;\2/g '` fi #!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. derby_exec_command="exec \"$JAVACMD\" $DERBY_OPTS -classpath \"$LOCALCLASSPATH\" org.apache.derby.drda.NetworkServerControl $@" eval $derby_exec_command
スクリプトの変更
このスクリプトは実行時のカレントディレクトリを起点としてログファイルの生成、設定ファイルの読み込みなどを行う。
いずれのディレクトリにおいても$DERBY_HOMEディレクトリが起点となるように変更した方が良い。
sed -i.original -e "s/derby_exec_command=/cd \$DERBY_HOME\nderby_exec_command=/g" bin/derby
ネットワークサーバ起動
プロセスを分離しないとコントロールが戻らなくなる。
NetworkServerControl start &
初期設定にてすべてのインタフェースで接続を有効にしているが、デフォルトの動作として、CentOSではIPv6が有効な場合、Java系のネットワークサーバプロダクトはデフォルトで受付インタフェースとしてIPv6のみを許可する。
また、IPv6を無効にした場合は受付インタフェースとしてループバックアドレスのみ許可する。
従って、Derby使用時にはIPv4アドレスで外部のホストから接続を許可したい場合、明示的に接続できるIPアドレスを指定しなければならない。
特定のインタフェースに割り当てられたIPアドレスを指定することで、そのIPアドレスを持つインタフェースのみ接続を許可することができる。
「0.0.0.0」を指定すれば、すべてのインタフェースで接続を許可することができる。
NetworkServerControl start -h <IPアドレス>
IPアドレス
- 記法
NetworkServerControl start -h <host> &
ネットワークサーバ停止
NetworkServerControl shutdown
特定のIPアドレスを指定して起動している場合は-hオプションにより、IPアドレスを指定する。
- IPアドレス指定
NetworkServerControl shutdown -h <IPアドレス>
dblook
データベースの情報からDDL文を復元するツールである。
このツール以外にDDL文を復元する方法はない。
使い方
いずれにおいてもユーザ定義のDDLのみ表示可能で、システムが定義したDDLは表示されない。
データベース全てのDDLを生成する
dblook -d jdbc:derby:<IPアドレス>:1527/<DB名>
テーブルを指定してDDLを生成する
指定したテーブルに関連付けれているインデックスなども表示される
dblook -d jdbc:derby:<IPアドレス>:1527/<DB名> -t <テーブル名>
ヘルプ
[root@derby derby]# dblook Usage: java org.apache.derby.tools.dblook -d <source database url> [options] where the source URL is the full URL, including the connection protocol and any connection attributes that might apply. For example, use 'jdbc:derby:myDB', or 'jdbc:derby://localhost:1527/myDB;user=usr;'. options include: -z <schema name> to specify a schema to which the DDL generation should be limited. Only database objects with that schema will have their DDL generated. -t <table one> <table two> ... to specify a list of tables for which the DDL will be generated; any tables not in the list will be ignored. -td <value> to specify what should be appended to the end of each DDL statement. This defaults to ';'. -noview to prevent the generation of DDL for views. -append to keep from overwriting the output files. -verbose to have error messages printed to the console (in addition to the log file). If not specified, errors will only be printed to the log file. -o <filename> to specify the file name to which the generated DDL will be written. If not specified, default is the console.
ij
DerbyのCLIクライアントツール。
スクリプトの修正
ijは明示的に指定しない限りij用設定ファイルを読み込まない。
そこで、ij用のデフォルト設定ファイルを読み込むように変更する。
設定ファイルを読み込むオプション(-p <設定ファイルパス>)を指定した場合、二つ目以降のオプションは無視されるので、正常に動作する。
また、ijスクリプトは実行時のカレントディレクトリをデータベースのストレージパスとして扱う。
その為、データベースを作成した時と異なるパスで再度ijでデータベースにアクセスしようとしてもアクセスできない。
いずれのディレクトリにおいても$DERBY_HOMEディレクトリが起点となるように変更する。
- ij用設定ファイルが未作成の場合、作成しておく
touch $DERBY_HOME/ij.properties
- スクリプトを変更する
この時バックアップを作成しておく(ij.original)
sed -i.original -e "s/\$@\"/\$@ -p \$DERBY_HOME\/ij.properties\"/g" -e "s/derby_exec_command=/cd \$DERBY_HOME\nderby_exec_command=/g" $DERBY_HOME/bin/ij
以下の行を変更している
[root@eldorado-of derby]# diff bin/ij bin/ij.original 191,192c191 < cd $DERBY_HOME < derby_exec_command="exec \"$JAVACMD\" $DERBY_OPTS -classpath \"$LOCALCLASSPATH\" org.apache.derby.tools.ij $@ - p $DERBY_HOME/ij.properties" --- > derby_exec_command="exec \"$JAVACMD\" $DERBY_OPTS -classpath \"$LOCALCLASSPATH\" org.apache.derby.tools.ij $@"
起動
起動時には設定ファイルを指定することが可能。
設定ファイルを指定しない場合、設定ファイルが読み込まれることはない。
オプションを直接指定することはできないので設定ファイルに記述のして、そのファイルを渡す必要がある。
設定ファイルを指定するオプションを複数回指定した場合、最初のもののみ読み込まれ、2番目以降のものは無視され、設定ファイルが存在しなくてもエラーにならない。
起動後は対話的に処理を実行していく。
- 起動
[root@derby ~]# ij ij version 10.13 ij>
- help
[root@derby ~]# ij --help Usage: java org.apache.derby.tools.ij [-p propertyfile] [inputfile]
終了
exit;
ヘルプ
help;
- 実行例
ij> help; Supported commands include: PROTOCOL 'JDBC protocol' [ AS ident ]; -- sets a default or named protocol DRIVER 'class for driver'; -- loads the named class CONNECT 'url for database' [ PROTOCOL namedProtocol ] [ AS connectionName ]; -- connects to database URL -- and may assign identifier SET CONNECTION connectionName; -- switches to the specified connection SHOW CONNECTIONS; -- lists all connections AUTOCOMMIT [ ON | OFF ]; -- sets autocommit mode for the connection DISCONNECT [ CURRENT | connectionName | ALL ]; -- drop current, named, or all connections; -- the default is CURRENT SHOW SCHEMAS; -- lists all schemas in the current database SHOW [ TABLES | VIEWS | PROCEDURES | FUNCTIONS | SYNONYMS ] { IN schema }; -- lists tables, views, procedures, functions or synonyms SHOW INDEXES { IN schema | FROM table }; -- lists indexes in a schema, or for a table SHOW ROLES; -- lists all defined roles in the database, sorted SHOW ENABLED_ROLES; -- lists the enabled roles for the current -- connection (to see current role use -- VALUES CURRENT_ROLE), sorted SHOW SETTABLE_ROLES; -- lists the roles which can be set for the -- current connection, sorted DESCRIBE name; -- lists columns in the named table COMMIT; -- commits the current transaction ROLLBACK; -- rolls back the current transaction PREPARE name AS 'SQL-J text'; -- prepares the SQL-J text EXECUTE { name | 'SQL-J text' } [ USING { name | 'SQL-J text' } ] ; -- executes the statement with parameter -- values from the USING result set row REMOVE name; -- removes the named previously prepared statement RUN 'filename'; -- run commands from the named file ELAPSEDTIME [ ON | OFF ]; -- sets elapsed time mode for ij MAXIMUMDISPLAYWIDTH integerValue; -- sets the maximum display width for -- each column to integerValue ASYNC name 'SQL-J text'; -- run the command in another thread WAIT FOR name; -- wait for result of ASYNC'd command HOLDFORCONNECTION; -- sets holdability for a connection to HOLD -- (i.e. ResultSet.HOLD_CURSORS_OVER_COMMIT) NOHOLDFORCONNECTION; -- sets holdability for a connection to NO HOLD -- (i.e. ResultSet.CLOSE_CURSORS_AT_COMMIT) GET [SCROLL INSENSITIVE] [WITH { HOLD | NOHOLD }] CURSOR name AS 'SQL-J query'; -- gets a cursor (JDBC result set) on the query -- the default is a forward-only cursor with holdability NEXT name; -- gets the next row from the named cursor FIRST name; -- gets the first row from the named scroll cursor LAST name; -- gets the last row from the named scroll cursor PREVIOUS name; -- gets the previous row from the named scroll cursor ABSOLUTE integer name; -- positions the named scroll cursor at the absolute row number -- (A negative number denotes position from the last row.) RELATIVE integer name; -- positions the named scroll cursor relative to the current row -- (integer is number of rows) AFTER LAST name; -- positions the named scroll cursor after the last row BEFORE FIRST name; -- positions the named scroll cursor before the first row GETCURRENTROWNUMBER name; -- returns the row number for the current position of the named scroll cursor -- (0 is returned when the cursor is not positioned on a row.) CLOSE name; -- closes the named cursor LOCALIZEDDISPLAY [ ON | OFF ]; -- controls locale sensitive data representation EXIT; -- exits ij HELP; -- shows this message Any unrecognized commands are treated as potential SQL-J commands and executed directly.
接続
ループバックアドレスで接続が受け付けられている必要がある。
connect '<URL>';
通常は以下のように指定する
connect 'jdbc:derby://127.0.0.1:1527/<DB名>';
DBがない場合は新規作成する場合は以下のようにする。
connect 'jdbc:derby://127.0.0.1:1527/<DB名>;create=true';
設定ファイルでオプション”ij.protocol”をJDBCに指定することで、プロトコル、接続先を省略可能で、ローカルサーバのDB名のみを指定して接続可能になる。
その場合、以下のようになる。
connect '<DB名>'; connect '<DB名>;create=true';
接続に成功すると、以降SQLを発行可能である。
切断
disconnect;
コメント
“–“で開始する
--comment
“/*”と”*/”でくくる
/* comment */
クエリ直接実行
標準入力のリダイレクトを用いてijの引数に直接SQLを与えて実行する。
末尾のセミコロンは省略してもよい。
ij <(echo "select * from table1")
記号の入力が多く面倒であるため、以下のようにスクリプトを作成すると便利である。
cat > bin/qtoderby << EOT ij <(echo "\$*") echo "" EOT chmod 744 bin/qtoderby
アスタリスク(*)、シングルクォート(‘)、ダブルクォート(“)、丸括弧(())を入力する際はバックスラッシュでエスケープするか(\*)、クエリ全部をダブルクォーテーションでくくらなければならないが、それ以外は引数としてそのままクエリを記述可能である。
- 例
qtoderby show tables qtoderby select \* from table1 qtoderby "select * from table1" qtoderby select id,name from table1 where name = \'abc\' qtoderby "select id,name from table1 where name = 'abc'"
設定ファイル
サーバ用プログラムと同様に設定ファイルを用意することで、特定の設定を有効にした状態で、ijを使用できる。
設定ファイルは自動で読み込まれず、明示的に指定する必要がある。
その為、設定ファイルを特定の名前にする必要はない。
接続プロトコル
デフォルトのDBサーバ接続プロトコルを指定する。
- 設定値
ij.protocol=<接続プロトコル>
derby用JDBCを使用してローカル接続する場合は以下のように指定する
ij.protocol=jdbc:derby:
derby用JDBCを使用してネットワーク接続する場合は以下のように指定する。
ネットワークサーバモードで使用する際はこちらで記載しておくのがよい。
ij.protocol=jdbc:derby://127.0.0.1:1527/
接続データベース
- ij.databaseオプション
起動時に接続するデータベースを指定する。
データベースの後にオプションを指定することも可能。
ij.dataSourceオプションとどちらか一方を好みで使用すればよい。
- 設定値
ij.database = <データベースURL> | <データベース名>
パラメータ”ij.protocol”が設定されている場合、データベース名のみ指定することができる。
- ij.dataSource
createオプションが指定できるが、ij.databaseオプションでも指定できるのでどちらか一方を好みで使用すればよい。 - 設定値
ij.dataSource.databaseName=<データベース名> ij.dataSource.createDatabase=create
接続名
ij使用中にURLをすべて記載せずに、設定した簡単な接続名を指定して接続することが可能
ij.connection.<接続名> = <URL>
例外出力
例外発生時に例外の内容をすべて出力するかどうか
ij.exceptionTrace = { true | false }
一行あたり出力最大長
ij.maximumDisplayWidth = <最大長>
結果のファイル出力
ij.outfile = <ファイル名>
ログイン情報
- ユーザ名
ij.user = <ユーザ名>
- パスワード
ij.password = <パスワード>
プロトコル名
ij.protocol.<プロトコル名> = <プロトコル>
エラーコード表示
エラーコードを表示するかどうか。
エラーコードはエラーの重大度で、エラーの内容を表すエラー識別子とは別のものである。
ij.showErrorCode = { true | false }
起動時接続名表示
ij起動時に自動接続するよう設定している場合に、接続先を表示するかどうか
ij.showNoConnectionsAtStart = { true | false }
SELECT結果行数表示
ij.showNoCountForSelect = { true | false }
組み込みモード時URLチェック
組み込みモードで使用する際に指定したURLのチェックを行うかどうか。
DerbyのJDBC以外を使用する場合にこのオプションを無効かする。
- 設定値
ij.URLCheck = { true | false }
- デフォルト
ij.URLCheck = true
文字コード、ロケール
- 文字コード
derby.ui.codeset = <文字コード>
- 日本語
derby.ui.codeset = UTF8 derby.ui.codeset = JIS derby.ui.codeset = SJIS derby.ui.codeset = EUCJIS derby.ui.codeset = Cp939
- 日本語
- ロケール
derby.ui.locale = <ロケール>
- 日本
derby.ui.locale = ja_JP
- 日本
setEmbeddedCP
Javaアプリケーションで組み込んで使用するためのクラスパスを設定するスクリプト。
直接実行してもスクリプト中で設定した環境変数はスクリプト内でしか有効にならないので、自作のスクリプト内で使用する。インストール時に含まれているツールでこのスクリプトを使用しているものはない。
その為、自身で明示的にこのスクリプトを使用しないのなら削除してしまっても問題ない。
setNetworkClientCP
Derbyサーバへクライアントとしてアクセスするためのクラスパスを設定するスクリプト。
直接実行してもスクリプト中で設定した環境変数はスクリプト内でしか有効にならないので、自作のスクリプト内で使用する。インストール時に含まれているij、dblook等のツールは内部で独自に設定を行っている。
その為、自身で明示的にこのスクリプトを使用しないのなら削除してしまっても問題ない。
setNetworkServerCP
Derbyをサーバとして使用するためのクラスパスを設定するスクリプト。
直接実行してもスクリプト中で設定した環境変数はスクリプト内でしか有効にならないので、自作のスクリプト内で使用する。インストール時に含まれているstartNetworkServer、NetworkServerControl等のツールは内部で独自に設定を行っている。
その為、自身で明示的にこのスクリプトを使用しないのなら削除してしまっても問題ない。
startNetworkServer
サーバモードで起動するスクリプト。
NetworkServerControlにてサーバの管理ができるので、基本的に使用しない。
- スクリプトの内容
#!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. if [ -n "$derby_common_debug" ] ; then set -x fi # OS specific support. $var _must_ be set to either true or false. cygwin=false; darwin=false; case "`uname`" in CYGWIN*) cygwin=true ;; Darwin*) darwin=true if [ -z "$JAVA_HOME" ] ; then JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home fi ;; esac if [ -z "$DERBY_HOME" -o ! -d "$DERBY_HOME" ] ; then ## resolve links - $0 may be a link to derby's home PRG="$0" progname=`basename "$0"` # need this for relative symlinks while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done DERBY_HOME=`dirname "$PRG"`/.. # make it fully qualified DERBY_HOME=`cd "$DERBY_HOME" && pwd` fi # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then [ -n "$DERBY_HOME" ] && DERBY_HOME=`cygpath --unix "$DERBY_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` fi # set DERBY_LIB location DERBY_LIB="${DERBY_HOME}/lib" if [ -z "$JAVACMD" ] ; then if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi else JAVACMD=`which java 2> /dev/null ` if [ -z "$JAVACMD" ] ; then JAVACMD=java fi fi fi if [ ! -x "$JAVACMD" ] ; then echo "Error: JAVA_HOME is not defined correctly." echo " We cannot execute $JAVACMD" exit 1 fi # set local classpath, don't overwrite the user's LOCALCLASSPATH=$DERBY_LIB/derby.jar:$DERBY_LIB/derbynet.jar:$DERBY_LIB/derbytools.jar:$DERBY_LIB/derbyoptionaltools.jar:$DERBY_LIB/derbyclient.jar # if CLASSPATH_OVERRIDE env var is set, LOCALCLASSPATH will be # user CLASSPATH first and derby-found jars after. # In that case, the user CLASSPATH will override derby-found jars # # if CLASSPATH_OVERRIDE is not set, we'll have the normal behaviour # with derby-found jars first and user CLASSPATH after if [ -n "$CLASSPATH" ] ; then # merge local and specified classpath if [ -z "$LOCALCLASSPATH" ] ; then LOCALCLASSPATH="$CLASSPATH" elif [ -n "$CLASSPATH_OVERRIDE" ] ; then LOCALCLASSPATH="$CLASSPATH:$LOCALCLASSPATH" else LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH" fi # remove class path from launcher -cp option CLASSPATH="" fi # For Cygwin, switch paths to appropriate format before running java # For PATHs convert to unix format first, then to windows format to ensure # both formats are supported. Probably this will fail on directories with ; # in the name in the path. Let's assume that paths containing ; are more # rare than windows style paths on cygwin. if $cygwin; then if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then format=mixed else format=windows fi DERBY_HOME=`cygpath --$format "$DERBY_HOME"` DERBY_LIB=`cygpath --$format "$DERBY_LIB"` if [ -n "$JAVA_HOME" ]; then JAVA_HOME=`cygpath --$format "$JAVA_HOME"` fi LCP_TEMP=`cygpath --path --unix "$LOCALCLASSPATH"` LOCALCLASSPATH=`cygpath --path --$format "$LCP_TEMP"` if [ -n "$CLASSPATH" ] ; then CP_TEMP=`cygpath --path --unix "$CLASSPATH"` CLASSPATH=`cygpath --path --$format "$CP_TEMP"` fi CYGHOME=`cygpath --$format "$HOME"` fi # add a second backslash to variables terminated by a backslash under cygwin if $cygwin; then case "$DERBY_HOME" in *\\ ) DERBY_HOME="$DERBY_HOME\\" ;; esac case "$CYGHOME" in *\\ ) CYGHOME="$CYGHOME\\" ;; esac case "$LOCALCLASSPATH" in *\\ ) LOCALCLASSPATH="$LOCALCLASSPATH\\" ;; esac case "$CLASSPATH" in *\\ ) CLASSPATH="$CLASSPATH\\" ;; esac fi # Readjust classpath for MKS # expr match if [ \( "`expr $SHELL : '.*sh.exe$'`" -gt 0 \) -a \( "$cygwin" = "false" \) ]; then LOCALCLASSPATH=`echo $LOCALCLASSPATH | sed -E 's/([\d\w]*):([\d\w]*)/\1;\2/g '` fi #!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. derby_exec_command="exec \"$JAVACMD\" $DERBY_OPTS -classpath \"$LOCALCLASSPATH\" org.apache.derby.drda.NetworkServerControl start $@" eval $derby_exec_command
stopNetworkServer
サーバモードで起動しているDerbyを停止するスクリプト。
NetworkServerControlにてサーバの管理ができるので、基本的に使用しない。
sysinfo
JAVAやOSのバージョンなどのシステム情報を表示する。
NetworkServerControlからでも行えるの削除してしまってもよい。(NetworkServerControl sysinfo)
- 実行例
[root@derby ~]# /usr/local/derby/bin/sysinfo ------------------ Java Information ------------------ Java Version: 1.8.0_131 Java Vendor: Oracle Corporation Java home: /usr/local/jre1.8.0_131 Java classpath: /usr/local/derby/lib/derby.jar:/usr/local/derby/lib/derbynet.jar:/usr/local/derby/lib/derbytools.jar:/usr/local/derby/lib/derbyoptionaltools.jar:/usr/local/derby/lib/derbyclient.jar:.:/usr/local/jre/lib/tools.jar:/usr/local/jre/lib/dt.jar OS name: Linux OS architecture: amd64 OS version: 3.10.0-514.el7.x86_64 Java user name: root Java user home: /root Java user dir: /root java.specification.name: Java Platform API Specification java.specification.version: 1.8 java.runtime.version: 1.8.0_131-b11 --------- Derby Information -------- [/usr/local/db-derby-10.13.1.1-bin/lib/derby.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbytools.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbynet.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbyclient.jar] 10.13.1.1 - (1765088) [/usr/local/db-derby-10.13.1.1-bin/lib/derbyoptionaltools.jar] 10.13.1.1 - (1765088) ------------------------------------------------------ ----------------- Locale Information ----------------- Current Locale : [English/United States [en_US]] Found support for locale: [cs] version: 10.13.1.1 - (1765088) Found support for locale: [de_DE] version: 10.13.1.1 - (1765088) Found support for locale: [es] version: 10.13.1.1 - (1765088) Found support for locale: [fr] version: 10.13.1.1 - (1765088) Found support for locale: [hu] version: 10.13.1.1 - (1765088) Found support for locale: [it] version: 10.13.1.1 - (1765088) Found support for locale: [ja_JP] version: 10.13.1.1 - (1765088) Found support for locale: [ko_KR] version: 10.13.1.1 - (1765088) Found support for locale: [pl] version: 10.13.1.1 - (1765088) Found support for locale: [pt_BR] version: 10.13.1.1 - (1765088) Found support for locale: [ru] version: 10.13.1.1 - (1765088) Found support for locale: [zh_CN] version: 10.13.1.1 - (1765088) Found support for locale: [zh_TW] version: 10.13.1.1 - (1765088) ------------------------------------------------------ ------------------------------------------------------
derby.war
データベースサーバ管理のWEBアプリケーション。
- インストール
利用する場合、以下を行う。
- Tomcat等のサーブレットコンテナを用意する
- ライブラリをサーブレットコンテナのライブラリディレクトリにコピーする
cp $DERBY_HOME/lib/*.jar $TOMCAT_HOME/lib/
- サーブレットコンテナのwebappディレクトリにこのwarファイルを移動させる
mv $DERBY_HOME/lib/derby.war $TOMCAT_HOME/webapps/
- 機能
データベースサーバ自体の管理はできるが、データベース内のデータの管理はできない。
データベースサーバの起動・終了、ログの有効化・無効化、トレースの実行・終了、動的オプションの設定が行えるのみである。
PlanExporter
実行計画の結果出力ツール。
実行計画の生成自体はijコマンド中で行えるが、結果表示が困難なため、別途このツールを用いてファイル出力して確認する。
手順
実行計画は常に生成できるわけではなく、機能を有効にしたときのみ生成できる。
機能を有効にすると、その間中に発行された全てのクエリで実行計画が生成される。
また、実行計画を生成すると、すぐに表示されるわけではなく、専用のテーブルに格納される。
実行計画生成終了後に機能を無効にしてから、それを閲覧することになるが、結果は複数のテーブルに分散されており、MySQLのように垂直表示(\G)ができないため、非常に見づらい。
その為、一旦ijを終了し、XML形式かHTML形式でファイル出力してから見た方が良い。
実行計画の生成結果は指定したスキーマに専用のテーブルが作成され、そこに保存される。
以下では専用のスキーマとして「XPLAIN」を指定している。
- ijを起動する
ij
- DBに接続する
- 実行計画を有効にする
CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1); CALL SYSCS_UTIL.SYSCS_SET_XPLAIN_SCHEMA('XPLAIN');
- 任意のSQLを発行する
- 実行計画を無効にする
CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(0); CALL SYSCS_UTIL.SYSCS_SET_XPLAIN_SCHEMA('');
- 結果一覧を表示する
select stmt_text, stmt_id from XPLAIN.SYSXPLAIN_STATEMENTS;
この後でファイル出力する際にここで表示される”statement ID”が必要になる。 - ijを終了する
exit;
- 結果をファイル出力し、表示する
全て一度に出力できず”statement ID”を変更して1度ずつ実行しなければならない。
ファイル名を変更しない場合、上書きされるので、1つずつ結果確認しなければならない。
※指定するスキーマ名は大文字にしなければならない。
java -classpath $DERBY_HOME/lib/derbytools.jar:$DERBY_HOME/lib/derby.jar org.apache.derby.tools.PlanExporter jdbc:derby:test XPLAIN <statement ID> -xml xplain.xml; cat xplain.xml; cat xplain.xml;
生成されるテーブル
- SYSXPLAIN_RESULTSETS
- SYSXPLAIN_RESULTSET_TIMINGS
- SYSXPLAIN_SCAN_PROPS
- SYSXPLAIN_SORT_PROPS
- SYSXPLAIN_STATEMENTS
- SYSXPLAIN_STATEMENT_TIMINGS
その他
http://executequery.org/index.php
http://eclipsesql.sourceforge.net/
http://squirrel-sql.sourceforge.net/
アプリケーション開発
http://db.apache.org/derby/docs/10.13/ref/index.html
サンプルプログラム
JDBC利用サンプル
このサンプルを実行すると「jdbcTest」データベースが作成される
import java.io.BufferedReader; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLTransactionRollbackException; import java.sql.Statement; import java.sql.Timestamp; public class JDBCTest { public static void main(String[] args) { String dbName = "jdbcTest"; String tableName = "table1"; String connectionURL = "jdbc:derby://192.168.0.51:1527/" + dbName + ";create=true"; String createQuery = "CREATE TABLE " + tableName + " (id INT NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " + " when TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " + " val VARCHAR(32) NOT NULL) "; String trancateQuery = "TRUNCATE TABLE " + tableName; String insertQuery = "INSERT INTO " + tableName + "(val) values (?)"; String selectQuery = "select id, when, val from " + tableName + " order by when"; try(Connection connection = DriverManager.getConnection(connectionURL); Statement statement = connection.createStatement();) { System.out.println("Connected to database : " + dbName); try { statement.execute(createQuery); System.out.println("New table created : " + tableName); } catch(SQLTransactionRollbackException e) { if(e.getSQLState().equals("X0Y32")) { System.out.println("Already exists table : " + tableName); } else { throw e; } } System.out.println(); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("program exits if enter \"e\""); System.out.println("data are cleared if enter \"c\""); try(PreparedStatement insertPreparedStatement = connection.prepareStatement(insertQuery);) { while(true) { System.out.print("enter string > "); String input = reader.readLine(); if(input.length() == 0) continue; if(input.equals("e")) break; if(input.equals("c")) { statement.execute(trancateQuery); continue; } insertPreparedStatement.setString(1, input); insertPreparedStatement.executeUpdate(); ResultSet resultSet = statement.executeQuery(selectQuery); System.out.println("--------------------------------------------------"); while(resultSet.next()) { String key = resultSet.getString(1); Timestamp when = resultSet.getTimestamp(2); String val = resultSet.getString(3); System.out.println(when + " : " + val + " (" + key + ")"); } resultSet.close(); System.out.println("--------------------------------------------------"); } } } catch(Throwable e) { System.out.println("! ERROR !"); e.printStackTrace(); } System.out.println("Closed connection"); } }
SQL
型
数値
整数
SMALLINT
2 bytes
INT / INTEGER
4 bytes
BIGINT
8 bytes
実数
REAL
4 bytes
DOUBLE
8 bytes
文字列
VARCHAR
可変文字列で指定可能な最大長が32,672byte
LONG VARCHAR
可変文字列である点はVARCHARと同じだが、作成時に明示的に最大長を指定する必要はない。
最大長は32,700byteで固定。
VARCHAR FOR BIT DATA
可変文字列で、バイナリを含ませることができる。
最大長は32,672 bytes。
- 記法
VARCHAR (<最大サイズ>) FOR BIT DATA
- Java型
VARBINARY
CLOB
可変文字列で指定可能な最大長が2,147,483,647byte。
- 記法
CLOB [ ( <最大長> [{ K | M | G }] ) ]
時刻
DATE
年月日を扱える
TIME
時分秒(秒は小数点異常のみ)を扱える
TIMESTAMP
全ての時間を扱える。
つまり、年月日時分秒(秒は小数点以下9桁)を扱える。
テーブル
作成
CREATE table <テーブル名> { ( {column-definition | Table-level constraint} [ , {column-definition | Table-level constraint} ] * ) | [ ( column-name [ , column-name ] * ) ] AS query-expression WITH NO DATA }
再作成
テーブルのデータを全て破棄する。
あくまでデータのみで、関連付けられているインデックスなどは破棄されないし、”generated identity”句を使用した自動採番の数は1に初期化されない。
truncate table <テーブル名>;
破棄
テーブルをデータ、定義毎破棄する。
関連付けられているインデックスなどがあれば、同時に破棄される。
drop table <テーブル名>;
制約
主キー
単独の列を指定する
複数の列で構成する
create table TEST ( NAME1 varchar(64) not null, NAME2 varchar(64) not null, VALUE varchar(256), primary key (NAME1, NAME2) );
インデックス
作成
- 制約
- 型
インデックスは以下の型には作成できない。
- LONG VARCHAR
- BLOB
- CLOB
- XML
- ユーザ定義型
- 列
インデックスは以下の列には自動で作成されているので設定できない。
- 主キー
- ユニークキー
- 外部キー
- 型
- 記法
CREATE [ UNIQUE ] INDEX <インデックス名> ON <テーブル名> ( <列名> [ ASC | DESC ] ... )
行
挿入
insert into <テーブル名> (<列名1>, <列名2>, ...) values (<値1>, <値2>, ...);
全ての列に値を代入する場合は、列名の指定を省略できる。
insert into <テーブル名> values (<値1>, <値2>, ...);
値に文字列を指定するときはダブルクォーテーションでなく、シングルクォーテーションで囲まなければならない。
自動生成列の取得
自動で値を生成するよう設定した列の値を挿入時に返すようにするには、次のようにSQLを実行する。
- テーブル定義
C12列が自動生成列
CREATE TABLE TABLE1 (C11 int, C12 int GENERATED ALWAYS AS IDENTITY)
- SQL実行
O/Rマッパー利用時は各O/Rマッパーの使用法に従う。
- 例1
Statement stmt = conn.createStatement(); stmt.execute( "INSERT INTO TABLE1 (C11) VALUES (1)", Statement.RETURN_GENERATED_KEYS); ResultSet rs = stmt.getGeneratedKeys();
- 例1
- 例2
Statement stmt = conn.createStatement(); String [] colNames = new String [] { "C12" }; stmt.execute( "INSERT INTO TABLE1 (C11) VALUES (1)", new String[]{<列名>[, ...]}); ResultSet rs = stmt.getGeneratedKeys();
- 例2
Statement stmt = conn.createStatement(); String [] colNames = new String [] { "C12" }; stmt.execute( "INSERT INTO TABLE1 (C11) VALUES (1)", new int[]{<列番号>[, ...]}); ResultSet rs = stmt.getGeneratedKeys();
句
LIMIT
結果の内、指定の行数だけを取得する。
OFFSET句を付加することで、先頭から指定の行だけスキップすることが可能。
OFFSET句のみを単独で使用することはできない。
単独で使用する場合はこちらを使用する。
LIMIT句は{}で括らないとエラーになるので注意。
- 記法
{ LIMIT <行数> [ OFFSET <行数> ] }
OFFSET
結果の内、先頭から指定の行だけ取得しない
- 記法
offset <行数> row
FETCH
結果の内、指定の行数だけを取得する
- 記法
fetch first <行数> row only
エラー
SQLSTATE: XSDB6
接続しようとしたDBが使用中である。
他のアプリケーションが使用しているか確認する。(ijによる接続も含む)
Derbyは起動中には1種類のアプリケーション(1種類のJVMインスタンス、1種類のクラスローダー)からしか接続を受け付けない。
従って、1度何らかのアプリケーションからアクセスすると他のアプリケーションからはDerbyを再起動しない限りアクセスできない。
ただし、ネットワークサーバモードで起動することで各接続がネットワークサーバインタフェースを中継することで隠ぺいされ、単一のJVMからの接続とDerbyの管理モジュールは認識する為、同時に複数の接続元からアクセス可能となる。
つまり、ネットワークサーバモードで起動している場合、ijで接続する際もローカル接続ではなく、ネットワーク接続を行う必要がある。
PROCEDURE
作成例
Derbyについて
データ管理構造
データベース
データベースは1つのDerbyインスタンスにおける、データ階層の最大の単位である。
- 一覧確認
データベースの一覧をDerbyから取得する手段はない。
ただし、各データベースにつき、Derbyのインストール場所にデータベース名を持つディレクトリが作成されるので、それをリストアップすることで、データベース一覧を取得可能
find $DERBY_HOME/ -maxdepth 1 -type d | egrep -v "/$|bin|lib|logs" | sed "s/.*\///g"
- データベースの削除
rm -rf $DERBY_HOME/<データベース名>
スキーマ
各データベースにはスキーマ(名前空間のようなもの)が存在し、ユーザはスキーマ配下にテーブルなどのオブジェクトを作成する。
Derbyではユーザがオブジェクトを作成する際、デフォルトでは”APP”スキーマが指定される。
その他のデフォルトで作成されるスキーマはDerby内部で利用されるもので、参照のみ可能である。
- 一覧確認
スキーマ一覧は以下のコマンドで確認できる。
SHOW SCHEMAS;
- 実行例
ij> SHOW SCHEMAS; TABLE_SCHEM ------------------------------ APP NULLID SQLJ SYS SYSCAT SYSCS_DIAG SYSCS_UTIL SYSFUN SYSIBM SYSPROC SYSSTAT
- 実行例
- 作成
CREATE SCHEMA schemaName [ AUTHORIZATION userName ]
AUTHORIZATION句を指定した場合、指定のユーザに使用権限を与える。
AUTHORIZATION句を指定しなかった場合、現在のユーザに使用権限を与える。
テーブル
デフォルトテーブル
データベースを作成すると、デフォルトでいくつかのテーブルが作成される。
- 一覧確認
ij> show tables; TABLE_SCHEM |TABLE_NAME |REMARKS ------------------------------------------------------------------------ SYS |SYSALIASES | SYS |SYSCHECKS | SYS |SYSCOLPERMS | SYS |SYSCOLUMNS | SYS |SYSCONGLOMERATES | SYS |SYSCONSTRAINTS | SYS |SYSDEPENDS | SYS |SYSFILES | SYS |SYSFOREIGNKEYS | SYS |SYSKEYS | SYS |SYSPERMS | SYS |SYSROLES | SYS |SYSROUTINEPERMS | SYS |SYSSCHEMAS | SYS |SYSSEQUENCES | SYS |SYSSTATEMENTS | SYS |SYSSTATISTICS | SYS |SYSTABLEPERMS | SYS |SYSTABLES | SYS |SYSTRIGGERS | SYS |SYSUSERS | SYS |SYSVIEWS | SYSIBM |SYSDUMMY1 |
SYSSTATEMENTS
select * from sys.SYSSTATEMENTS;
STMTID |STMTNAME |SCHEMAID |&|VALID|TEXT |LASTCOMPILED |COMPILATIONSCHEMAID |USINGTEXT ----------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- --------------------------------------------- 286cc01e-015d-de6b-fdd6-000000c97380|getUDTs |8000000d-00d0-fd77-3ed8-000a0a0b1900|S|false|SELECT CAST (NU LL AS VARCHAR(128)) AS TYPE_CAT, CASE WHEN (SCHEMANAME IS NULL) THEN CAST (NULL AS VARCHAR(128)) ELSE SCHEMANAME& |NULL ...
SYSTABLES
select * from sys.SYSTABLES;
TABLEID |TABLENAME |&|SCHEMAID |& ------------------------------------------------------------------------------------------------ 80000010-00d0-fd77-3ed8-000a0a0b1900|SYSCONGLOMERATES |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 80000018-00d0-fd77-3ed8-000a0a0b1900|SYSTABLES |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 8000001e-00d0-fd77-3ed8-000a0a0b1900|SYSCOLUMNS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 80000022-00d0-fd77-3ed8-000a0a0b1900|SYSSCHEMAS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 8000002f-00d0-fd77-3ed8-000a0a0b1900|SYSCONSTRAINTS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 80000039-00d0-fd77-3ed8-000a0a0b1900|SYSKEYS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 8000003e-00d0-fd77-3ed8-000a0a0b1900|SYSDEPENDS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R c013800d-00d7-ddbd-08ce-000a0a411400|SYSALIASES |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 8000004d-00d0-fd77-3ed8-000a0a0b1900|SYSVIEWS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 80000056-00d0-fd77-3ed8-000a0a0b1900|SYSCHECKS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 8000005b-00d0-fd77-3ed8-000a0a0b1900|SYSFOREIGNKEYS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 80000000-00d1-15f7-ab70-000a0a0b1500|SYSSTATEMENTS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 80000000-00d3-e222-873f-000a0a0b1900|SYSFILES |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R c013800d-00d7-c025-4809-000a0a411200|SYSTRIGGERS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R f81e0010-00e3-6612-5a96-009e3a3b5e00|SYSSTATISTICS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R c013800d-00f8-5b70-bea3-00000019ed88|SYSDUMMY1 |S|c013800d-00f8-5b53-28a9-00000019ed88|R b8450018-0103-0e39-b8e7-00000010f010|SYSTABLEPERMS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 286cc01e-0103-0e39-b8e7-00000010f010|SYSCOLPERMS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 2057c01b-0103-0e39-b8e7-00000010f010|SYSROUTINEPERMS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R e03f4017-0115-382c-08df-ffffe275b270|SYSROLES |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 9810800c-0121-c5e2-e794-00000043e718|SYSSEQUENCES |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 9810800c-0121-c5e1-a2f5-00000043e718|SYSPERMS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R 9810800c-0134-14a5-40c1-000004f61f90|SYSUSERS |S|8000000d-00d0-fd77-3ed8-000a0a0b1900|R a65c80ac-015d-de6b-fdd6-000000c97380|TEST |T|80000000-00d2-b38f-4cda-000a0a412c00|R 24 rows selected
SYSCOLUMNS
テーブルの列情報を取得できる。
列名、定義、自動採番列の現在付与済みの番号などが分かる。
ただし、現在付与済みの番号はcommitされていない場合は表示されないものの、その番号は次回付与されないので、必ずしも次の採番は現在の値+1というわけではない。
select * from SYS.SYSCOLUMNS
URL
Derbyに接続する際、URLの形式で接続先を指定する。
Derby用のJDBCを用いる一般的な使用方法では以下のようになる。
ネットワーク接続
jdbc:derby:{<IPアドレス>|<ホスト名>}:1527/<DB名>
ローカル接続
jdbc:derby:<DB名>
オプション
URLの末尾にオプションを付加することができる。
オプションは”;”(セミコロン)をつけ、その後に記述する
DBの作成
このオプションは接続時にデータベースがなかった場合は作成したうえで接続するかどうかを指定する。
create={ true | false }
- true
データベースがない場合、作成する - false
データベースがない場合、作成しない(接続失敗)
ストアドプロシージャ
DerbyではDerby内に保存して実行できるユーザ定義手続きにPROCEDUREとFUNCTIONの2種類が存在する。
両者とも、ユーザが独自のJavaメソッドを作成し、jar化してクラスパスを通すことで、任意の自作メソッドを呼び出すことができる機能である。
メソッド内でDBのデータを扱う場合はJDBC経由でアクセスする。
- PROCEDURE
完結した手続きで、単独でCALLコマンドにより呼び出される。
その為、SQL文中に組み込んで使用することはできない。
複数の列を取得するselect文のように、複数の値を持つ結果を返すことができる。
メソッド内部でselectの他、更新系のクエリを呼び出すことも可能。
トリガーとして実行することはできない。
- FUNCTION
FUNCTIONはSQL文中に組み込んで使用でき、実行結果をSQL文に反映させたり、SQLの結果をFUNCTIONの引数に与えたりすることができる。
複数の値を持つ結果を返すことができず、結果は単一の値でなければならない。
メソッド内部でselectは使用できるが、更新系のクエリを呼び出すことはできない。
トリガーとして実行することができる。
動作
ネットワークサーバモード
起動
Derbyを起動させても各データベースはすぐに使用可能にならない。
各データベースへ接続(ローカル接続も含む)があって初めて、使用可能な準備が行われる。
この準備を”boot”と呼ぶ。
bootされたデータベースはロックされ、接続しようとしたJVM、またはクラスローダーしか使用できないようになる。
オプションによって1つのデータベースがbootされたら他のデータベースもbootすると設定することが可能。
このbootプロセスがあるため、Derbyを起動後すぐにサービスインさせるのではなく、一旦何らかの接続を行ってからサービスインすると、すぐに使用可能となる。
これはキャッシュを有効にしている場合は、なおさら行うべき処理である。
リソース制限
Derbyには以下のリソース制限が存在する。
- テーブル数
java.lang.Long.MAX_VALUEの値(2^64)
- テーブル毎インデックス数
32767
- テーブル毎列数
1012
- インデックス毎列数
16
- テーブル毎行数
制限なし
- テーブル容量
制限なし。
ただし、OSで単一ファイルの最大サイズの制限がある場合はこれにかかる可能性がある。
- 行サイズ
制限なし。
ファイル構成
ページ
テーブルとインデックスはOSで定められたページ単位に管理されるが、ページは2種類作成される。
1種類はデータそのものであるが、もう1種類は管理情報を格納するページである。
この管理用のページはデータ用のページが最大8ページになるまで1ページで管理できる。
それ以上になると、もう1ページ管理用のページが作成される。
パフォーマンスチューニング
https://builds.apache.org/job/Derby-docs/lastSuccessfulBuild/artifact/trunk/out/tuning/index.html