DAO 如何与 realm 一起使用?因为在我的 Activity 中,我尝试设置模型类的成员时出现异常:
java.lang.IllegalStateException: Changing Realm data can only be done from inside a transaction.
我知道使用 realm.executeTransaction
可以解决这个问题,但我 Activity 中的代码不再与数据库无关,因为它将计算特定于低级数据库通信的代码。所以以后如果我想更改数据库,重构将花费大量时间和工作......此外,我将不得不在我的所有 Activity 中处理对 Realm.getDefaultInstance();
这是我的 Activity 代码示例
protected void onCreate(Bundle savedInstanceState)
{
mBook = mBookDaoImpl.getBookById(bookId);
}
// Later in the code
private void saveBook(String name)
{
mBook.setName(name);
}
这是我的模型类
public class Book extends RealmObject
{
@Required
@PrimaryKey
private String id;
private String name;
public Book() {
}
public Book(String id, String name) {
this.id = id;
this.name = name;
}
// getter setter methods
}
这是我的 DAO 接口(interface):
public interface BookDao
{
List<Book> getAllBooks();
Book getBookByIsbn(int isbn);
void saveBook(Book book);
void deleteBook(Book book);
}
最后是我的实现:
public class BookDaoImpl implements BookDao
{
private static BookDaoImpl INSTANCE = null;
private Realm mRealm;
private BookDaoImpl()
{
mRealm = Realm.getDefaultInstance();
}
public static BookDaoImpl getInstance()
{
if (INSTANCE == null)
INSTANCE = new BookDaoImpl();
return INSTANCE;
}
@Override
public List<Book> getAllBooks()
{
return mRealm.where(Book.class).findAll();
}
@Override
public Book getBookById(String id)
{
return mRealm.where(Book.class).equalTo("id", id).findFirst();
}
@Override
public void saveBook(final Book book)
{
mRealm.executeTransaction(new Realm.Transaction()
{
@Override
public void execute(Realm realm)
{
if (book.getId() == null)
book.setId(UUID.randomUUID().toString());
realm.copyToRealmOrUpdate(book);
}
});
}
@Override
public void deleteBook(final Book book)
{
mRealm.executeTransaction(new Realm.Transaction()
{
@Override
public void execute(Realm realm)
{
mRealm.where(Counter.class).equalTo("id", book.getId())
.findFirst()
.deleteFromRealm();
}
});
}
}
最佳答案
Realm 的 getInstance()
方法返回 thread-local, reference counted instance which must be paired with a close() call
,因此您的 DAO 实现可能不符合您的预期。
如果你使用我的图书馆Realm-Monarchy这是我专门为更容易“抽象 Realm ”而创建的,然后你可以像这样实现你的 DAO:
public class BookDaoImpl implements BookDao
{
private static BookDaoImpl INSTANCE = null;
private Monarchy monarchy;
private BookDaoImpl(Monarchy monarchy)
{
this.monarchy = monarchy;
}
public static BookDaoImpl getInstance(Monarchy monarchy)
{
if (INSTANCE == null) {
synchronized(BookDaoImpl.class) {
if(INSTANCE == null) {
INSTANCE = new BookDaoImpl(monarchy);
}
}
}
return INSTANCE;
}
@Override
public List<Book> getAllBooks()
{
return monarchy.fetchAllCopiedSync((realm) -> realm.where(Book.class));
}
@Override
public Book getBookById(final String id)
{
List<Book> books = monarchy.fetchAllCopiedSync((realm) -> realm.where(Book.class).equalTo("id", id));
if(books.isEmpty()) {
return null;
} else {
return books.get(0);
}
}
@Override
public void saveBook(final Book book)
{
monarchy.runTransactionSync((realm) -> {
if (book.getId() == null)
book.setId(UUID.randomUUID().toString());
realm.insertOrUpdate(book);
});
}
@Override
public void deleteBook(final Book book)
{
monarchy.runTransactionSync((realm) -> {
realm.where(Counter.class).equalTo("id", book.getId())
.findFirst()
.deleteFromRealm();
});
}
}
P.S.:如果返回 List<T>
,您将放弃很多功能/功能同步,而不是像 LiveData<List<T>>
这样的可观察对象(或最初是 RealmResults<T>
)。
关于java - 具有 Realm 的 DAO 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51005438/