2014年12月23日火曜日

H2データベースでテーブルが存在しない時だけテーブルを作成

H2データベースでテーブルが存在しない時だけテーブルを作成する方法です。

CREATE時に、IF NOT EXISTSを使用することで、テーブルが存在しない時のみ作成することができます。
これを使うことで、テーブル定義済み例外の発生を防ぐことができます。

CREATE TABLE IF NOT EXISTS USER (
  ID BIGINT NOT NULL AUTO_INCREMENT,
  NAME VARCHAR(100 CHAR) NOT NULL,
  PRIMARY KEY (ID)
);

このIF NOT EXISTSはVIEWの作成やカラムの追加時などにも使用できます。

2014年12月22日月曜日

[Oracle12c]generatedカラムの値をJDBC経由でinsert後に取得する

Oracle12cで追加された自動生成カラムの値を、JDBC経由でINSERTを行った際に取得する方法です。

コードサンプル

テーブル定義

CREATE TABLE USER_INFO
(
    ID INTEGER PRIMARY KEY NOT NULL,
    NAME VARCHAR2(100)
)

Javaコード

PreparedStatement statement = connection
        .prepareStatement(
                "insert into USER_INFO (name) values (?)",
                new String[]{"id"});
statement.setString(1, "なまえ");
int count = statement.executeUpdate();
System.out.println("count = " + count);

try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
    if (generatedKeys.next()) {
        System.out.println(generatedKeys.getInt(1));
    }
}

解説

PreparedStatement生成時に、自動生成キーを返す機能を持つPreparedStatementを生成します。
上のサンプルでは、自動生成カラムはID列なので、prepareStatementの2番めの引数にID列を指定しています。

必要な値をバインド後に、executeUpdateを呼び出してINSERT処理を実行します。

INSERT処理が正常に終了後、getGeneratedKeysを呼び出して、自動生成カラムに対して自動的に採番されて設定された値を取得します。
getGeneratedKeysは、ResultSetを返すのでフェッチ(nextメソッドの呼び出し)しながら値を取得していきます。
Oracleでは、getGeneratedKeysで返されるResultSetからの値の取得はインデックスのみ可能なので、カラム名によるアクセスは出来ません。

[Java8]インタフェースのデフォルトメソッド

Java8から新しく追加されたインタフェースのデフォルトメソッド。

デフォルトメソッドの定義

デフォルトメソッドは、defaultキーワードと共にメソッドを宣言します。
この例では、printメソッドがデフォルトメソッドとして宣言されています。
interface Hoge {
    default void print() {
        System.out.println("hoge");
    }
}

同じデフォルトメソッドを持つ複数のインタフェースを実装した場合

何もしなければコンパイルエラーとなります。
例えば、下のコードではImplクラスが同じ定義のデフォルトメソッドを持つI1とI2インターフェースを実装しているので、コンパイル時にエラーとして報告されます。
interface I1 {
    default void print() {
        System.out.println("I1");
    }
}
interface I2 {
    default void print() {
        System.out.println("I2");
    }
}

class Impl implements I1, I2 {
}

もしどちらか一方の実装を使用したいのであれば、superキーワードを使用して一方のインタフェースの実装を選択します。
下の例では、I2インタフェースのデフォルト実装を選択しています。
class Impl implements I1, I2 {
    @Override
    public void print() {
        I2.super.print();
    }
}

もちろん、下のコードのように実装を上書きすることもできます。
class Impl implements I1, I2 {
    @Override
    public void print() {
        System.out.println("Impl");
    }
}

片方がデフォルトメソッドで片方が抽象メソッドの場合も、コンパイルエラーとなります。
この場合も、上で説明したようにデフォルトメソッドを選択するか、このクラスで新たな実装をするか選択する必要があります。
interface I1 {
    default void print() {
        System.out.println("I1");
    }
}
interface I2 {
    void print();
}

class Impl implements I1, I2 {
}

