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

本文介绍如何将 Android Room 数据库封装成类似 Redis 的缓存效果。通过定义实体类、DAO 层及服务层等步骤,实现了 K/V 存储模式,增强了应用的数据管理能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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.class

@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.class

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出来。有哪位大佬可以指点一下^_^

### 集和配置 Redis 的方法 在 Android Studio 中集和配置 Redis 并不是直接通过 Android Studio 完的,而是需要借助外部服务或者本地环境中的 Redis 实例。以下是具体实现方式: #### 1. **安装 Redis** 在开发环境中安装 Redis 是第一步。可以通过以下命令在 Linux 或 macOS 上快速完安装: ```bash sudo apt update && sudo apt install redis-server -y # 对于 Ubuntu/Debian 系统 brew install redis # 对于 macOS 系统 ``` 如果是在 Windows 环境下,则推荐下载官方提供的可执行文件并手动运行[^1]。 #### 2. **启动 Redis 服务器** 安装完后,确保 Redis 正常启动。可以使用如下命令验证其状态: ```bash redis-cli ping PONG # 表明 Redis 已经正常工作 ``` #### 3. **引入 Jedis 库到项目中** Jedis 是 Java 社区广泛使用的 Redis 客户端库之一,在 Android 项目中也可以轻松集它。打开 `build.gradle` 文件,并添加依赖项: ```gradle implementation 'redis.clients:jedis:4.0.0' ``` 执行同步操作以加载该库至工程中。 #### 4. **编写代码连接 Redis** 下面是一个简单的例子展示如何利用 Jedis 连接到 Redis 数据库以及存储数据: ```java import redis.clients.jedis.Jedis; public class MainActivity { private static final String REDIS_HOST = "localhost"; private static final int REDIS_PORT = 6379; public void connectToRedis() { try (Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT)) { // 创建新的 Jedis 实例 System.out.println("Connection to server sucessfully"); // 设置键值对 jedis.set("key", "value"); System.out.println("Key set successfully"); // 获取指定键对应的值 String value = jedis.get("key"); System.out.println("Value retrieved from key is: " + value); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 5. **处理异常情况** 当应用程序无法连接到 Redis 时,通常是因为 Redis 没有正确启动或者是防火墙阻止了通信等问题。此时应该检查网络连通性和 Redis 是否正在监听正确的地址与端口[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值