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

安卓开发 数据库

安卓开发中的数据库使用指南


安卓常用数据库类型

安卓开发中常见的数据库方案包括:

数据库类型 特点 适用场景
SQLite 轻量级嵌入式数据库,支持SQL语法,Android内置支持 本地数据存储(如用户配置)
Room 基于SQLite的抽象层,提供编译时校验和流畅API 复杂本地数据管理
Realm 高性能对象数据库,支持实时更新和跨平台同步 高频读写操作(如日志)
Firebase Realtime Database 云数据库,数据实时同步,无需自建服务器 实时协作类应用
Room + RxJava/LiveData Room结合响应式编程,自动感知数据变化 MVVM架构下的数据层

SQLite基础操作

  1. 创建数据库

    // 获取可写数据库
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("app.db", null);
    // 创建表
    db.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
  2. 增删改查示例
    | 操作 | SQL语句 | Android代码片段 |
    |————|—————————————–|——————————————|
    | 插入 | INSERT INTO users (name) VALUES ('Alice') | db.execSQL("INSERT INTO users (name) VALUES (?)", new Object[]{"Alice"}); |
    | 查询 | SELECT FROM users | Cursor cursor = db.rawQuery("SELECT FROM users", null); |
    | 更新 | UPDATE users SET name='Bob' WHERE id=1 | db.execSQL("UPDATE users SET name=? WHERE id=?", new Object[]{"Bob", 1}); |
    | 删除 | DELETE FROM users WHERE id=1 | db.execSQL("DELETE FROM users WHERE id=?", new Object[]{1}); |


Room组件进阶

  1. 定义实体类

    @Entity(tableName = "users")
    public class User {
        @PrimaryKey(autoGenerate = true)
        public int id;
        @ColumnInfo(name = "name")
        public String name;
    }
  2. 创建DAO接口

    @Dao
    public interface UserDao {
        @Insert
        void insert(User user);
        @Query("SELECT  FROM users WHERE id=:userId")
        User getUserById(int userId);
        @Update
        void update(User user);
        @Delete
        void delete(User user);
    }
  3. 构建数据库

    @Database(entities = {User.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {
        public abstract UserDao userDao();
    }

关键问题与解决方案

  1. 主线程操作数据库导致卡顿

    • 原因:直接在UI线程执行数据库读写操作。
    • 解决:使用AsyncTaskExecutorServiceLiveData(Room)异步处理。
      // Room + LiveData示例
      LiveData<List<User>> users = appDatabase.userDao().getAllUsers();
      users.observe(lifecycleOwner, list -> {
          // 更新UI
      });
  2. 数据库版本升级数据迁移

    • 实现:重写RoomDatabase.MigrationSQLiteOpenHelper.onUpgrade
      static final Migration MIGRATION_1_2 = new Migration(1, 2) {
          @Override
          public void migrate(SupportSQLiteDatabase database) {
              database.execSQL("ALTER TABLE users ADD COLUMN age INTEGER");
          }
      };

最佳实践

  • 使用加密数据库:通过SQLiteOpenHelperencrypt()方法保护敏感数据。
  • 避免内存泄漏:确保SQLiteOpenHelper单例模式,避免多次创建实例。
  • 选择合适框架:简单需求用SQLite,复杂业务优先Room,高频读写考虑Realm。

相关问题与解答

问题1:Room的@Query参数如何处理null值?

  • 解答:Room的@Query不支持直接传递null参数,需使用:parameter占位符并传入null
    @Query("SELECT  FROM users WHERE age > :minAge")
    List<User> getUsers(int minAge); // minAge=null会触发异常

    正确做法:在DAO中处理null逻辑,或使用@Nullable注解配合条件判断。


问题2:SQLite多线程并发写入会导致什么问题?

  • 解答:SQLite默认支持多线程读取,但写入需加锁,未正确处理可能引发:
    • 数据竞争(脏读、不可重复读)
    • 数据库锁定导致ANR(Application Not Responding)
      解决方案:使用ContentProvider集中管理访问,或通过synchronized块控制
0