一方が抽象クラスの場合には、抽象クラスに定義されたメソッドが優先されて選択されます。
例えば下のコードの場合、A1抽象クラスに定義されたprintメソッドが呼び出されます。
interface I1 {
    default void print() {
        System.out.println("I1");
    }
}

abstract class A1 {
    public void print() {
        System.out.println("A1");
    }
}

class Impl extends A1 implements I1 {
}

2014年11月3日月曜日

[Java8]メソッド参照

lambda式で定義したい処理内容と全く同じ処理をするメソッドがすでに提供されている場合には、
そのメソッドをメソッド参照という機能を使用してメソッドを渡してあげれば良い。

メソッド参照は、以下のように::演算子でクラス名(オブジェクト名)とメソッド名を連結して使用する。
使用できるパターンは、以下のとおり。

* オブジェクト::instanceメソッド
* クラス名::staticメソッド
* クラス名::instanceメソッド

使用例

System.out.printlnを使用した例は以下のようになる。
list.forEach(System.out::println);

// 上記は、以下と全く同じ
list.forEach(s -> System.out.println(s));

オーバロードされたメソッドがある場合

メソッド参照使用時で、オーバロードされたメソッドが存在していた場合にどのメソッドを呼びだそうとしているかについては、コンパイラがコードの内容から判断しようとする。

例えば、以下の例だとメソッド参照が使用された箇所の関数型インタフェースが受け取る型に対応したメソッドが使用される。

public class Hoge {

    public static void main(String[] args) {
        List strings = Arrays.asList("1", "2", "3");
        strings.forEach(Hoge::output);  // Stringを引数に取るoutputが選択される

        List numbers = Arrays.asList(1, 2, 3);
        numbers.forEach(Hoge::output);  // intを引数に取るoutputが選択される
    }

    public static void output(String s) {
        System.out.println("string");
    }

    public static void output(int i) {
        System.out.println("int");
    }
}

2014年11月2日日曜日

[Java8]Lambda式の形式

ラムダ式は、引数 -> 式本体の形式で記述する。

基本パターン

(String first, String second) -> {
  return Integer.compare(first.length, second.length)
}

型推論可能な場合は、引数の型を省略出来る

左辺の総称型などから推論可能な場合などに型推論される。
(first, second) -> {
  return Integer.compare(first.length, second.length)
}

型推論された引数を一つだけ保つ場合には、カッコも省略可能

Arrays.asList(1, 2, 3, 4, 5).forEach(n -> System.out.println(n));

アノテーションなど

メソッドの引数と同じように、、アノテーションやfinal修飾子をつけることも可能
(final String first, final String second) -> {
  return Integer.compare(first.length, second.length)
}

戻り値について

lambdaの戻り値は明示しない。常に文脈から型が判断される。
以下の例だとintが期待されているところで使用できる。

※分岐などで結果を返したり返さなかったりするようなlambda式は不正となる。(コンパイルエラー)
(final String first, final String second) -> {
  return Integer.compare(first.length, second.length)
}

2014年10月22日水曜日

Java8のFunctionalInterfaceアノテーション

FunctionalInterfaceは、関数型インタフェースであることを示すために使用するアノテーション。

基本的に、関数型インタフェースの要件(インタフェースで抽象メソッドは1つなど・・・)を満たしていれば良いが、
FunctionalInterfaceアノテーションを付加するとコンパイル時に関数型インタフェースの要件を満たしていない場合コンパイルエラーとしてくれる。
また、このインタフェースが関数型インタフェースであることが、明確なので関数型インタフェースにはこのアノテーションを付加するとよい。

例えば、以下の様なインタフェース定義は関数型インタフェースの要件を満たさないためコンパイルエラーとなる

@FunctionalInterface
interface Hoge {
    void hoge();
    void fuga();
}

エラー内容としては以下の様なものが出力される。
Error:(1, 1) java: 予期しない@FunctionalInterface注釈
  Hogeは機能インタフェースではありません
    インタフェース Hogeで複数のオーバーライドしない抽象メソッドが見つかりました

2014年10月5日日曜日

[jQuery]first-of-typeセレクタ

