上一篇
安卓开发 数据库
- 行业动态
- 2025-04-21
- 2
安卓开发中的数据库使用指南
安卓常用数据库类型
安卓开发中常见的数据库方案包括:
数据库类型 | 特点 | 适用场景 |
---|---|---|
SQLite | 轻量级嵌入式数据库,支持SQL语法,Android内置支持 | 本地数据存储(如用户配置) |
Room | 基于SQLite的抽象层,提供编译时校验和流畅API | 复杂本地数据管理 |
Realm | 高性能对象数据库,支持实时更新和跨平台同步 | 高频读写操作(如日志) |
Firebase Realtime Database | 云数据库,数据实时同步,无需自建服务器 | 实时协作类应用 |
Room + RxJava/LiveData | Room结合响应式编程,自动感知数据变化 | MVVM架构下的数据层 |
SQLite基础操作
创建数据库
// 获取可写数据库 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("app.db", null); // 创建表 db.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
增删改查示例
| 操作 | 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组件进阶
定义实体类
@Entity(tableName = "users") public class User { @PrimaryKey(autoGenerate = true) public int id; @ColumnInfo(name = "name") public String name; }
创建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); }
构建数据库
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
关键问题与解决方案
主线程操作数据库导致卡顿
- 原因:直接在UI线程执行数据库读写操作。
- 解决:使用
AsyncTask
、ExecutorService
或LiveData
(Room)异步处理。// Room + LiveData示例 LiveData<List<User>> users = appDatabase.userDao().getAllUsers(); users.observe(lifecycleOwner, list -> { // 更新UI });
数据库版本升级数据迁移
- 实现:重写
RoomDatabase.Migration
或SQLiteOpenHelper.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"); } };
- 实现:重写
最佳实践
- 使用加密数据库:通过
SQLiteOpenHelper
的encrypt()
方法保护敏感数据。 - 避免内存泄漏:确保
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
块控制