安卓开发中常用的本地数据库方案包括:
数据库类型 | 特点 | 适用场景 |
---|---|---|
SQLite | 轻量级嵌入式数据库,Android原生支持 | 简单数据存储、离线缓存 |
Room | 基于SQLite的ORM框架,提供编译时校验 | 复杂对象映射、避免手写SQL |
Realm | 高性能对象数据库,跨平台支持 | 实时数据同步、大型数据集 |
创建数据库帮助类
public class DBHelper extends SQLiteOpenHelper { private static final String NAME = "app.db"; private static final int VERSION = 1; public DBHelper(Context context) { super(context, NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建用户表 String sql = "CREATE TABLE user(id INTEGER PRIMARY KEY,name TEXT)"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 数据迁移逻辑 } }
基本CRUD操作
// 插入数据 ContentValues values = new ContentValues(); values.put("name", "张三"); db.insert("user", null, values);
// 查询数据
Cursor cursor = db.query(“user”, null, “id=?”, new String[]{“1”}, null, null, null);
if(cursor.moveToFirst()){
String name = cursor.getString(cursor.getColumnIndex(“name”));
}
// 更新数据
ContentValues updateValues = new ContentValues();
updateValues.put(“name”, “李四”);
db.update(“user”, updateValues, “id=?”, new String[]{“1”});
// 删除数据
db.delete(“user”, “id=?”, new String[]{“1”});
三、Room持久化库实践
1. 实体定义
```java
@Entity(tableName = "user")
public class User {
@PrimaryKey(autoGenerate = true)
public int id;
@ColumnInfo(name = "name")
public String name;
}
DAO接口
@Dao public interface UserDao { @Insert void insertUser(User... users); @Query("SELECT FROM user WHERE id = :userId") User getUserById(int userId); @Update void updateUser(User user); @Delete void deleteUser(User user); }
数据库构建
@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 = new User(); user.name = "王五";
// 插入(异步)
db.userDao().insertUser(user);
// 观察数据变化(LiveData)
LiveData
liveUser.observe(this, user -> {
// UI更新逻辑
});
四、性能优化策略
| 优化方向 | 实施方案 |
|---------|----------|
| 主线程阻塞 | 使用`AsyncTask`或`ExecutorService`处理耗时操作 |
| 内存泄漏 | 使用`Application`级数据库实例,避免频繁创建 |
| 批量操作 | 使用`SQLiteStatement`预编译语句 |
| 索引优化 | 为高频查询字段添加`INDEX` |
五、常见问题解决方案
| 问题现象 | 解决方案 |
|---------|----------|
| `SQLiteException: no such table` | 检查`onCreate()`是否被调用,版本号是否正确 |
| Room编译报错 | 清理项目缓存,检查@Entity注解是否正确 |
| 多线程冲突 | 使用`RxJava`或`Coroutine`进行线程控制 |
---
相关问题与解答
Q1:Room相比直接使用SQLite的优势是什么?
A1:Room提供以下改进:
编译时语法检查,避免运行时SQL错误
自动生成DAO实现类,减少模板代码
内置LiveData/RxJava支持,简化观察者模式
类型安全的对象映射,防止数据类型错误
更好的架构分层支持(Repository模式)
Q2:如何处理数据库版本升级时的兼容性问题?
A2:通过`onUpgrade()`方法实现:
1. 版本控制:在`DBHelper`构造函数指定`versionCode`
2. 迁移脚本:在`onUpgrade()`中编写ALTER语句(如添加新列)
3. 数据迁移:使用`Migration`类分阶段迁移(Room特有)
4. 测试验证:通过`SQLiteDatabase.execSQL()`执行迁移脚本后,检查数据完整性
5. 备份恢复:重要更新前导出旧数据,更新后导入新结构