当前位置: 首页 > 知识库问答 >
问题:

如何使用MVVM架构在Room Android中获取数据

傅博瀚
2023-03-14

所以我遵循MVVM架构,在那里我有一个银行交易数据库:

@Database(entities = {Transaction.class}, version = 1, exportSchema = false) @TypeConverters({DateConverter.class}) 
public abstract class TransactionsRoomDatabase extends RoomDatabase {

        public abstract TransactionDao transactionDao();  
        private static volatile TransactionsRoomDatabase INSTANCE;

        private static final int NUMBER_OF_THREADS = 4;
        private static final ExecutorService databaseWriteExecutor =
                Executors.newFixedThreadPool(NUMBER_OF_THREADS);
    
        public static ExecutorService getDatabaseWriteExecutor() {
            return databaseWriteExecutor;
        }
    
        public static TransactionsRoomDatabase getDatabase(final Context context) {
            if (INSTANCE == null) {
                synchronized (TransactionsRoomDatabase.class) {
                    if (INSTANCE == null) {
                        INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                                TransactionsRoomDatabase .class, "database")
                                .build();
                    }
                }
            }
            return INSTANCE;
        } }

我的Dao类有两个查询:

@Dao
public interface TransactionDao {
   // first query
    @Query("SELECT * " +
            "FROM transactions_table " +
            "ORDER BY bookingDate, valueDate DESC")
    LiveData<List<Transaction>> getAllTransactions();
  
  // second query that I don't know how to call it in my fragment
    @Query("SELECT * " +
            "FROM transactions_table " +
            "WHERE debtorAccount = :debtorAccount " +
            "ORDER BY valueDate DESC "
    )
    LiveData<List<Transaction>> getTransactionsFiltered(String debtorAccount);

   // insert the list of transactions in databse
   @Insert(onConflict = OnConflictStrategy.REPLACE)
   void insertTransactions(List<Transaction> transactionList);
}

仓库:

public class TransactionRepository {
    private TransactionDao transactionDao;
    private LiveData<List<Transaction>> transactionList;

    public TransactionRepository(Application application) {
        TransactionsRoomDatabase roomDatabase = TransactionsRoomDatabase.getDatabase(application);
        transactionDao = transactionsRoomDatabase.transactionDao();
        transactionList = transactionDao.getAllTransactions();
    }
  
   // get all transactons
   public LiveData<List<Transaction>> getAllTransactions() {
    return transactionList;
   }

   // insert transactions in database using DAO. Are done in another thread so the main thread is not blocked
    public void insertTransactions(List<Transaction> transactionList) {
        TransactionsRoomDatabase.getDatabaseWriteExecutor().execute(() ->       transactionDao.insertTransactions(transactionList));
    }
}

视图模型:

public class HomeAdvancedViewModel extends AndroidViewModel {
    private TransactionRepository transactionRepository;
    private LiveData<List<Transaction>> allTransactions;

    public HomeAdvancedViewModel(Application application) {
        super(application);
        transactionRepository = new TransactionRepository(application);
        allTransactions = transactionRepository.getAllTransactions();
    }

    public LiveData<List<Transaction>> getAllTransactions() {
        return allTransactions;
    }
}

在主片段中,我正在用数据库中的所有事务填充回收视图:

public class MainFragment extends Fragment {
    private HomeAdvancedViewModel homeAdvancedViewModel;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        homeAdvancedViewModel = new ViewModelProvider(this).get(HomeAdvancedViewModel.class); // define viewModel
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        /* Here I'm using the observable pattern. When transactions in database are changed, I call my setCurrentTransactions(...) function that populates again the recycler view */
        homeAdvancedViewModel.getAllTransactions().observe(getViewLifecycleOwner(), transactions -> setCurrentTransactions(transactionListAdapter, recyclerViewTransactions, transactions));
    }
}

我的问题是:如何从DAO调用函数

getTransactionsFiltered(String debtorAccount) 

要填充相同的recyclerView(当按下某个按钮时)?我不能吃这样的东西

        public void getTransactionsFiltered(String account) {
            TransactionsRoomDatabase.getDatabaseWriteExecutor().execute(() ->       transactionDao.getTransactionsFiltered(account)); // calling the 2nd query in DAO
        }

在我的DAO中,因为查询应该在另一个线程上执行(我不允许在主线程上执行),所以我的DAO不能返回事务列表<你能提供帮助吗?

共有1个答案

尤茂材
2023-03-14

回答
我是这样解决的:

在Repository类中添加了以下功能:

public class TransactionRepository {
    private TransactionDao transactionDao;
    private LiveData<List<Transaction>> transactionList;

    public TransactionRepository(Application application) {
        TransactionsRoomDatabase roomDatabase = TransactionsRoomDatabase.getDatabase(application);
        transactionDao = transactionsRoomDatabase.transactionDao();
        transactionList = transactionDao.getAllTransactions();
    }
  
   // get all transactons
   public LiveData<List<Transaction>> getAllTransactions() {
    return transactionList;
   }

   // NEW FUNCTION ADDED
   public LiveData<List<Transaction>> getTransactionsFiltered(String account) {
     return accountsRoomDatabase.transactionDao().getTransactionsFiltered(account);
   }
}

这样,主线程就不会被阻塞。我不确定这是否是最好的方法,但它解决了我的问题

 类似资料:
  • 问题内容: 我想在Django中使用postgreSQL模式,该怎么做? 问题答案: 我一直在使用: 过去没有意识到仅适用于只读操作。当你尝试添加新记录时,它将失败,因为该序列类似于“ schema.tablename” _column_id_seq。 到目前为止还可以。谢谢。

  • 我在下面有一个存储库代码,在这里我还希望有一个函数,通过查询数据库(这里我使用了Room)返回购物车项目,这样它就会返回:Select*from cart where cartId={{id} 如何在AsyncTask上编写函数并从中返回值? 存储库类: 我的刀课:

  • 我在将表模型(在模型中)与我的JTable(在视图中)分开时遇到问题,我的模型包含使用方法从数据库获取数据所需的查询: 型号.java View.java 这就是我遇到问题的部分: Controller.java 显然,< code>JTable不能改变它第一次获得的< code>DefaultTbaleModel对象,所以当我执行时,我总是得到一个空的JTable,所以简而言之,我不能在我的<

  • 我一直在derby/netbeans中创建数据库。我想输出数据库的结构,而不仅仅是输出整个数据库。我该怎么做? 我已经尝试了"EXEC'table name';",它返回"错误代码-1,SQL状态42X01:语法错误:在第1行第1列遇到"exec"。"和"SELECT*fromINFORMATION_SCHEMA.COLUMNSWHeretable_name='table name';",它返回"

  • Model-View-ViewModel (MVVM)是用于开发软件应用程序的架构设计模式。 MVVM由Microsoft Architect John Gossman于2005年开发。该模式源自模型 - 视图 - 控制器(MVC)模式。 MVVM的优势在于它将应用程序层的图形用户界面与业务逻辑分开。 MVVM负责处理来自底层模型的数据,以便非常容易地表示和管理它。 MVVM中的ViewModel

  • 问题内容: 我正在尝试创建一个简单的方法,该方法将ResultSet作为参数接收并返回一个包含ResultSet的行数的int。这是执行此操作的有效方法吗? 我尝试了这个: 但我说错了 在此先感谢您的指点! 问题答案: 如果您有权访问导致该结果集的准备好的语句,则可以使用 这样可以以回退光标的方式准备语句。这也记录在ResultSet Javadoc中 但是,通常,对于大型结果集,前进和后退游标可