Android Realm数据库的查询及自动更新

本文介绍了Android中Realm数据库的查询方法及自动更新机制。包括如何使用条件查询获取数据,如年龄范围、姓名匹配等;同时讲解了如何设置监听器以实现实时数据更新,以及在不同线程环境下数据更新的具体操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇文章Android Realm数据库的使用写了Relam数据库的基本配置和基本用法,这次主要看看Realm数据库的查询以及自动更新。
1.查询
查询分为同步和异步,同步和异步的使用请看上一篇文章,这次主要是学习查询条件的使用:
//查找年龄在10~50岁的Student,并且结果按降序排列
 RealmResults<Student> list = mRealm.where(Student.class)
        .between("age", 10, 50)
        .findAllSorted("age", Sort.DESCENDING);

 //查找年龄大于等于70或者名字叫"斯巴达1"的所有Student,结果按升序排列
 RealmResults<Student> list = mRealm.where(Student.class)
        .beginGroup()
        .greaterThanOrEqualTo("age", 70)
        .or()
        .equalTo("name", "斯巴达1")
        .endGroup()
        .findAllSorted("age", Sort.ASCENDING);

//查找班级是1并且年龄是20的Student
RealmResults<Student> list = mRealm.where(Student.class)
        .equalTo("clazz", 1)
        .findAll()
        .where()
        .equalTo("age", 20)
        .findAll();
基本语法和GreenDao差不多,用过类似ORM的应该都很容易上手。
2.自动更新
如果Realm的实例存在于带有Looper,也就是UI线程,那么这个Realm就拥有自动更新的功能。也就是说如果Realm数据库发生了变化,那么数据库就会在下一个事件循环中自动更新,这样也就实现了数据与UI的同步。
如果你在子线程中添加数据到Realm数据库,你可以添加一个onChangeListener来监听数据的变化,这样在数据发生变化的时候就会执行相应的操作。
public class MyActivity extends Activity {
    private Realm realm;
    private RealmChangeListener realmListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      realm = Realm.getDefaultInstance();
      realmListener = new RealmChangeListener() {
        @Override
        public void onChange(Realm realm) {
            // ... do something with the updates (UI, etc.) ...
        }};
      realm.addChangeListener(realmListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Remove the listener.
        realm.removeChangeListener(realmListener);
        //or use realm.removeAllChangeListeners() if needed.
        // Close the Realm instance.
        realm.close();
    }
}
这些变化的监听也可以添加在RealmObject或者RealmResults的实例中,你可以通过这样的方式来监视对象和查询结果的改变。另外,当监听回调函数被调用时,相应的数据已经被更新,不需要去做刷新操作。
public class MyActivity extends Activity {
    private Realm realm;
    private RealmChangeListener puppiesListener;
    private RealmChangeListener dogListener;

    private RealmResults<Dog> puppies;
    private Dog dog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      realm = Realm.getDefaultInstance();
      puppiesListener = new RealmChangeListener() {
        @Override
        public void onChange(RealmResults<Dog> puppies) {
            // ... do something with the updated puppies instance
        }};

      // Find all the puppies
      puppies = realm.where(Dog.class).lessThanOrEqualTo("age", 2).findAll();
      puppies.addChangeListener(puppiesListener);

      dogListener = new RealmChangeListener() {
        @Override
        public void onChange(Dog dog) {
            // ... do something with the updated Dog instance
        }};

      dog = realm.where(Dog.class).equalTo("name", "Fido").findFirst();
      dog.addChangeListener(dogListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Remove the listeners
        puppies.removeChangeListener(puppiesListener);
        dog.removeChangeListener(dogListener);
        // Close the Realm instance.
        realm.close();
    }
}
如果Realm实例存在与非UI线程,那么数据不会发生自动刷新,知道手动调用waitForChange()方法。如果您想确定当前 Realm 实例是否有自动更新功能,可以通过调用 isAutoRefresh() 方法查询。官方是这样说的:
Change listeners only work on Looper threads. For non-looper threads, you manually have to use Realm.waitForChange() instead.
也就是说对Realm数据变化的监听只会在主线程执行,要想在非UI线程使用,需要使用waitForChange()代替。
另外,官方还重写了ListView和RecyclerView的Adapter,可以实现数据的实时刷新。用法大同小异,需要在module一级的build.gradle中添加依赖:
compile 'io.realm:android-adapters:1.4.0'
具体用法以RecyclerView为例:
public class DetailActivity extends AppCompatActivity {

  public static final String STUDENT = "STUDENT";
  private Realm mRealm;

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detail);
    getSupportActionBar().setTitle("RealmAdapter");
    mRealm = Realm.getDefaultInstance();

    RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.mRecyclerView);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    //Realm的查询方法

    //查找年龄在10~50岁的Student,并且结果按降序排列
    RealmResults<Student> list = mRealm.where(Student.class)
        .between("age", 10, 50)
        .findAllSorted("age", Sort.DESCENDING);
    mRecyclerView.setAdapter(new MyAdapter(this, list, true));//这里就设置了自动更新
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.insert) {
      mRealm.beginTransaction();
      List<Student> list = new ArrayList<>();
      for (int i = 0; i < 100; i++) {
        Student s = new Student(UUID.randomUUID().toString(), "斯巴达" + i, i, (i % 2) + 1);
        list.add(s);
      }
      mRealm.copyToRealm(list);
      mRealm.commitTransaction();
    }
    return super.onOptionsItemSelected(item);
  }

  class MyAdapter extends RealmRecyclerViewAdapter<Student, MyAdapter.ViewHolder> {

    public MyAdapter(@NonNull Context context, @Nullable OrderedRealmCollection<Student> data, boolean autoUpdate) {
      super(context, data, autoUpdate);
    }

    class ViewHolder extends RecyclerView.ViewHolder {
      private TextView name;
      private TextView clazz;

      public ViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.name);
        clazz = (TextView) itemView.findViewById(R.id.clazz);
      }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
      return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
      Student student = getData().get(position);
      holder.name.setText(student.getName());
      holder.clazz.setText(String.format(Locale.CHINA, "%d班", student.getClazz()));
    }
  }


  @Override
  protected void onDestroy() {
    super.onDestroy();
    if (mRealm != null && !mRealm.isClosed()) {
      mRealm.close();
      mRealm = null;
    }
  }
}

想了解更详细的内容可以看官方介绍

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值