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 25, 2005
Sep 23, 2005
[Library] JavaSVN にチャレンジ
JavaSVN とは
Java から Subversion にアクセスできるライブラリ。 Subversion のクライアントを Pure Java で実装しているツワモノ。 お馴染み Eclipse 用 Subversion Plugin の Subclipse でも内部で利用されている。
- JavaSVN
- http://tmate.org/svn/
- JavaSVN サンプルコード
- http://tmate.org/svn/kb/examples/index.php
JavaSVN の実行環境構築
- JavaSVN (ganymed.jar, javasvn.jar, javasvn-cli.jar, javasvn-javahl.jar) をクラスパスに追加する
サンプルコード
package jp.in_vitro.codelets.javasvn;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
public class Codelet {
public Codelet() {
super();
}
public static void main(final String[] args) throws SVNException {
String url = "http://example.com/repos/";
String username = "myname";
String password = "mypassword";
Codelet me = new Codelet();
me.initializeJavaSVN();
SVNRepository repository = me.prepareSVNRepository(url, username,
password);
me.printInfo(repository, "projects/");
me.printInfo(repository, "projects/pom.xml");
repository.closeSession();
}
protected void initializeJavaSVN() {
DAVRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();
}
protected void printInfo(final SVNRepository repository, final String path)
throws SVNException {
SVNNodeKind nodeKind = repository.checkPath(path, -1);
if (nodeKind == SVNNodeKind.NONE) {
System.out.println("NONE");
} else if (nodeKind == SVNNodeKind.UNKNOWN) {
System.out.println("UNKNOWN");
} else if (nodeKind == SVNNodeKind.DIR) {
Map properties = new HashMap();
List children = new ArrayList();
repository.getDir(path, -1, properties, children);
System.out.println("*** properties ***");
for (Object key : properties.keySet()) {
System.out.println("" + key + " - " + properties.get(key));
}
System.out.println("*** children ***");
for (Object child : children) {
System.out.println("" + child);
}
} else if (nodeKind == SVNNodeKind.FILE) {
Map properties = new HashMap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
repository.getFile(path, -1, properties, baos);
System.out.println("*** properties ***");
for (Object key : properties.keySet()) {
System.out.println("" + key + " - " + properties.get(key));
}
}
}
protected SVNRepository prepareSVNRepository(final String url,
final String username, final String password) throws SVNException {
SVNRepository repository = SVNRepositoryFactory.create(SVNURL
.parseURIEncoded(url));
ISVNAuthenticationManager authenticationManager = SVNWCUtil
.createDefaultAuthenticationManager(username, password);
repository.setAuthenticationManager(authenticationManager);
return repository;
}
}
Sep 22, 2005
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();
}
}
}
}
Sep 17, 2005
[Library] Pure Java DBMS
Pure Java の RDBMS を探してみた。 探してみると結構な数がある。 hsqldb は以前試してみたことがあるが、イマイチ使い勝手が良くなかった。 というわけで、他の RDBMS を試してみよう。
- hsqldb - Original License
- http://hsqldb.org/
- Derby - Apache License, Version 2.0
- http://db.apache.org/derby/
- Mckoi - GPL
- http://mckoi.com/database/
- QED - Original License
- http://www.quadcap.com/home.html
- tinySQL - LGPL
- http://sourceforge.net/projects/tinysql/
- One$DB - LGPL
- http://daffodildb.com/one-dollar-db.html
Sep 15, 2005
[Library] Jsch にチャレンジ
JCIFS とは
SSH2 用の Java ライブラリ。 SFTP、SCPなどにも対応している優れもの。
- Jsch
- http://www.jcraft.com/jsch/index.html
- Jsch のサンプルコード
- http://www.jcraft.com/jsch/examples/
JCIFS の実行環境構築
- Jsch(jsch-0.1.23.jar) をクラスパスに追加。
サンプルコード
package jp.in_vitro.codelets.jsch;
import java.lang.reflect.Field;
import java.util.Vector;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.HostKey;
import com.jcraft.jsch.HostKeyRepository;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class Codelet {
public Codelet() {
super();
}
public static void main(final String[] args) throws Exception {
Codelet me = new Codelet();
me.connectSsh("192.168.1.1", "myname", "mypassword");
}
public void connectSsh(final String hostname, final String username,
final String password) throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException, JSchException {
JSch jsch = new JSch();
Session session = null;
while (true) {
try {
session = jsch.getSession(username, hostname, 22);
session.setPassword(password);
session.connect(3000);
break;
} catch (JSchException e) {
if (e.getLocalizedMessage().indexOf("UnknownHostKey") >= 0) {
// 無理矢理 known_host に登録。ホントはマズい。
HostKey hostkey = session.getHostKey();
HostKeyRepository hostkeyRepo = jsch.getHostKeyRepository();
Field field = hostkeyRepo.getClass().getDeclaredField(
"pool");
field.setAccessible(true);
System.out.println("" + field.getType());
Vector hostkeyRepoPool = (Vector) field.get(hostkeyRepo);
hostkeyRepoPool.add(hostkey);
session.disconnect();
continue;
}
break;
}
}
Channel channel = session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();
}
}
Sep 14, 2005
[Book] Programming Java Virtual Machine
書籍情報
![]()
Programming Java Virtual Machine
レビュー
Java の bytecode が何故動作するのか、という Java の世界における根本的な解説を提供してくれる一冊。 最近は Ease of Development(EoD) の旗印の下、コーディングを簡単に、簡単にという動きが強い。 ただ、現実には依然として bytecode レベルの知識がないと理解できないことも多い。 VM の知識というと毛嫌いする人も居るが、Java で真面目に生計を立てたいのなら是非一読を薦めたい。
Sep 10, 2005
[JSR] JSR 181 Web Services Metadata for the Java Platform ダイジェスト
Web Services Metadata for the Java Platform の仕様をざっと眺めたときのメモ。
JSR 181 Web Services Metadata for the Java Platform
オリジナルの入手はこちら → JSR 181
Concepts
Server Programming Model
Web Services Metadata
- Annotation: javax.jws.WebService
- Annotation: javax.jws.WebMethod
- Annotation: javax.jws.Oneway
- Annotation: javax.jws.WebParam
- Annotation: javax.jws.WebResult
- Annotation: javax.jws.HandlerChain
- Annotation: javax.jws.soap.SOAPBinding
- Annotation: javax.jws.soap.SOAPMessageHandlers
Java Mapping To XML/WSDL
SOAP Binding
Mapping JSR-181 to the J2EE 1.4 Runtime Environment
Using JSR-181 annotations to affect the shape of the WSDL
Sep 02, 2005
[Book] UML Distilled
書籍情報
日本語翻訳版
レビュー
UML の入門書としては非常に名の通った書籍なのでご存知の方も多いだろう。 この本の良いところは、UML の解説は入門に徹しつつもきちんと現実的な解説を織り込んでいるところ。 下手に何冊も UML の書籍を読み漁るよりも、この一冊を丁寧に読む方が良いと思う。

![[JavaSVN 0.9.3 のクラス図]](/blog/entries/Library/20050925_01/javasvn-0.9.3.png)


