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

安卓开发如何查询数据库

安卓开发中查询数据库的实现方式

使用 SQLite 直接查询

SQLite 是安卓内置的轻量级数据库,适合简单场景。

步骤:

  1. 创建数据库帮助类
    通过 SQLiteOpenHelper 管理数据库创建与版本更新。
  2. 获取可读实例
    调用 getReadableDatabase() 获取可读数据库对象。
  3. 执行查询
    使用 rawQuery()query() 方法执行 SQL 语句。

代码示例:

// 数据库帮助类
public class MyDatabaseHelper extends SQLiteOpenHelper {
    public MyDatabaseHelper(Context context) {
        super(context, "my_database.db", null, 1);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT)");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS user");
        onCreate(db);
    }
}
// 查询数据
MyDatabaseHelper dbHelper = new MyDatabaseHelper(context);
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT  FROM user WHERE id = ?", new String[]{"1"});
while (cursor.moveToNext()) {
    String name = cursor.getString(cursor.getColumnIndex("name"));
    // 处理数据
}
cursor.close();
db.close();

优点:

  • 直接操作,灵活性高。
    缺点:
  • 需手动处理线程安全、SQL 注入风险、数据转换。

使用 Room 持久化库(推荐)

Room 是安卓官方推荐的数据库层封装,基于 SQLite,提供抽象层和编译时校验。

步骤:

  1. 定义实体类
    使用 @Entity 标注对应数据库表。
  2. 创建 DAO 接口
    定义 @Query 方法或增删改查方法。
  3. 构建数据库类
    继承 RoomDatabase 并绑定实体。
  4. 调用查询方法
    通过 DAO 实例执行查询。

代码示例:

// 实体类
@Entity(tableName = "user")
public class User {
    @PrimaryKey(autoGenerate = true)
    public int id;
    @ColumnInfo(name = "name")
    public String name;
}
// DAO 接口
@Dao
public interface UserDao {
    @Query("SELECT  FROM user WHERE id = :userId")
    User getUserById(int userId);
}
// 数据库类
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}
// 查询数据(需在子线程或异步执行)
AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "app_db").build();
User user = db.userDao().getUserById(1);

优点:

  • 编译时 SQL 校验,避免运行时错误。
  • 支持 LiveData 实时监听、类型安全。
    缺点:
  • 学习成本稍高,需理解注解和架构。

通过 ContentProvider 查询(跨应用)

ContentProvider 用于公开数据给其他应用,适合数据共享场景。

步骤:

  1. 创建 ContentProvider
    实现 query() 方法处理查询请求。
  2. 调用 ContentResolver 查询
    使用 query() 方法发送查询请求。

代码示例:

// ContentProvider 中处理查询
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    return db.query("user", projection, selection, selectionArgs, null, null, sortOrder);
}
// 客户端查询
Uri uri = Uri.parse("content://com.example.app.provider/user");
Cursor cursor = getContentResolver().query(uri, null, "id=?", new String[]{"1"}, null);
if (cursor != null) {
    while (cursor.moveToNext()) {
        String name = cursor.getString(cursor.getColumnIndex("name"));
        // 处理数据
    }
    cursor.close();
}

优点:

  • 支持跨应用数据共享。
    缺点:
  • 实现复杂,需处理权限和数据暴露。

查询网络数据库(如 Firebase)

若数据存储在远程数据库(如 Firebase Realtime Database),需通过 API 查询。

步骤:

  1. 添加依赖
    引入 Firebase SDK。
  2. 初始化数据库
    获取 FirebaseDatabase 实例。
  3. 监听数据
    使用 addValueEventListeneraddListenerForSingleValueEvent

代码示例:

// Firebase 查询
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("users").child("1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String name = dataSnapshot.child("name").getValue(String.class);
        // 处理数据
    }
    @Override
    public void onCancelled(DatabaseError error) {}
});

注意事项

问题 解决方案
主线程操作数据库 使用 AsyncTaskExecutorServiceLiveData(Room)在子线程执行查询。
SQL 注入风险 使用参数化查询()或 Room 的 @Query 参数绑定。
数据库版本升级 实现 Migration 接口或覆盖 onUpgrade() 方法处理数据迁移。
权限问题 安卓 10+ 需申请 READ_EXTERNAL_STORAGE(若存储在外部存储)。

相关问题与解答

问题1:如何实现 Room 数据库的版本迁移?

解答:
Room.databaseBuilder() 中添加 .addMigrations(MIGRATION_1_2),并定义 Migration 对象:

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE user ADD COLUMN age INTEGER");
    }
};

问题2:如何在 Room 中执行多表关联查询?

解答:

  1. 在 DAO 中使用 @Transaction 注解保证事务一致性。
  2. 定义嵌套对象或自定义返回类型:
    @Transaction
    @Query("SELECT  FROM user JOIN address ON user.id = address.userId WHERE user.id = :userId")
    List<UserWithAddress> getUserWithAddress(int userId);
0