バージョン1.9から追加されたセレクタ。

親要素内で、セレクタで指定した要素が最初に出現する要素が選択される。

この例だと、div要素内で最初に出現するspanタグが選択される。
(hogeとあいうえおのspanタグ)
<div>
  <span>hgoe</span>
  <span>fuga</span>
</div>
<div>
  <span>あいうえお</span>
  <span>かきくけこ</span>
  <span>さしすせそ</span>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
  $("span:first-of-type").css({
    color: 'red'
  });

</script>

表示結果

選択された最初のspanタグにスタイルが設定されているのがわかる。

※first-of-typeと逆のlast-of-typeセレクタもある。

2014年7月11日金曜日

Activiti-explorerをtomcatにデプロイ

1. activitiをダウンロード

http://activiti.org/download.html からActivitiをダウンロードする。
ダウンロードされたファイルは任意のディレクトリに解凍しておく。

2. Tomcatをダウンロード

http://tomcat.apache.org/download-80.cgiからTomcatをダウンロードする。
ダウンロードされたファイルは任意のディレクトリに解凍しておく。

3.Activiti-ExplorerをTomcatにデプロイする。

ダウンロードしたAcitivitiを解凍したディレクトリ内の「wars/activiti-explorer.war」を、
Tomcatを解凍したディレクトリの「webapps」にコピーする。

4.Tomcatを起動する。

Tomcatを解凍したディレクトリの「bin/startup.sh」を実行し、Tomcatを起動する。

5.画面を開く

http://localhost:8080/activiti-explorer/ にアクセスする。
以下の様な画面が開けば、デプロイは成功しています。


6.ログインの実行

アカウントは「http://www.activiti.org/userguide/#deploymentWithExplorer」の「Activiti setup」の章に記述されています。

まずは、デプロイして実行出来るところまで。
UI気にしなければこのまま、使えるのかな?もうちょっと調べてみないと。

2014年4月29日火曜日

[AngularJS]ng-initを使用して初期値の設定

ng-initディレクティブを使用して、初期値の設定が出来る。

コード

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>ng-init</title>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
</head>
<body ng-app>
<div ng-init="hello = 'Hello'" >
  {{hello}} World!!<br/>

  <label>入力欄
    <input type="text" ng-model="hello">
  </label>
</div>
</body>
</html>

実行結果

2014年4月2日水曜日

[html5]canvas上に画像を配置

context#drawImageを使用してcanvas上に画像を配置することができる。

以下のように3種類のdrawImageを用途によって使い分ける。
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>canvasに画像を配置</title>
  <style>
    #mycanvas {
      outline: blue 1px solid;
    }
  </style>
</head>
<body>
<!-- canvas上に配置する予定の画像を非表示で用意する -->
<div style="display: none">
  <img src="hoge.png" alt="example" id="myimage" width="592" height="59"/>
</div>
<canvas id="mycanvas" width="800" height="350">
</canvas>
<script>
  !function () {
    var canvas = document.getElementById('mycanvas'),
        ctx;

    if (!canvas.getContext) {
      return;
    }

    ctx = canvas.getContext('2d');
    window.addEventListener('load', function() {
      var image = document.getElementById('myimage');
      // 左上のポジション指定
      ctx.drawImage(image, 10, 10);
      // ポジションと幅、高さ指定
      ctx.drawImage(image,
          10, 90,   // 左上のポジション
          102, 49); // 幅と高さ
      
      // 元画像の描画範囲(切り取り範囲)と幅と高さを指定
      ctx.drawImage(image,
          60, 30,   // 切り取り開始位置(左上の開始位置)
          25, 40,   // 切り取る幅と高さ
          10, 180,  // 画像を配置する左上のポジション
          25, 40);  // 画像の幅と高さ
    });
  }();
</script>
</body>
</html>

2014年3月21日金曜日

[html5]datalistタグ

datalistタグを使用すると、関連付けられたinputタグに入力候補をリスト表示することが出来る。
関連付けは、inputタグのlist属性とdatalistタグのid属性で行う。

