ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

Java における byte 型について (あるいはバイナリデータを扱うためのキャスト)

この記事は、もともと次のページに書かれていた内容に、加筆・修正を行ったものです。

はじめに

この記事では、ビット列を角括弧で囲み、[00000000] のように表現する事にします。

byte 型の表現範囲

Java のプリミティブ型 (基本データ型) の 1 つに byte 型というものがあります。 その名の通り 1 バイト (8 ビット) のサイズの整数値を表現できます。

つまり、[00000000] から [11111111] まで表現することができます。

数値でいうと 0 (0x00) から 255 (0xFF) まで表現できる、と思うところですが、実際には Javabyte 型は符号付きであり、表現できる範囲は -128 から 127 までとなっています。

The values of the integral types are integers in the following ranges:

  • For byte, from -128 to 127, inclusive
  • (略)
Chapter 4. Types, Values, and Variables

バイナリデータを扱うための byte 型のキャスト

符号なしで 0 から 255 の整数を表現したい

上述のとおり byte 型には符号が付いているのですが、バイナリデータの各バイトを 0 (0x00) から 255 (0xFF) の整数値で扱いたい場面がたまにあります。 当然 byte 型のままでは 128 以上の整数値を扱えませんので、short 型や int 型にキャストする必要があります。 逆に、shortint で表現される 0 から 255 までの整数値を byte にキャストしたい場面もあるでしょう。 (例えば InputStream#read() メソッドは、バイトの情報を 0 から 255 までの整数値として返してきます。)

byte 型からの変換

Java SE 8 からは Byte クラスに便利メソッドが用意されているので、それを使うといいでしょう。 (id:nowokay さんに教えていただきました! ありがとうございます!)

Java SE 7 以下では自分でキャストする必要があります。

キャストする場合 (Java SE 7 以下の場合)

byte から intshort へのキャストは、widening primitive conversion です。 このキャストでは、キャストによって数値の情報が失われることがありません。 (キャスト前とキャスト後で数値として同じ値が表現される。)

バイトを非負整数で表現するという目的においては、単にキャストするだけでは MSB (Most Significant Bit) が 1 の場合 (すなわち、値が負の場合) に、期待する結果にはなりません。

byte valueByte = -1; // ビット列で表すと [11111111]
short valueShort = (short) valueByte; // valueShort の値は -1
                                      // ビット列で表すと [1111111111111111]

short 型にしたときにビット列としては [0000000011111111] となって欲しいところですが、元が負値であるために上位ビットに全て 1 が入ってしまっているわけです。 byte 型をキャストして 0 から 255 の整数値の表現にするには、キャスト後に下位 8 ビット以外を 0 にすれば良いでしょう。

byte valueByte = -1; // ビット列で表すと [11111111]
short valueShort = (short) valueByte; // valueShort の値は -1
                                      // ビット列で表すと [1111111111111111]
// 下位の 8 ビットだけ残し、残りを全て 0 にする。
valueShort &= 0xFF; // 期待通りの 255 という数値になる
                    // ビット列で表すと [0000000011111111]

// キャストと下位 8 ビット以外を削る処理を 1 行で行っても良い。
valueShort = (short) (valueByte & 0xFF);

byte 型へのキャスト

一方で、intshort から byte へのキャストは、narrowing primitive conversion です。 このキャストで整数型を byte に変換する場合、単純に元の数値を表すビット列の下位 8 ビットがキャスト後の byte 値となります。

なので、0 から 255 の整数値で表現される値を byte 型にする場合は、単純にキャストしてやればよいのです。

short valueShort = 0xFF; // 数値としては 255。 ビット列で表すと [0000000011111111]
byte valueByte = (byte) short; // 数値としては -1。 ビット列で表すと [11111111]

byte 値を 16 進数表記の文字列にする

C 言語を使う人にはおなじみの printf ですが、似たものが Java にもあります。 (Java SE 5 より導入された模様。)

これを使用すれば、簡単に byte 値を 16 進数表記の文字列にできます。 標準出力などに出力して目で確認したい時にはなかなか便利です。

byte b = (byte) 0xE8; // 数値としては -24

// String#format メソッドを使用して文字列取得。
String bStr = String.format("%02X", b); // => "E8"

// PrintStream#printf メソッドを使用してそのまま出力する。
System.out.printf("%02X", b);

Java SE 1.4 以前は 「Javaのbyte型を16進数で表現」 みたいにまどろっこしいことをしないとダメだったと思います (もしかしたらもっと楽な方法はあるのかも知れませんが) けど、なかなか便利になったものです。

読んだ: Java エンジニア養成読本

2014 年 12 月に発売された 『Java エンジニア養成読本 [現場で役立つ最新知識、満載!]』 を読みました。 これだけを読んで Java がわかるわけではないけど、歴史から Java EE、周辺技術に至るまで説明されていて、Java 初心者が全体を俯瞰するのに良さそうだと思いました!

内容紹介

本書は、複数の著者による共著になっています。

まず、巻頭記事がきしださんによる 「誰も教えてくれない Java の世界」。 Java の歴史や、Java のエディション (Java SE、EE、ME について)、JDKJREJCP、JSR の紹介や各種 IDE や有名なフレームワークの紹介など、Java を使い始めてみたけど世界観がよくわからない、という人に役立つ情報が凝縮されています。 「お前に Sun が救えるか」 といったネタも紹介されています。

続く特集 1 が irof さんによる 「Java 入門」。 もちろん Java の構文の細かいところまでは説明されていませんが、クラス定義についてや例外処理、標準ライブラリについてのプラクティスなどが紹介されています。

特集 2 は bitter_fox さんによる 「Java SE 8 時代のデータ処理入門」。 Java SE 8 で導入されたラムダ式や Stream API について説明されます。 私もここら辺のことはまだ詳しくは知らなかったのでためになりました。

特集 3 はキクタローさんによる 「現場で役立つ Java EE」。 Java 初心者にとっては Java EE とは何者なのか良くわからない存在だと思いますが、この特集を読むことでなんとなく何者であるかはわかると思います。 Java EE と一口に言ってもその技術要素は多岐に渡りますが、この特集では ServletJSFJAX-RSJPACDIEJB といったわりと良く使われる技術要素について主に説明されます。 私も JSFEJB については詳しくなかったので、本書を読んで勉強になりました。

特集 4 は渡辺さんによる 「現場で役立つチーム開発入門」。 Git や MavenJUnit によるテストや Jenkins といった、開発現場で良く使われている周辺技術が説明されます。

最後に 「イマドキの Java 受託開発の現場で求められる知識」 というタイトルで、提案や設計について、「web 開発の現場では Java の知識だけでなく、HTML や CSS、JS の知識なども必要である」 みたいな話や、テストやデプロイについて説明されます。

感想

Java 初心者が Java を使った web アプリケーション開発について学ぶのにちょうど良い書籍になっていると思います。 もちろん、前半は web アプリケーション開発とは関係なく Java について学べますし、Java を使うなら (web アプリケーション開発をするつもりがなくても) 読むと良いでしょう。

文体がいいのか構成がいいのかムックという本の形態が良いのかわかりませんが、技術書としては読みやすかったです。

既に Java について深い造詣があるならこの本を読む必要はないと思います *1 が、これから Java を使っていきたい人や最近 Java を学び始めた人は、この本を早い段階で呼んでおくと後々の学習が捗ると思います。 Java の良書はいろいろありますが、重量級なものも多いですので、まずは軽く本書から読んでみる、というのをオススメします。

あなたと Java エンジニア養成読本、今すぐ購入!

Kindle 版もあるようですよ!

Javaエンジニア養成読本 [現場で役立つ最新知識、満載!] (Software Design plus)

Javaエンジニア養成読本 [現場で役立つ最新知識、満載!] (Software Design plus)

Javaエンジニア養成読本[現場で役立つ最新知識、満載!]

Javaエンジニア養成読本[現場で役立つ最新知識、満載!]

*1:Java 8 周りはまだ、ということであれば 「Java SE 8 時代のデータ処理入門」 は役立つでしょう

【Retrofit を読む】 利用者が定義したインターフェイスに実装を提供する Java ライブラリの作り方 【リフクレション】

この記事は、はてなエンジニアアドベントカレンダー 2014 の 15 日目のエントリです。 昨日は id:chris4403 による 「開発合宿で何を考えてどう作ったか」 でした。

このエントリでは、Android アプリおよび Java アプリケーション用の REST クライアントライブラリである Retrofit のコードを参照しながら、利用者が定義したインターフェイスの実装を提供するようなライブラリの実装方法について説明します。 主に Java のリフレクションの話になります。

注意点など

  • 本記事中に掲載されている Retrofit のコードは、Apache License, Version 2.0 のもとで公開されているものです。
  • 記事執筆時点の master ブランチの最新のコミットを参照しています。
  • Android アプリ開発者で Retrofit のコードを読みたい人は Android Studio で Retrofit のプロジェクトを開くのが楽で良いと思います。

Retrofit の紹介

Retrofit について簡単に紹介します。 詳しい話は公式サイトの方を見てください。

Retrofit は Square によって開発されている REST クライアントライブラリです。 HTTP リクエストを実行するためのメソッドを持ったインターフェイスを定義すると、Retrofit がそのインターフェイスの実装を提供してくれます。 アノテーションにより、HTTP メソッドの指定やどの引数がなんのパラメータであるか、あるいはリクエストボディであるかといったことを指定できます。

下記は Groovy スクリプトはてなハイクの公開タイムラインを取得する REST クライアントのサンプルコード *1 です。 HTTP メソッドの種類とリクエスト先のパスを GET アノテーション で指定しています。 そして、リクエストごとにクエリパラメータを変更できるように、クエリパラメータの値を引数として受け取るようになっています。

@Grab('com.squareup.retrofit:retrofit:1.8.0')

import retrofit.RestAdapter
import retrofit.http.GET
import retrofit.http.Query

// HTTP リクエストを投げるメソッドを持つインターフェイスを定義する。
interface HaikuService {
    /** はてなハイクの公開タイムラインを取得する */
    @GET("/api/statuses/public_timeline.json")
    List<?> getPublicTimeline(@Query("page") int page, @Query("count") int count)
}

// 定義したインターフェイスの実装を取得。
RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint("http://h.hatena.ne.jp")
    .build()
HaikuService haiku = restAdapter.create(HaikuService.class)

// 取得した実装を使用してハイクの公開タイムラインの内容を表示。
def statuses = haiku.getPublicTimeline(1, 10)
for (def status : statuses) {
    println '---'
    println status.user.name
    println status.text
}

利用者側がインターフェイスを定義して、そのインターフェイスの実装をライブラリが提供する、というのが特徴的ですね。

なお、HTTP 通信の実装や、リクエストボディおよびレスポンスボディと Java オブジェクトの変換機能の実装については Retrofit 自体が持っているわけではありません。 (デフォルトで HTTP 通信の実装はプラットフォームに応じたものが使われ、変換機能には Gson が使われますが、好みに応じてそれらは変更できます。)

利用者が定義したインターフェイスに対して実装を提供するために必要な技術

さて、Retrofit のように利用者が定義したインターフェイスに対して実装を提供するようなライブラリを書くことを考えましょう。 Java では、リフレクションを使用することで実現可能です。

任意のインターフェイスに対して実装を提供するために、Proxy クラス を使用することができます。 そして、実行されたメソッドの情報を取得するために、リフレクションのための各種メソッドを使用できます。 この 2 つについて順番に説明します。

Proxy クラス

Proxy クラスは、動的プロキシクラス (実行時に指定されたインターフェイスを実装するクラス) を生成するためのクラスであり、また、動的クラスのスーパークラスにもなるものです。 実際のメソッド呼び出しの処理は InvocationHandler インターフェイス を実装したクラスのインスタンスが担います。 Proxy クラスを使うことで、実行時に任意のインターフェイスに実装を提供することができます。

Retrofit では、retrofit.RestAdapter#create(Class) メソッド の中で動的プロキシクラスのインスタンス生成が行われます。

  /** Create an implementation of the API defined by the specified {@code service} interface. */
  @SuppressWarnings("unchecked")
  public <T> T create(Class<T> service) {
    Utils.validateServiceClass(service);
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new RestHandler(getMethodInfoCache(service)));
  }

