そーす

福岡在住。iOS/Androidアプリ, Webフロントエンドのエンジニアです。Swift, Kotlin, JavaScript, ReactNative

Ormaを既存プロジェクトに導入してみた

f:id:saburesan:20160223222201p:plain

Ormaを導入してみた。
v2.0

選んだ理由

  • 既存のプロジェクトへの導入だったので、モデルの制限が少ない方が良い
  • Android-CleanArchitectureを意識して設計していて、データ層はRxのSingle<POJO>を返すInterfaceのみを公開しているので、POJOが使えて現状のドメイン層への影響がない
  • RxJavaのObservableをサポートしてると尚よい

github.com

選ばれたのはOrmaでした。

既存のPOJOをモデル化

既存のMessageクラスをモデル化してみる。

Message.java

public class Message {

    public String key;

    public Long timestamp;

    public User sender;

    public String body;

    public MessageType dataType;

    public Image image;
}

Userクラス、Imageクラス、MessageTypeEnumも必要に応じてモデル化する。

User.java

public class User {

   public int id;

   public String name;

   public Image image;
}

Image.java

public class Image {
   public String originalImageUrl;

   public String thumbnailImageUrl;
}

MessageType.java

public enum MessageType{
    text, image
}

Messageクラスのモデル化

@Table
public class Message {

    @Column
    @PrimaryKey
    public String key;

    @Column
    public Long timestamp;

    @Column
    public User sender;

    @Column
    public String body;

    @Column
    public MessageType dataType;

    @Column
    public Image image;
}

@Table

テーブルの宣言アノテーション

@Column

カラムの宣言アノテーション

@PrimaryKey

カラムのプライマリーキー指定アノテーション

Messageクラスで必要なのはこれだけ。実にシンプル。 まだコンパイル通りませんがね。

Userクラスのモデル化

@Table
public class User {

   @Column
   @PrimaryKey
   public int id;

   @Column
   public String name;

   @Column
   public Image image;
}

StaticTypeAdapterを使う

StaticTypeAdapterはクラスをモデル化しなくてもsqliteに保存出来る形にするための機能です。 enumやモデル化するまでも無いクラスの場合はこれを使うと非常に便利です。
例えばImgeクラスであれば

@StaticTypeAdapter(
        targetType = Image.class,
        serializedType = String.class
)
public class ImageStaticTypeAdapter {

    @NonNull
    public static String serialize(@NonNull Image source) {
        return new Gson().toJson(source);
    }

    @NonNull
    public static Image deserialize(@NonNull String serialized) {
        return new Gson().fromJson(serialized, Image.class);
    }
}

のようにすることで、モデル化せずにDBへ保存ができます。
また、enumでは

@StaticTypeAdapter(
        targetType = MessageType.class,
        serializedType = String.class
)
public class MessageTypeStaticTypeAdapter {

    @NonNull
    public static String serialize(@NonNull MessageType source) {
        return source.name();
    }

    @NonNull
    public static MessageType deserialize(@NonNull String serialized) {
        return MessageType.valueOf(serialized);
    }
}

v2.0では@StaticTypeAdapterを宣言していればコンパイル時に勝手に読み取ってくれます。
このようにStaticTypeAdapterを使えば、モデル化するまでもないクラスやenumを簡単に保存できます。

超ライトに使いたい時とかはModel1つ作ってあとはStaticTypeAdapterでJSONで入れるっていう荒業も簡単だし、変更も容易なのでいいですね。