テキストフィールドで使用した例

<input type="text" name="n" list="J1"/>
<datalist id="J1">
  <option value="ベガルタ仙台">
  <option value="鹿島アントラーズ">
  <option value="柏レイソル">
  <option value="浦和レッズ">
  <option value="大宮アルディージャ">
  <option value="FC東京">
  <option value="横浜Fマリノス">
  <option value="川崎フロンターレ">
  <option value="アルビレックス新潟">
  <option value="ヴァンフォーレ甲府">
  <option value="清水エスパルス">
  <option value="名古屋グランパス">
  <option value="セレッソ大阪">
  <option value="ガンバ大阪">
  <option value="ヴィッセル神戸">
  <option value="徳島ヴォルティス">
  <option value="サンフレッチェ広島">
  <option value="サガン鳥栖">
</datalist>

Chromeでの表示例


色選択で使用した例

<input type="color" name="color" list="c">
<datalist id="c">
  <option value="#000000">
  <option value="#ff0000">
  <option value="#00ff00">
  <option value="#0000ff">
  <option value="#ffffff">
</datalist>

Chromeでの表示例


2014年2月15日土曜日

html5の必須入力欄のスタイル定義

cssを使用してhtml5で追加された必須入力欄(required属性が設定されいる項目)のスタイルを定義する方法

required擬似クラスに対してスタイル定義をすることで、required属性が設定された入力欄のスタイルを変更出来る。
    input:required {
      background-color: lightcoral;
    }

[html5]日付・時間系の入力欄

日付

input type="date"で日付入力欄になる

<input type="date" >

出力例


時間

input type="time"で時間入力欄になる

<input type="time" >

出力例


年月

input type="month"で時間入力欄になる

<input type="month" >

出力例

2014年2月9日日曜日

[CoffeeScript]オブジェクトのプロパティを一覧表示

オブジェクトのプロパティの値をCoffeeScriptで一覧表示する方法。

CoffeeScriptでは、「for of」を使ってプロパティ数分ループを行って処理をする。
JavaScriptの場合は、「for in」なので微妙に違いがあって間違えやすい気がする。

コード例

for key, value of 変数名で、オブジェクトの全プロパティに対して処理が出来る。
hoge =
  k1: 'v1'
  k2: 'v2'

for key, value of hoge
  console.log key, ' = ', value

class Hoge
  prop1: 'prop1'
  prop2: 'prop2'

for key, value of new Hoge()
  console.log key, ' = ', value

実行結果

オブジェクト、インスタンスともにプロパティ名とプロパティの値が出力される。
k1  =  v1
k2  =  v2
prop1  =  prop1
prop2  =  prop2

2014年1月26日日曜日

AngularJSでHello World

http://docs.angularjs.org/cookbook/helloworldを見つつAngularJSでHello Worldをやってみた。
Controllerのロジックは、CoffeScriptにしてみたぐらいで、後は上記のサイトの内容通り。

html

ポイントは、htmlタグでng-appディレクティブを記述しているところ。
これで、htmlタグはいかがAngularJSアプリとなる。
<!DOCTYPE html>
<html ng-app="">
<head>
  <meta charset="utf-8" />
  <title>AngularJSでHello World!!</title>
</head>
<body>
<div ng-controller="HelloController">
Your name: <input type="text" ng-model="name"/>
<hr />
Hello {{name || "World"}}!
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="hello.js"></script>
</body>
</html>

JavaScript

htmlのng-controllerディレクティブで指定したControllerに対応するfunctionを定義する。

CoffeeScriptだと関数がグローバルスコープとならないので、関数名の頭に@をつけたりwindowオブジェクトに作成してあげる必要がある。
ちょっとイケてない感じなのが残念。

このJavaScriptでは、コントローラのスコープ($scope)内にname属性を定義して'World'を代入しています。
@HelloController = ($scope) ->
  $scope.name = 'World'

実行結果

JavaScriptでname属性に設定した値が、「Hello {{name || 'World' }}!」部に出力される。
Your name:

Hello {{name || "World"}}!