Mar 12, 2006
[Derby] Derby を Tomcat 5.5 の DataSource に設定する方法
Server Mode で起動した Derby を Tomcat 5.5 に DataSource として登録する方法をメモ。 Tomcat 5.0 → 5.5 で設定方法が変わったことで、意外と設定に時間がかかってしまった。
- The Apache Tomcat 5.5 Servlet/JSP Container JNDI Datasource HOW-TO
- http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html
Derby を Server Mode で起動
Derby 10.1.2.1 を前提とする。
> set JAVA_HOME=c:\jdk1.5.0_06 > set DERBY_INSTALL=c:\db-derby-10.1.2.1-bin > cd db-derby-10.1.2.1-bin\frameworks\NetworkServer\bin db-derby-10.1.2.1-bin\frameworks\NetworkServer\bin>startNetworkServer.bat サーバーは、ポート 1527 で接続を受け入れる準備ができました。
Tomcat 5.5 の設定
Tomcat 5.5.15 を前提とする。
- Tomcat に Derby の JDBC ドライバを登録する。 derbyclient.jar、derbynet.jar、derbytools.jar を %CATALINA_HOME%/common/lib/ にコピーする。
-
DataSource の設定を行う。
%CATALINA_HOME%/conf/server.xml に下記の設定を追加する。
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="/myapp" docBase="myapp" reloadable="false" crossContext="true"> <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" driverClassName="org.apache.derby.jdbc.ClientDriver" url="jdbc:derby://localhost:1527/derbyDB;create=true"/> </Context> <Host>
Cannot create JDBC driver of class '' for connect URL 'null' java.sql.SQLException: No suitable driverという例外が発生する。
Web アプリケーションの設定
<web-app>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
アプリケーションからの呼び出し
普通に JNDI 経由で DataSource を取得すれば良い。
Context context = new InitialContext();
Object obj = context.lookup("java:comp/env/jdbc/TestDB");
DataSource dataSource = (DataSource)obj;
Connection connection = dataSource.getConnection();
Feb 23, 2006
[Derby] Derby メモ(3)
Derby のパフォーマンスに関するリファレンスをメモ。 「Derby ならでは」というものは少ない。 システムのプロパティ(derby.storage.pageCacheSize、derby.storage.pageReservedSpace、derby.storage.pageSize)くらいか。
- Performance tips and tricks
- http://db.apache.org/derby/docs/10.0/manuals/tuning/perf19.html
- derby.storage.pageCacheSize
- http://db.apache.org/derby/docs/10.1/tuning/tuning-single#N18B49
- derby.storage.pageReservedSpace
- http://db.apache.org/derby/docs/10.1/tuning/tuning-single#N18D9B
- derby.storage.pageSize
- http://db.apache.org/derby/docs/10.1/tuning/tuning-single#N18FFB
Feb 09, 2006
[Derby] Derby メモ(2)
Derby を使った Java 開発に必要な情報をメモ。
- Derby Reference Manual
- http://db.apache.org/derby/docs/10.1/ref/
- Statements
- http://db.apache.org/derby/docs/10.1/ref/crefsqlj39374.html
- DataTypes
- http://db.apache.org/derby/docs/10.1/ref/crefsqlj31068.html
- Derby System Tables
- http://db.apache.org/derby/docs/10.1/ref/rrefsistabs38369.html
Derby データ型 <-> Java データ型のマッピング
Derby と Java のデータ型のマッピングを一覧表にしたものが欲しかったのだが、探した限りでは見つからなかったので自作してみた。
とは言っても、↑の DataTypes の内容を表形式にしただけのオソマツなもの。
個人的にはこれで十分だが。
| Syntax | Corresponding compile-time Java type | JDBC metadata type (java.sql.Types) | 備考 |
|---|---|---|---|
| BIGINT | java.lang.Long | BIGINT | -9223372036854775808 (java.lang.Long.MIN_VALUE) ~ 9223372036854775807 (java.lang.Long.MAX_VALUE) |
| { BLOB | BINARY LARGE OBJECT } ( length [{K |M |G }])) | java.sql.Blob | BLOB | K(1024), M(1024 * 1024), G(1024 * 1024 * 1024) |
| CHAR[ACTER] [(length)] | java.lang.String | CHAR | |
| { CHAR | CHARACTER }[(length)] FOR BIT DATA | - | BINARY | |
| {CLOB |CHARACTER LARGE OBJECT}(length [{{K |M |G}])) | java.sql.Clob | CLOB | K(1024), M(1024 * 1024), G(1024 * 1024 * 1024) |
| DATE | java.sql.Date | DATE | サポートするフォーマットは
|
| { DECIMAL | DEC } [(precision [, scale ])] | java.math.BigDecimal | DECIMAL | |
| { DOUBLE PRECISION | DOUBLE } | java.lang.Double | DOUBLE | precision は 1 ~ 31。scale は precision 以下。 |
| FLOAT [ (precision) ] | - | REAL or DOUBLE | |
| { INTEGER | INT } | java.lang.Integer | INTEGER | -2147483648 (java.lang.Integer.MIN_VALUE) ~ 2147483647 (java.lang.Integer.MAX_VALUE) |
| LONG VARCHAR | java.lang.String | LONGVARCHAR | |
| LONG VARCHAR FOR BIT DATA | - | - | |
| NUMERIC [(precision [, scale ])] | java.math.BigDecimal | NUMERIC | |
| REAL | java.lang.Float | REAL | |
| SMALLINT | java.lang.Short | SMALLINT | -32768 (java.lang.Short.MIN_VALUE) ~ 32767 (java.lang.Short.MAX_VALUE) |
| TIME | java.sql.Time | TIME | サポートするフォーマットは
|
| TIMESTAMP | java.sql.Timestamp | TIMESTAMP | サポートするフォーマットは
|
| { VARCHAR | CHAR VARYING | CHARACTER VARYING }(length) | java.lang.String | VARCHAR | The maximum length for a VARCHAR string is 32,672 characters. |
| { VARCHAR | CHAR VARYING | CHARACTER VARYING } (length) FOR BIT DATA | - | VARBINARY | The maximum size of the length value is 32,672 bytes. |
Sep 28, 2005
[Derby] Derby の実行速度
Derby の INSERT 速度を試してみた。 時間がなかったのでかなりいい加減。 非常に単純な INSERT 文を 100 万回繰り返してみた。
結果
| embedded モード | server モード | |
|
INSERT 1000000回 コネクション毎に 1000000 件ずつ 1 回繰り返し |
45406msec (≒45秒) | 320594msec (≒5分) |
|
INSERT 1000000回 コネクション毎に 1000 件ずつ 1000 回繰り返し |
51797msec (≒52秒) | 321812msec (≒5分) |
|
INSERT 1000000回 コネクション毎に 1 件ずつ 1000000 回繰り返し |
798422msec (≒13分) | 計測不能(何故か Exception で落ちる) |
環境
- OS
- Windows XP Professional
- CPU
- Pentium4 2.4GHz
- Memory
- 1GByte
コード(部分抜粋)
protected void insertRecordMassively1() throws SQLException {
// 1 回のコネクションで 1000 件の INSERT を 1000 回繰り返す。
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
Connection connection = this.getConnection();
try {
PreparedStatement statement = connection
.prepareStatement("INSERT INTO sample VALUES (?,?)");
for (int j = 0; j < 1000; j++) {
int field01 = (int) ((Math.random() * 100000) % 10000);
String field02 = "01:" + field01;
statement.setInt(1, field01);
statement.setString(2, field02);
statement.executeUpdate();
}
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
long end = System.currentTimeMillis();
System.out.println("INSERT * 1000 * 1000 : " + (end - start) + "msec");
}
Sep 26, 2005
[Derby] Derby を server モードで起動
先日は Derby を embedded モードで起動したので、今回は server モードを試してみた。 server モードの場合も embedded モードとほとんど同一のコードで起動できた。 意外と簡単。 クライアント側も Driver と URL を変更したら何事も無く接続できた。
Derby の実行環境構築
Derby を Server モードで起動する場合、embedded モードで利用したもの + α の jar が必要になる。
- Derby(derby.jar、derbynet.jar、derbyclient.jar) をクラスパスに追加
サンプルコード
package jp.in_vitro.codelets.derby;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.apache.derby.drda.NetworkServerControl;
public class Codelet3 {
public Codelet3() {
super();
}
public static void main(final String[] args) throws Exception {
Codelet3 me = new Codelet3();
me.execute();
}
protected void execute() throws Exception {
// Derby の起動。
DerbyServer server = new DerbyServer();
server.start();
while (!server.isInitialized()) {
Thread.sleep(1000);
}
// ネットワーク(と言っても loopback)経由で Derby に接続。
DerbyClient client = new DerbyClient();
client.initializeClient();
client.execute();
// Derby の終了。
server.stop();
}
public static class DerbyClient {
private static final String DRIVER = "org.apache.derby.jdbc.ClientDriver";
private static final String PROTOCOL = "jdbc:derby://localhost:1527/";
public DerbyClient() throws ClassNotFoundException {
super();
this.initializeClient();
}
public void execute() throws SQLException {
Connection connection = null;
try {
connection = this.getConnection();
Statement statement = connection.createStatement();
ResultSet rs = statement
.executeQuery("SELECT * FROM sys.systables");
while (rs.next()) {
System.out.println("" + rs.getString(1));
}
rs.close();
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
protected void initializeClient() throws ClassNotFoundException {
Class.forName(DRIVER);
}
protected Connection getConnection() throws SQLException {
Connection connection = null;
Properties props = new Properties();
props.put("user", "me");
props.put("password", "password");
connection = DriverManager.getConnection(PROTOCOL
+ "derbyDB;create=true", props);
connection.setAutoCommit(false);
return connection;
}
}
public static class DerbyServer implements Runnable {
private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
private static final String PROTOCOL = "jdbc:derby:";
private Thread thread;
private boolean initialized;
public DerbyServer() {
super();
}
public void start() {
if (this.thread == null) {
this.thread = new Thread(this);
this.thread.start();
}
}
public void stop() {
if (this.thread != null) {
this.thread = null;
}
}
public void run() {
try {
this.initializeDBMS();
while (this.thread != null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
this.destroyDBMS();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isInitialized() {
return this.initialized;
}
protected void initializeDBMS() throws Exception {
System.setProperty("derby.drda.startNetworkServer", "true");
Class.forName(DRIVER).newInstance();
NetworkServerControl server = new NetworkServerControl();
server.ping();
this.initialized = true;
}
protected void destroyDBMS() throws SQLException {
this.initialized = false;
Connection connection = null;
try {
connection = DriverManager.getConnection(PROTOCOL
+ ";shutdown=true");
connection.commit();
} catch (SQLException e) {
// Derby が正常終了すると SQLException が発行される。
System.out.println("" + e.getLocalizedMessage() + " : "
+ e.getErrorCode());
} finally {
if (connection != null) {
connection.close();
}
}
}
}
}
Sep 20, 2005
[Derby] Derby メモ
Derby で調べた内容を少しだけメモ。 Derby 公式サイトにあるドキュメントを拾い集めただけ。
Derby environments
Derby には "embedded" モードと "server" モードで動作できる。 "embedded" モードはアプリケーション内部で起動されて、そのアプリケーション内でのみ使用可能なモード。"server" モードは単体でアプリケーションとして動作するモードで、複数のクライアントアプリケーションから使用可能。 コネクションの張り方やマルチスレッドなどで挙動が異なるらしい。
- Environments in which Derby can run
- http://db.apache.org/derby/docs/10.1/getstart/getstart-single.html#cgsquck70629
- Connection Mode
- http://db.apache.org/derby/docs/10.1/devguide/devguide-single.html#N16F6D
Derby Driver
Derby で使用できる JDBC ドライバは以下の 2 つ。
- org.apache.derby.jdbc.EmbeddedDriver ・・・ "embedded" モード用ドライバ
- org.apache.derby.jdbc.ClientDriver ・・・ "server" モード用ドライバ
Database connection URL
URL の書式は以下の通り。
jdbc:derby://<server>[:<port>]/databaseName[;URLAttributes=<value> [;...]]
- Database connection URL
- http://db.apache.org/derby/docs/10.1/getstart/getstart-single.html#rgsquck30197
Derby プロパティ
Derby を実行する際に指定できるプロパティ一覧。
の様に JVM 起動時に指定するか、java -Dderby.system.home=c:\\derby ...
Properties props = System.getProperties();
props.setProperty("derby.system.home", "c:\\derby");
の様にアプリケーション中から指定する。derby.properties という設定ファイルに記述することもできる。
Sep 19, 2005
[Derby] Derby にチャレンジ
Derby とは
Derby は 元 CloudScape と呼ばれた RDBMS。 IBM が Apache に寄贈したもの。 Pure Java で DBMS 自体のサイズが 2M と小さいのがステキ。
Derby の実行環境構築
- Derby(derby.jar) をクラスパスに追加
サンプルコード
package jp.in_vitro.codelets.derby;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class Codelet {
private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
private static final String PROTOCOL = "jdbc:derby:";
public Codelet() {
super();
}
public static void main(final String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, SQLException {
Codelet me = new Codelet();
me.execute();
}
protected void execute() throws InstantiationException,
IllegalAccessException, ClassNotFoundException, SQLException {
// Derby を embedded モードで起動する。
this.initializeDBMS();
try {
try {
// テーブルの生成。
this.createTable();
} catch (SQLException e) {
// 既に Table が生成済みの可能性があるので・・・
}
// insert
this.insertRecord();
// update
this.updateRecord();
// select
this.selectRecord();
// delete
this.deleteRecord();
// テーブルの削除。
this.dropTable();
} finally {
// Derby のシャットダウン
this.destroyDBMS();
}
}
protected void initializeDBMS() throws InstantiationException,
IllegalAccessException, ClassNotFoundException, SQLException {
Class.forName(DRIVER).newInstance();
Connection connection = null;
try {
connection = DriverManager.getConnection(PROTOCOL
+ "derbyDB;create=true");
connection.commit();
} finally {
if (connection != null) {
connection.close();
}
}
}
protected void destroyDBMS() throws SQLException {
Connection connection = null;
try {
connection = DriverManager.getConnection(PROTOCOL
+ ";shutdown=true");
connection.commit();
} catch (SQLException e) {
// Derby が正常終了すると SQLException が発行される。
System.out.println("" + e.getLocalizedMessage() + " : "
+ e.getErrorCode());
} finally {
if (connection != null) {
connection.close();
}
}
}
protected Connection getConnection() throws SQLException {
Connection connection = null;
Properties props = new Properties();
props.put("user", "me");
props.put("password", "password");
connection = DriverManager.getConnection(PROTOCOL + "derbyDB", props);
connection.setAutoCommit(false);
return connection;
}
protected void createTable() throws SQLException {
Connection connection = this.getConnection();
try {
Statement statement = connection.createStatement();
statement
.executeUpdate("CREATE TABLE sample(field01 INT, field02 VARCHAR(10))");
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
protected void insertRecord() throws SQLException {
Connection connection = this.getConnection();
try {
Statement statement = connection.createStatement();
statement.executeUpdate("INSERT INTO sample VALUES (999,'dummy data')");
statement.executeUpdate("INSERT INTO sample VALUES (888,'hogehoge')");
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
protected void updateRecord() throws SQLException {
Connection connection = this.getConnection();
try {
Statement statement = connection.createStatement();
statement
.executeUpdate("UPDATE sample SET field01=100 WHERE field02='dummy data'");
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
protected void deleteRecord() throws SQLException {
Connection connection = this.getConnection();
try {
Statement statement = connection.createStatement();
statement.executeUpdate("DELETE FROM sample");
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
protected void selectRecord() throws SQLException {
Connection connection = this.getConnection();
try {
Statement statement = connection.createStatement();
ResultSet rs = statement
.executeQuery("SELECT * FROM sample ORDER BY field01");
while (rs.next()) {
System.out.println("field01=" + rs.getString(1) + ", field02="
+ rs.getString(2));
}
rs.close();
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
protected void dropTable() throws SQLException {
Connection connection = this.getConnection();
try {
Statement statement = connection.createStatement();
statement.executeUpdate("DROP TABLE sample");
connection.commit();
connection.close();
} finally {
if (connection != null) {
connection.close();
}
}
}
}



