プログラマメモ2 - programmer no memo2

h2 tacpserverでアプリケーションから起動 2014/04/27

javaです。h2です。

プログラムからtcpサーバーとして起動。
が、どうもbaseDir指定しとかないといけないのかが確信もてず。

いまのところ以下のコードで起動
        Server server = Server.createTcpServer(
                new String[] { "-tcpPort", "9092", "-tcpAllowOthers",
                        "-pgAllowOthers", "-baseDir", BASE_DIR }).start();

作成されるDBの実体はどこなんだろう。。。

H2 - afterカラムして追加はできないような....BEFOREしかない 2011/06/26

H2です。
dropしてcreateしてたテーブルですが、データが入ってしまったので、alterしてカラム追加です。

alter_table_add - SQL Grammar

afterカラムして追加はできないような....BEFOREしかないような。

一番最後に追加したい場合は普通にaddするだけなので、afterが文法的になくても困らないけど。

H2 データ投入方法 2011/05/15

H2です。



データ投入方法です。

java -cp /h2/bin/*.jar org.h2.tools.RunScript -url "url" -script SQL.sql

って感じ

テストデータはスクリプト用意して出したり入れたりできるよ。

H2使いやすくて便利だなー

H2で複合キー 2011/04/08

SQL Grammar

H2で複合キーです。

drop table aaa;
create table aaa
(
table_name VARCHAR2(100) ,
a1 VARCHAR2(100),
a2 VARCHAR2(100),
a3 VARCHAR2(100),
a4 VARCHAR2(100),
a5 VARCHAR2(100),
a6 VARCHAR2(100),
a7 VARCHAR2(100),
a8 VARCHAR2(100),
a9 VARCHAR2(100),
a10 VARCHAR2(100),
a11 VARCHAR2(100),
a12 VARCHAR2(100),
a13 VARCHAR2(100),
PRIMARY KEY(table_name, a1),
) ;


参考
H2 Databaseで複合キー|localhost:1981

H2でテーブル作成時のSQLを取得 2009/10/17

H2データベースです。

select SQL from INFORMATION_SCHEMA.tables;


システムテーブルであるINFORMATION_SCHEMAからいろいろ情報取得できます。

webのH2コンソールで、ためしてみました。


実験するときに使いやすいのでついつい使ってしまうH2です。

H2 Database - CREATE DOMAINが使える 2008/05/28

H2 Database です。


ドキュメントみるとCREATE DOMAINが使えるようです。
えーと、CREATE DOMAINを使う理由は、テーブルごとに制約の設定がちらばることが防げるといったところでしょうか。たぶんこれが実用的な説明なのかも(postgresの説明であった。CREATE DOMAIN)。

あと、CREATE DOMAINが何かしらの型を強制するものであるならいいのかなぁとか考えたり。

参考

H2 Database - MERGE INTOが使える 2008/05/24

SQLについてあまり知らないので、よく悩むのは、レコードがなければinsert、あればupdateと処理するとき。
まずselectして調べて、手続き型言語(SQLを操作する方の側)で、if~else~するっていうのしか思いつかなかったのだけど、oracle 9iというものは、どうもMERGEというものが使えるらしい。

参考



それで、このMERGEって何気に、H2 Databaseで、使えることがわかって、得した気分。
upsert = (update or insert)ってことなのでしょうかね。
対象の行はユニークになる行でないとだめなようです。

Updates the row if it exists, and if the row does not exist, inserts a new row.
If the key columns are not specified, the primary key columns are used to find the row.
This command is sometimes called 'UPSERT' as it updates a row if it exists,
or inserts the row if it does not yet exist.
If more than one row per new row is affected, an exception is thrown.H2 Database Engine

H2 Database - グラフィックなデータを格納してみる。 2008/05/22
2008/09/27

Javaです。
データベースにイメージを格納します。

動機


シナリオ
画像を公開されているwebAPIから取得します。同じ画像を何度も、取得すると提供API側に負荷がかかります。
取得した画像をキャッシュするようにしてください。


というわけで、H2を使って、メモリ上にもたせてみる手習いです。
H2でなければいけないというわけではもちろんないです。

byteの配列を格納します。
その際に、ステートメントのsetBinaryStreamを使っています。
setBytesを使ってもいいようです。

参考

package h2test;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test {

static class ImageUtils {
public static byte[] getImageBytes(BufferedImage image,
String imageFormat) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(bos);
image.flush();
ImageIO.write(image, imageFormat, os);
os.flush();
os.close();
return bos.toByteArray();
}
}

public static void main(String[] args) throws SQLException,
ClassNotFoundException, IOException {

// 格納用の画像を作成
BufferedImage bufferedImage = new BufferedImage(200, 200,
BufferedImage.TYPE_INT_ARGB);
{
Graphics2D g2d = (Graphics2D) bufferedImage.createGraphics();
g2d.setColor(new Color(24, 65, 199, 30));

g2d.fillRect(0, 0, 200, 200);
g2d.dispose();
}

Test test = new Test();

test.init();

test.update("INSERT INTO imagetable ( id, image ) VALUES(?, ?)",
"1234", ImageUtils.getImageBytes(bufferedImage, "png"));

Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {

connection = test.getConnection();
statement = connection.createStatement();
resultSet = statement
.executeQuery("select id, image from imagetable");
if (resultSet.next()) {
String id = resultSet.getString("id");
Object o = resultSet.getBinaryStream("image");

try {
final BufferedImage image = ImageIO
.read((ByteArrayInputStream) o);

Thread thread = new Thread(new Runnable() {
public void run() {

JPanel p = new JPanel() {

protected void paintChildren(Graphics g) {

g.drawImage(image, 0, 0, null);

}

};
JFrame frame = new JFrame();
frame

.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(p);
frame.setVisible(true);
}
});
thread.start();
} catch (IOException e) {
e.printStackTrace();
}

}
System.out.println();

} catch (SQLException e) {
e.printStackTrace();
} finally {
Test.close(resultSet, statement, connection);
}
}

protected void init() throws SQLException, ClassNotFoundException {
update("CREATE TABLE imagetable ( id VARCHAR (64) NOT NULL,image BLOB)");
}

protected void update(String expression, Object... param)
throws SQLException, ClassNotFoundException {

Connection connection = getConnection();
PreparedStatement st = null;

st = connection.prepareStatement(expression);

int pos = 1;
for (Object o : param) {
if (o instanceof byte[]) {
byte[] bs = (byte[]) o;
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
bs);
st.setBinaryStream(pos, byteArrayInputStream, bs.length);
continue;
}

st.setObject(pos, o);

pos++;
}

int i = st.executeUpdate(); // run the query

if (i == -1) {
System.err.println("update failed....");
}

st.close();

connection.close();
}

protected void update(String expression) throws SQLException,
ClassNotFoundException {

Connection connection = getConnection();
Statement st = null;

st = connection.createStatement(); // statements

int i = st.executeUpdate(expression); // run the query

if (i == -1) {
System.err.println("update failed....");
}

System.out.println("====>" + i);

st.close();

connection.close();
}

// BasicDataSource dataSource = new BasicDataSource();
// {
// dataSource.setUrl("jdbc:h2:mem:mydb");
// dataSource.setUsername("sa");
// dataSource.setPassword("");
// }

protected Connection getConnection() throws SQLException,
ClassNotFoundException {
Connection connection = null;
try {
Class.forName("org.h2.Driver");
connection = DriverManager.getConnection("jdbc:h2:mem:mydb;DB_CLOSE_DELAY=-1",
"sa",
"");
} catch (SQLException e) {
throw e;
} catch (ClassNotFoundException e) {
throw e;
}

return connection;
}

static void close(ResultSet resultSet, Statement statement,
Connection connection) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
}
}

if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
}
}

if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
}
}
}
}

H2 Database - メモリオンリーデータベースでは、デフォルトでcloseするとデータがなくなる!? 2008/05/14

H2 データベースをインメモリで使う場合、デフォルトでは、closeするとその時点でデータがなくなってしまうようです。
この動作を変更する場合は、接続時のパラメータ(url)にDB_CLOSE_DELAY=-1を設定するといいようです。



以下、サンプルコード

protected Connection getConnection() throws SQLException,
ClassNotFoundException {
Connection connection = null;
try {
Class.forName("org.h2.Driver");
connection = DriverManager.getConnection("jdbc:h2:mem:mydb;DB_CLOSE_DELAY=-1",
"sa",
"");
} catch (SQLException e) {
throw e;
} catch (ClassNotFoundException e) {
throw e;
}

return connection;
}