retrofit.RestAdapter#create(Class<T>) メソッド

上記コードを見ればわかるように、指定されたインターフェイスの実際のメソッド呼び出しを処理するのは retrofit.RestAdapter.RestHandler クラスです。

リフレクションによるメソッド情報の取得

メソッドが呼ばれた際に実行される HTTP リクエストの内容は、各メソッドに付けられたアノテーションや返り値の型、仮引数の情報によって決まります。 すなわち、メソッドの情報を実行時に見る必要があります。 メソッドの情報を実行時に得るには、Method クラス に定義されている各種メソッドが使用できます。

Retrofit ではどのような処理になっているのか見ていきましょう。 retrofit.RestAdapter.RestHandler#invoke(Object, Method, Object[]) メソッドの実装は次のようになっています。

  @SuppressWarnings("unchecked") //
  @Override public Object invoke(Object proxy, Method method, final Object[] args)
  throws Throwable {
    /* (略) */
    // Load or create the details cache for the current method.
    final RestMethodInfo methodInfo = getMethodInfo(methodDetailsCache, method);
    if (methodInfo.isSynchronous) {
      try {
        return invokeRequest(requestInterceptor, methodInfo, args);
      } catch (RetrofitError error) {
    /* (略) */

retrofit.RestAdapter.RestHandler#invoke(Object, Method, Object[]) メソッド

まず、getMethodInfo(Method) メソッド呼び出しにより指定のメソッドの情報を RestMethodInfo オブジェクトとして受け取り、その後 invokeRequest メソッドを呼び出して実際の HTTP リクエスト処理に入ります。 実際には、同期実行か非同期実行か、あるいは RxJava を使っているかで処理が分かれたりしますが、ここではそこら辺の詳細には立ち入りません。

例えば、HTTP リクエストの結果の受け取り方は RestMethodInfo#parseResponseType() メソッドで解析されます。

  private ResponseType parseResponseType() {
    // Synchronous methods have a non-void return type.
    // Observable methods have a return type of Observable.
    Type returnType = method.getGenericReturnType();

    // Asynchronous methods should have a Callback type as the last argument.
    Type lastArgType = null;
    Class<?> lastArgClass = null;
    Type[] parameterTypes = method.getGenericParameterTypes();
    if (parameterTypes.length > 0) {
      Type typeToCheck = parameterTypes[parameterTypes.length - 1];
      lastArgType = typeToCheck;
      if (typeToCheck instanceof ParameterizedType) {
        typeToCheck = ((ParameterizedType) typeToCheck).getRawType();
      }
      if (typeToCheck instanceof Class) {
        lastArgClass = (Class<?>) typeToCheck;
      }
    }
    /* (略) */

retrofit.RestMethodInfo#parseResponseType() メソッド

同期実行の場合はメソッドの返り値として HTTP リクエストの結果が返され、非同期実行の場合はコールバックオブジェクトが引数に渡されるようになっているので、下記のメソッドを呼ぶことでメソッドの返り値と仮引数との両方を確認しています。

他にも、メソッドに付けられたアノテーション一覧を取得するために getAnnotations() メソッド が使われたり、仮引数につけられたアノテーションを取得するために getParameterAnnotations() メソッド が使われたりしています。

まとめと参考文献

  • Proxy クラスと InvocationHandler インターフェイスを使用することで、任意のインターフェイスに対して動的プロキシ・クラスを生成することができる。
  • リフレクションにより、メソッドの返り値の型などの情報を実行時に取得することができる。
  • これらの機能を使うことで、利用者が定義したインターフェイスに実装を提供するライブラリを記述できる。

リフレクションについては次のドキュメントを参考にすると良いでしょう。

おわりに

この記事では、Retrofit の実装を参照しながら Java のリフレクション機能について紹介しました。 バグの原因になりがちなのでアプリケーションコード中で直接リフレクションを使用するのはできるだけ避けた方がいいと思いますが、リフレクションにより Retrofit のような便利なライブラリを実現することも可能ですので、いい感じに使っていきたいですね。

*1:サンプルコードなのでエラー処理などちゃんと行っていません。

google-http-java-client 入門

Java で HTTP 通信するときのクライアントライブラリを何にするかいつも悩むのですが、最近 google-http-java-client が気になってたのでちょっと使ってみました。 汎用的に HTTP 通信ができればよい、というような用途にはちょうど良さそうです。

数年前からベータ版や RC 版としては存在していましたが、正式にリリースされたのは今年のようです。

google-http-java-client について

Google によって書かれた Java の HTTP クライアントライブラリです。

HTTP トランスポートの抽象化がされており、実際の HTTP 通信を行う低層のライブラリを選択できるのが特徴です。 例えば java.net.HttpURLConnection を使ったり、Apache HTTP Client を使ったりできます。

また、リクエストやレスポンスのコンテンツボディの XMLJSON のパースやシリアライズを行う機能も含まれており、便利です。

使用できる環境は、Java 5 以降の Java SE 環境や Java EE 環境、Android 1.5 以降などです。

ざっくりとした使い方

準備

使用するためには JAR ファイルをライブラリパスに追加するとか、Maven の依存関係管理に追加するとかする必要があります。 2014 年 11 月 8 日現在の最新バージョンは 1.19.0 で、Maven Central Repository に置かれています。

Gradle を使っているならば次のように依存関係を記述すればよいです。

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.google.http-client:google-http-client:1.19.0'
}

HTTP リクエストを行う処理の全体の流れ

  1. HttpTransport オブジェクトを用意する。
    • これはアプリケーション全体で 1 つだけ存在すればよい。
  2. HttpTransportcreateRequestFactory メソッドを呼んで HttpRequestFactory オブジェクトを生成する。
  3. HttpRequestFactory から HttpRequest を生成する。
  4. HttpRequestexecute メソッドを呼び出してリクエスト実行、レスポンスとして HttpResponse を取得。
  5. レスポンスを処理したあと、終了処理。

サンプルコード

GET リクエストを投げてレスポンスボディを表示する例を Gist に置いてあります。 バージョン 1.19.0 を使用しています。

レスポンスのパース

HttpRequest#setParser メソッド を使って ObjectParser インターフェイスを実装したインスタンスをパーサーとして登録しておくと、レスポンスのパースを任せることができます。

ライブラリに含まれている ObjectParser の実装としては、JsonObjectParser クラスUrlEncodedParser クラス があります。

サンプルコード

/* 必要な import 文
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.UrlEncodedParser;
import com.google.api.client.util.GenericData;
*/

// HttpRequest オブジェクトにパーサーを設定しておく。
// (req は HttpRequest オブジェクト)
req.setParser(new UrlEncodedParser());
// リクエスト実行。
HttpResponse res = req.execute();
try {
    // レスポンスのパースを行う。 (上で設定した UrlEncodedParser が使われる。)
    GenericData d = res.parseAs(GenericData.class);
} finally {
    // (以下略)

レスポンスのパース後のクラスを作る

上の例ではパース後のクラスとして GenericData を使用しましたが、どういうパラメータが渡ってくるかわかっている場合、それを受け取るためのクラスを用意しておいて、フィールドに値を設定させることもできます。

例えば、OAuth 1.0 Protocol の Temporary Credentials を取得するためのリクエストのレスポンスをパースする場合を考えてみましょう。 レスポンスの形式は 「oauth_token=xxxxx&oauth_token_secret=xxxxx&oauth_callback_confirmed=true」 というものであることはわかっているので、次のようなクラスでレスポンスを受け取ることができます。 @Key アノテーション をフィールドに付けることで、パースした結果を受け取るフィールドであることを示しています。

/* 必要な import 文
import com.google.api.client.util.GenericData;
import com.google.api.client.util.Key;
*/

// 必ずしも GenericData を継承する必要はないが、継承しておけばフィールドで定義されていないパラメータも受け取ることができる。
public class OAuthTemporaryCredentialResponse extends GenericData {
    @Key("oauth_token")
    public String identifier;
    @Key("oauth_token_secret")
    public String sharedSecret;
    @Key("oauth_callback_confirmed")
    public String callbackConfirmed;
}

そして、パース時にこのクラスを指定することでパース結果を OAuthTemporaryCredentialResponse オブジェクトとして受け取ることができます。

    OAuthTemporaryCredentialResponse d = res.parseAs(OAuthTemporaryCredentialResponse.class);
    System.out.println("identifier: " + d.identifier); // フィールドアクセスによりレスポンスの値にアクセスできる。

関連

「うらがみが Java まわりの ORM を知りたい会」 に参加してきた

Java の O/R マッパーまわりの話を知りたかったので、6/14 に行われた勉強会 「うらがみが Java まわりの ORM を知りたい会」 に参加してきました。 会場は和室でした。

Java まわりの O/R マッパー、あんまり詳しくないのでいろいろ知れて良かったです。 メモを残しておきます。

発表内容

Java の ORM、Doma の話 +α (@backpaper0 さん)

いろんな O/R マッパーについての簡単な紹介と、Doma の紹介。

  • 紹介された O/R マッパーのうち、使うとしたら JPA か Iciql か Doma かなーという気持ちになった。 (個人の感想です。)
    • ちなみに紹介されてる O/R マッパーのうち私がちゃんと知ってるのは JPA だけ。
  • Iciql と H2 Database を組み合わせて Android アプリで使うことができる (実際に製品開発に用いた) とのこと。
    • H2 Database は Android 用のビルド (?) があるらしい。
    • Java DB (Derby) を Android アプリで使おうとして挫折したことがあるので、今度は H2 Database を試してみたい。
Doma について
  • 公式サイト: Welcome to Doma — Doma 2.0 ドキュメント
  • 2 系は Java 8 以降。 1 系は Java 7 までらしい。
  • Doma、なんのライブラリにも依存してないらしい。
  • Pluggable Annotation Processing API を使ってる。
    • その仕組み上他の言語で使えない。
  • 原則としてクエリは SQL ファイルに書かないといけない。 (クエリビルダもあるが使わない方が良いらしい。)
    • SQL には if とか書ける。 ほぼ Java のコードを書けるっぽい。
  • コンパイル時にいろいろ検出。 (対応する SQL ファイルがなかったり中身が空だったり、アノテーションがなかったりすると)
  • DAO の引数や戻り値、エンティティのプロパティ (?) などにドメインクラスを使用できる。 (良い!!!)
  • 自動生成されるのはエンティティの補助クラスと DAO の実装クラスと、ドメインクラスの補助クラス。
議論
  • SQL で書くか Criteria API か?
    • Criteria API の方が IDE の補助があったりするけど、コードが膨らんだりするし、Doma だとコンパイル時に検証してくれたりするし SQL が良いと思ってる。
    • みたいな議論もあった。

F 社乙女チームの ORM (黒) 歴史 (@daiksy さん)

  • Scala でサーバーサイドを書くにあたっての O/R マッパー選択の歴史。
  • Play framework。
  • 今は Slick か ScalikeJDBC が良さそうだけど、昔は悩ましかった。
  • 最初: Squeryl
    • Implicit conversion を駆使するから IDE の補完が微妙だったりしてしっくりこなかったらしい。
  • 2 個目: ScalaQuery (のちの Slick)。
    • 使いやすいし、後々デファクトスタンダードになるのは理解できる。
    • Scala 2.9 → 2.10 のバージョンアップ時に Slick と名を変えて 2.9 系は切り捨てられた。
    • ScalaQuery を使っていた web アプリケーションはあえなくレガシー化...。
    • Scala はバイナリ互換性がないのがつらいよね。
  • 最後: MapperDao を採用。 (現在も。)
    • Squeryl, Slick, Activate, Circumflex-ORM, MapperDao, SORM, Scala ActiveRecord などを検討して、結果的に MapperDao。
    • DSL が結構良い。 普通の SQL っぽい感じで書ける。
    • ドキュメントの量とかは少ないので、今からなら Slick とか ScalikeJDBC のが良さそうな気がする。

Scala 周りの文化は全然知らないので、そんな感じなのかーと思いながら聞いてた。 Scala 便利だけど互換性とか大変そう。

JOOQ の紹介 (@chipstar_light さん)

  • 使ったことないけど紹介。
  • O/R マッパーというより DB アクセスライブラリ。
  • テーブルから Java コードを生成して、型安全な SQLJava 上で書ける、て感じ??
  • 既存の O/R マッパーでいい感じのがないけど JDBC をそのまま使うのも微妙、って感じの時に効果的に使えそう。

ORM 初心者が使おうとした (@KYON_MM さん)

3 つの O/R マッパー紹介
  • JOOQ
    • 機能的には使いやすい。 大体揃っているしユーザー数も多そう。
    • QueryDSL を駆逐してやるという勢いを感じる。
  • Iciql
    • とても薄いラッパー。 手軽で良さそう。
  • Slick
    • Play Framework のデフォルトになる予定。
    • 型型しすぎてる雰囲気。
      • Scalaz と同じ雰囲気。
    • ScalikeJDBC の方が好きな人が多いのでは?
議論的な話
  • ロックやリトライのサポートの話。
    • O/R マッパーでいい感じにサポートされているものは少ない。
    • ロックはともかくリトライは O/R マッパーがサポートすべきものではない気がするなーと思ったりした。
  • コネクションプールなどが O/R マッパーの内部で実装されていて不便なことが多い、とか。
    • テスト時にコネクションプールに手を入れられると便利。
    • BoneCP 使いたい、とか。
    • ScalikeJDBC では HikariCP が使えるようになった。 素晴らしい。

MyBatis (@s_kozake さん)

  • 大規模な案件に MyBatis で挑んだ。
  • MyBatis
    • 以前は iBatis という名前。
    • レガシーな環境、非正規化されたデータベース、SQL 文の実行を完全に制御したい場合によい選択肢となる。
    • 自動生成されるソースは?
  • MyBatis のラッパーをこざけさんが頑張って作っていい感じに使えるようになってた。 (すごい。)
  • Proxy クラス というのを初めて知った。
    • めっちゃ便利やん。

GORM めっさゆるい (@kazuhito_m さん)

  • リファレンス: 7 Object Relational Mapping (GORM) 2.4.0
  • Grails 用の O/R マッパー。
    • Grails とは独立させて使おうとすると大変っぽい?
  • GORM、Groovy らしさがあふれてるなーと思った。
  • ゆるい感じで使いたいならいいけど、まじめに大規模開発に使うと死にそう。