DAO如何与领域一起使用?因为在活动中尝试设置模型类的成员时会遇到异常:
java.lang.IllegalStateException:只能在事务内部完成更改领域数据。
我知道使用realm.executeTransaction
可以解决此问题,但是我的活动中的代码不再与数据库无关,因为它将使用特定于低级数据库通信的代码。因此,如果以后我想更改数据库,则重构将花费大量时间和工作...此外,我将不得不在所有活动中处理对Realm.getDefaultInstance();
这是我的活动代码示例
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界面:
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();
}
});
}
}
答案 0 :(得分:1)
Realm的getInstance()
方法返回一个thread-local, reference counted instance which must be paired with a close() call
,因此您的DAO实现可能不符合您的期望。
如果使用我专门创建的库Realm-Monarchy来简化“抽象领域”的创建,则可以像这样实现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();
});
}
}
PS:如果同步返回List<T>
,而不是像LiveData<List<T>>
(或最初的RealmResults<T>
)这样的可观察物,则会浪费很多功能/功能。