gpt4 book ai didi

java - 具有 Realm 的 DAO 模式

转载 作者:行者123 更新时间:2023-11-29 23:49:47 24 4
gpt4 key购买 nike

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com