You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ViewModel调用原生SQLite方法实现MVVM架构数据操作

现有代码报错原因

  • 类型不匹配:DbHelper.getAllData() 返回的是 ArrayList<HashMap<String, String>> 类型,你直接把它赋值给 MutableLiveData<ArrayList<HashMap<String, String>>> allNotesLivedata,类型不一致会直接触发编译报错
  • 数据变更无自动通知:原生SQLite没有内置观察者机制,你执行插入/更新/删除操作后,allNotesLivedata 不会自动刷新数据,UI拿到的永远是ViewModel初始化时的旧数据
  • 主线程操作风险:当前所有数据库操作都在主线程执行,数据量稍大就会触发ANR(应用无响应)

修正后的ViewModel实现

public class Viewmodell extends AndroidViewModel {
    private DbHelper repository;
    MutableLiveData<ArrayList<HashMap<String, String>>> allNotesLivedata = new MutableLiveData<>();

    public Viewmodell(@NonNull Application application) {
        super(application);
        repository = new DbHelper(application);
        // 初始化异步加载全量数据
        loadAllData();
    }

    // 异步查询数据并更新LiveData
    private void loadAllData() {
        Executors.newSingleThreadExecutor().execute(() -> {
            ArrayList<HashMap<String, String>> data = repository.getAllData();
            // 子线程用postValue更新LiveData
            allNotesLivedata.postValue(data);
        });
    }

    void insert(String name, String address) {
        Executors.newSingleThreadExecutor().execute(() -> {
            repository.insert(name, address);
            // 操作完成后刷新数据
            loadAllData();
        });
    }

    void update(int id, String name, String address) {
        Executors.newSingleThreadExecutor().execute(() -> {
            repository.update(id, name, address);
            loadAllData();
        });
    }

    void delete(int id) {
        Executors.newSingleThreadExecutor().execute(() -> {
            repository.delete(id);
            loadAllData();
        });
    }

    public LiveData<ArrayList<HashMap<String, String>>> getAllNotes() {
        return allNotesLivedata;
    }
}

额外优化建议

你当前DbHelper的增删改方法用字符串拼接SQL,存在SQL注入风险,建议改用官方提供的操作API,示例如下:

// 优化后的插入方法
public void insert(String name, String address) {
    SQLiteDatabase database = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(COLUMN_NAME, name);
    values.put(COLUMN_ADDRESS, address);
    // 官方API自动处理特殊字符转义,避免注入风险
    database.insert(TABLE_SQLite, null, values);
    database.close();
}

如果你的数据量较大,不需要每次操作都全量查询,可以直接修改LiveData内的集合数据后调用postValue更新,性能更高。

内容的提问来源于stack exchange,提问作者IRON MAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 11:33:01