Android Room封装成一个相似Redis的缓存数据库的效果

如何将Android Room封装成一个相似Redis的缓存数据库的效果。java

Android Room封装缓存。若是你还在用SharedPreferences,试试使用这种方式?android

Android Room是一个很是棒的数据库框架,提供了明确地Dao层来操做数据库(愈来愈像spring data jpa啦),这里我来告诉你如何使用Room封装出一个相似Redis的使用方式(写事后端的童鞋应该懂)。主要目标,把它弄成K/V数据库的效果。spring

1. 引入

allprojects {
    repositories {
        mavenCentral()
        google()
        jcenter()
        maven { url "https://jitpack.io" }
        maven { url "https://maven.google.com" }
    }
}

dependencies {
    implementation 'android.arch.persistence.room:runtime:1.0.0'
    annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
}
复制代码

2. 定义实体

缓存表数据库

@Entity(tableName = "cache")
public class CacheEntity {
    @PrimaryKey(autoGenerate = true)
    public int id;
    public String key;
    public String value;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}
复制代码

3. 封装初始化操做

DatabaseConfig.classjson

@Database(entities = {CacheEntity.class}, version = 1, exportSchema = false)
public abstract class DatabaseConfig extends RoomDatabase {
    public abstract CacheDao mCacheDao();
}
复制代码

DatabaseInitialize.class后端

public class DatabaseInitialize {
    private static DatabaseConfig databaseConfig;

    public DatabaseInitialize(){}

    public static void init(Context context) {
        // 生成数据库实例
        databaseConfig = Room
                .databaseBuilder(context.getApplicationContext(), DatabaseConfig.class, "huiminyougou")
                .allowMainThreadQueries() // 容许主线程中查询
                .build();
    }

    static DatabaseConfig getDatabaseConfig() {
        if (databaseConfig == null) {
            throw new NullPointerException("DatabaseInitialize.init(context) has not call, remember call this function in your Application.class");
        }
        return databaseConfig;
    }
}
复制代码

DatabaseSession.classapi

public final class DatabaseSession {

    private DatabaseSession(){}

    public static DatabaseConfig get() {
        return DatabaseInitialize.getDatabaseConfig();
    }
}	
复制代码

4. dao层

@Dao
public interface CacheDao {
    @Insert
    void insertCaches(CacheEntity... cacheEntities);

    @Update
    void updateCaches(CacheEntity... cacheEntities);

    @Query("SELECT * FROM cache WHERE `key` = :key LIMIT 0,1")
    CacheEntity findByKey(String key);

    @Delete
    void deleteCaches(CacheEntity... cacheEntities);
    
    @Query("SELECT * FROM cache")
    CacheEntity[] findAll();
}
复制代码

5. service(utils)层

public final class CacheService {
    private CacheService() {
    }

    private static CacheDao getRepository() {
        return DatabaseSession.get().mCacheDao();
    }

    /**
     * 设置缓存
     *
     * @param key
     * @param value
     */
    public static void set(String key, String value) {
        CacheEntity cacheEntity;
        cacheEntity = getRepository().findByKey(key);
        if (cacheEntity == null) {
            cacheEntity = new CacheEntity();
            cacheEntity.setKey(key);
            cacheEntity.setValue(value);
            getRepository().insertCaches(cacheEntity);
        } else {
            cacheEntity.setValue(value);
            getRepository().updateCaches(cacheEntity);
        }
    }

    /**
     * 设置缓存
     *
     * @param key
     * @param value
     */
    public static void set(String key, Object value) {
        CacheEntity cacheEntity = getRepository().findByKey(key);
        if (cacheEntity == null) {
            cacheEntity = new CacheEntity();
            cacheEntity.setKey(key);
            String jsonValue = GsonHelper.toJson(value);
            cacheEntity.setValue(jsonValue);
            getRepository().insertCaches(cacheEntity);
        } else {
            String jsonValue = GsonHelper.toJson(value);
            cacheEntity.setValue(jsonValue);
            getRepository().updateCaches(cacheEntity);
        }
    }

    /**
     * 获取缓存
     *
     * @param key
     * @return
     */
    public static String get(String key) {
        CacheEntity cacheEntity = getRepository().findByKey(key);
        if (cacheEntity == null) {
            return null;
        }
        return cacheEntity.getValue();
    }

    /**
     * 获取缓存对象
     *
     * @param key
     * @param classOfT
     * @param <T>
     * @return
     */
    public static <T> T get(String key, Class<T> classOfT) {
        CacheEntity cacheEntity = getRepository().findByKey(key);
        if (cacheEntity == null) {
            return null;
        }
        String jsonValue = cacheEntity.getValue();
        return GsonHelper.toObject(jsonValue, classOfT);
    }

    /**
     * 删除缓存
     *
     * @param key
     */
    public static void delete(String key) {
        CacheEntity cacheEntity = getRepository().findByKey(key);
        if (cacheEntity != null) {
            getRepository().deleteCaches(cacheEntity);
        }
    }

    /**
     * 删除所有缓存
     */
    public static void clearAll() {
        CacheEntity[] cacheEntities = getRepository().findAll();
        if (cacheEntities != null && cacheEntities.length != 0) {
            getRepository().deleteCaches(cacheEntities);
        }
    }
}
复制代码

GsonHelper.class缓存

public class GsonHelper {

    private GsonHelper() {
        // no instance
    }
    private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();

    public static String toJson(Object o) {
        return gson.toJson(o);
    }

    public static <T> T toObject(String json, Class<T> classOfT)  {
        return gson.fromJson(json, classOfT);
    }

    public static <T> List<T> toList(String json, Class<? extends T[]> clazz) {
        T[] array = gson.fromJson(json, clazz);
        return Arrays.asList(array);
    }
}
复制代码

6. 初始化操做

@Override
    public void onCreate() {
        super.onCreate();
        DatabaseInitialize.init(this);
    }
复制代码

7. 使用方式

这里以一个网络请求获取首页数据为例: 使用的是retrofit+rxjava,在请求成功后,将响应实体存入数据库中。网络

mGoodsRequestService.goodsShowIndex(lng, lat)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new BaseHttpObserver<GoodsIndex>() {
                @Override
                public void onSubscribe(Disposable d) {
                    mView.onRequestSubscribe(d);
                }

                @Override
                public void onSuccess(String msg, GoodsIndex data) {
                    CacheService.set(Constant.CacheKey.HOME_INDEX, data);
                    mView.onGoodsIndexRespond(data);
                    mView.onRequestComplete();
                }

                @Override
                public void onFailure(String msg) {

                }

                @Override
                public void onNetworkError(Throwable e) {
                    mView.onRequestError(e);
                }
            });
复制代码

在页面启动伊始,从数据库中拿到缓存数据:框架

GoodsIndex goodsIndex = CacheService.get(Constant.CacheKey.HOME_INDEX, GoodsIndex.class);
    if (goodsIndex != null) {
        mView.onGoodsIndexRespond(goodsIndex);
    }
复制代码

8. 末

这里的service层处理得并非很好,可是Android上没有相似@Autowired这样的注解,网络不少关于Dagger2的文章也是云里雾里,后面思考一下如何用AOP + Dagger2 封装一个相似的@Autowired出来。有哪位大佬能够指点一下^_^

相关文章
相关标签/搜索