上一篇
安卓开发定义数据库
- 行业动态
- 2025-04-21
- 4
数据库选型与方案
数据库类型 | 特点 | 适用场景 |
---|---|---|
SQLite | 轻量级嵌入式数据库,支持SQL语法,无需独立服务器进程 | 本地数据存储,简单CRUD操作 |
Room | 基于SQLite的ORM框架,提供编译时校验,支持LiveData | 需要对象关系映射,复杂数据操作,与MVVM架构结合 |
Realm | 高性能跨平台数据库,支持实时更新 | 多平台同步,大数据量操作 |
Firebase | 云数据库服务,实时同步,无需自建服务器 | 需要后端服务,实时数据同步场景 |
Room数据库定义规范
实体类定义
@Entity(tableName = "user") public class User { @PrimaryKey(autoGenerate = true) public int id; @ColumnInfo(name = "username") public String userName; @ColumnInfo(name = "age") private int age; // 必须提供无参构造函数 public User(String userName, int age) { this.userName = userName; this.age = age; } }
DAO接口定义
@Dao public interface UserDao { @Query("SELECT FROM user WHERE id = :userId") User getUserById(int userId); @Insert(onConflict = OnConflictStrategy.REPLACE) long insertUser(User user); @Update int updateUser(User user); @Delete int deleteUser(User user); // 自定义复杂查询 @Query("SELECT COUNT() FROM user WHERE age > :minAge") int countUsersOlderThan(int minAge); }
数据库类定义
@Database(entities = {User.class}, version = 2) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); // 数据库迁移策略 static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { // 创建新表 database.execSQL("CREATE TABLE IF NOT EXISTS user_backup (id INTEGER PRIMARY KEY, username TEXT)"); // 数据迁移 database.execSQL("INSERT INTO user_backup(id,username) SELECT id,username FROM user"); // 删除旧表 database.execSQL("DROP TABLE user"); // 重命名新表 database.execSQL("ALTER TABLE user_backup RENAME TO user"); } }; }
数据库初始化与使用
AppDatabase db = Room.databaseBuilder( context, AppDatabase.class, "app-database" ) .addMigrations(MIGRATION_1_2) // 添加迁移策略 .allowMainThreadQueries() // 开发阶段允许主线程操作(生产环境需移除) .build(); // 数据操作示例 UserDao userDao = db.userDao(); User user = new User("John", 25); userDao.insertUser(user);
常见问题与解决方案
问题现象 | 解决方案 |
---|---|
数据库版本升级导致崩溃 | 实现Migration接口处理数据迁移 |
主线程操作数据库异常 | 使用Executors或异步任务处理 |
编译时报错:缺少xxx表 | 检查@Entity注解和数据库版本号 |
数据插入失败 | 检查@PrimaryKey冲突策略和字段约束 |
相关问题解答
Q1:Room相比直接使用SQLite有哪些优势?
- 编译时校验:通过注解生成代码,提前发现语法错误
- 对象关系映射:自动处理Java对象与数据库表的转换
- 活跃对象支持:@LiveData注解实现数据观察
- 类型安全:避免运行时SQL拼接错误
- 更好的架构支持:与ViewModel、Coroutines无缝配合
Q2:如何处理多表关联查询?
@Transaction @Query("SELECT FROM user WHERE id IN (SELECT user_id FROM order)") List<User> getUsersWithOrders();
通过@Transaction
保证原子性,使用标准SQL进行多表JOIN操作,对于复杂查询,建议将业务逻辑下沉到Repository层