当前位置:首页 > 行业动态 > 正文

安卓开发怎么查询数据

本地数据库查询(SQLite/Room)

SQLite 原生查询

  • 适用场景:直接操作数据库,适合简单需求或第三方库不支持的情况。
  • 示例代码
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT  FROM user WHERE age > ?", new String[]{"20"});
    if (cursor.moveToFirst()) {
        do {
            String name = cursor.getString(cursor.getColumnIndex("name"));
            // 处理数据
        } while (cursor.moveToNext());
    }
    cursor.close();
  • 缺点:需手动管理线程、SQL 注入风险、无编译时校验。

Room 持久化库

  • 优势:编译时校验 SQL、支持 LiveData 自动更新、简化线程处理。
  • 查询方式
    • 普通查询
      @Dao
      public interface UserDao {
          @Query("SELECT  FROM user WHERE age > :age")
          List<User> getUsersByAge(int age);
      }
    • 流式查询(支持实时更新):
      @Query("SELECT  FROM user WHERE age > :age")
      LiveData<List<User>> getUsersByAgeLiveData(int age);
  • 表格对比
    | 特性 | SQLite 原生 | Room |
    |———————|————————|————————–|
    | 编译时校验 | | |
    | 线程管理 | 需手动处理 | 自动处理(异步查询) |
    | 数据变更监听 | 需手动实现 | 支持 LiveData/Flow |
    | 防止 SQL 注入 | 需手动处理 | 编译时校验参数 |

网络数据查询(Retrofit/OkHttp)

Retrofit + Callback

  • 适用场景:RESTful API 请求,支持多种数据格式(JSON/XML)。

  • 示例代码

    public interface ApiService {
        @GET("users")
        Call<List<User>> getUsers(@Query("age") int age);
    }
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.example.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    ApiService apiService = retrofit.create(ApiService.class);
    apiService.getUsers(20).enqueue(new Callback<>() {
        @Override public void onResponse(Call<List<User>> call, Response<List<User>> response) {
            // 处理成功结果
        }
        @Override public void onFailure(Call<List<User>> call, Throwable t) {
            // 处理失败
        }
    });
  • 缺点:回调嵌套导致代码复杂(可结合 RxJava 或协程优化)。

Retrofit + 协程(Kotlin)

  • 优势:避免回调地狱,代码更简洁。

  • 示例代码

    interface ApiService {
        @GET("users")
        suspend fun getUsers(@Query("age") age: Int): List<User>
    }
    val retrofit = Retrofit.Builder()
        .baseUrl("https://api.example.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build()
    val apiService = retrofit.create(ApiService::class.java)
    GlobalScope.launch {
        try {
            val users = apiService.getUsers(20)
            // 更新 UI
        } catch (e: Exception) {
            // 处理异常
        }
    }
  • 表格对比
    | 特性 | Callback 模式 | 协程模式 |
    |———————|—————————-|————————–|
    | 代码简洁度 | 低(嵌套回调) | 高(顺序执行) |
    | 异常处理 | 需手动 try/catch | 可直接抛出/捕获 |
    | 线程管理 | 需手动切换 | 自动继承协程上下文 |


其他数据查询方式

ContentProvider(系统级数据)

  • 适用场景:读取系统数据(如联系人、文件)或跨应用共享数据。
  • 示例代码
    Uri uri = ContactsContract.Contacts.CONTENT_URI;
    Cursor cursor = context.getContentResolver().query(
        uri,
        null, // 所有列
        "age > ?",
        new String[]{"20"},
        null
    );
    // 解析 cursor...
  • 限制:需处理权限(如 READ_CONTACTS),API 复杂度较高。

Realm 数据库

  • 特点:支持离线、实时更新,适合高频读写场景。
  • 查询示例
    RealmResults<User> results = realm.where(User.class)
        .greaterThan("age", 20)
        .findAll();
  • 注意:需学习特定语法,社区支持不如 Room。

常见问题与解答

问题1:如何优化数据库查询性能?

  • 解答
    1. 索引优化:为频繁查询的字段(如 age)添加索引。
    2. 分页查询:使用 LIMITOFFSET(SQLite)或 PagingSource(Room)。
    3. 缓存机制:结合 LiveData 或内存缓存减少重复查询。
    4. 异步处理:避免在主线程执行耗时操作。

问题2:网络请求如何实现分页加载?

  • 解答
    • Retrofit + 协程
      interface ApiService {
          @GET("users")
          suspend fun getUsers(@Query("page") page: Int, @Query("limit") limit: Int): List<User>
      }
      // 调用时动态传递 page 参数
    • Paging3 库
      val pager = Pager(config = PagingConfig(pageSize = 20)) {
          apiService.getUsers(it, 20) // it 为当前页码
      }
      // 通过 flow 获取分页数据

  • 本地查询:优先使用 Room(安全性、便捷性),复杂场景考虑 Realm。
  • 网络查询:推荐 Retrofit + 协程(代码简洁),或结合 RxJava(功能丰富)。
  • 系统数据:通过 ContentProvider 读取,注意权限管理