SQLiteにMapオブジェクトを保存(おすすめはActiveAndroid)


チャオ!
SQLiteにMapオブジェクトを突っ込みたい場合ってあるあるですよね!

MapをSQLiteに保存

そういう場合は

Map → JSONObject → String

で保存して

String → JSONObject → Map

で読み込むのがおすすめ!

MapからStringに

MapからStringは超簡単♪

public String mapToJsonString(Map data) {
    if (data == null) {
        return null;
    }
    return new JSONObject(data).toString();
}

StringからMapに

StringからMapはちょっと面倒

public Map jsonStringToMap(String data) {
    if (data == null) {
        return null;
    }
    try {
        JSONObject json = new JSONObject(data);
        Iterator<Object> keys = json.keys();
        Map<String, Object> params = new HashMap<String, Object>();
        while (keys.hasNext()) {
            String key = keys.next().toString();
            String val = json.getString(key);
            params.put(key, val);
        }

        return params;
    } catch (JSONException e) {
        return null;
    }

    return null;
}

これでももうMapを保存し放題だね!

ActiveAndroidを使う場合

ナウなヤングはandroidでsqliteを使う場合ORMを使っていると思うけど、
おすすめはActiveAndroid

  • 勝手にできるIdが微妙
  • 複数のxxx.dbは使えない(?)

とか色々アレな所もあるけど、それを上回る魅力が!

で、ActivieAndroidでMapオブジェクトを保存するには

  1. 独自TypeSerializerを用意する
  2. AndroidManifest.xmlに一行追加

の2ステップだけで保存し放題!

1.独自TypeSerializerを用意する

好きな所にTypeSerializerを継承したMapSerializer.javaを保存

MapSerializer.java
package com.mypackage;

import com.activeandroid.serializer.TypeSerializer;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MapSerializer extends TypeSerializer {

    @Override
    public Class<?> getDeserializedType() {
        return Map.class;
    }

    @Override
    public Class<?> getSerializedType() {
        return String.class;
    }

    @Override
    public String serialize(Object data) {
        if (data == null) {
            return null;
        }
        return new JSONObject((Map)data).toString();
    }

    @Override
    public Map deserialize(Object data) {
        if (data == null) {
            return null;
        }
        try {
            JSONObject json = new JSONObject((String) data);
            Iterator<Object> keys = json.keys();
            Map<String, Object> params = new HashMap<String, Object>();
            while (keys.hasNext()) {
                String key = keys.next().toString();
                String val = json.getString(key);
                params.put(key, val);
            }

            return params;
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }
}

2.AndroidManifest.xmlに一行追加

AndroidManifest.xmlに下記を追記するれば準備完了!

AndroidManifest.xml
<meta-data android:name="AA_SERIALIZERS" android:value="com.mypackage.MapSerializer" />

例えば更にDateを保存するためのDateSerializerを追加した場合は

AndroidManifest.xml
<meta-data android:name="AA_SERIALIZERS" android:value="com.mypackage.Dateerializer,com.mypackage.MapSerializer" />

って感じで追加すればいい感じ。

使ってみる

あとはモデルで普通にMapを指定しておけばOKOK!

@Table(name = "myTable")
public class MyTable extends Model {

    @Column(name = "data")
    public Map data;
}