如何通过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
相关产品推荐
相关产品推荐

