当前位置: 首页 > news >正文

Room 数据存储

Room 是 Android Jetpack 组件中的一个持久化库,它是在 SQLite 上提供了一个抽象层,使得数据库访问更加简单、高效。

核心组件

Room 主要由三个组件组成:

  1. Entity(实体):表示数据库中的表

  2. DAO(Data Access Object):包含用于访问数据库的方法

  3. Database(数据库):持有数据库并作为应用持久化数据的主要访问点

1. Entity(实体)

Entity 是一个数据类,用于定义数据库中的表结构。

@Entity(tableName = "users")
data class User(@PrimaryKey(autoGenerate = true) val id: Int,@ColumnInfo(name = "first_name") val firstName: String,@ColumnInfo(name = "last_name") val lastName: String,val age: Int
)

常用注解:

  • @Entity:标记类为 Room 实体

  • @PrimaryKey:定义主键

  • @ColumnInfo:自定义列名

  • @Ignore:忽略字段,不存入数据库

2. DAO(数据访问对象)

DAO 是一个接口,定义了访问数据库的方法。

@Dao
interface UserDao {@Insertsuspend fun insert(user: User)@Updatesuspend fun update(user: User)@Deletesuspend fun delete(user: User)@Query("SELECT * FROM users")fun getAllUsers(): LiveData<List<User>>@Query("SELECT * FROM users WHERE id = :userId")suspend fun getUserById(userId: Int): User?
}

常用注解:

  • @Insert@Update@Delete:基本 CRUD 操作

  • @Query:自定义 SQL 查询

3. Database(数据库)

Database 是一个抽象类,扩展自 RoomDatabase。

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDaocompanion object {private var INSTANCE: AppDatabase? = nullfun getDatabase(context: Context): AppDatabase {return INSTANCE ?: synchronized(this) {val instance = Room.databaseBuilder(context.applicationContext,AppDatabase::class.java,"app_database").build()INSTANCE = instanceinstance}}}
}

使用 Room

  1. 添加依赖

implementation "androidx.room:room-runtime:2.4.0"
kapt "androidx.room:room-compiler:2.4.0"
implementation "androidx.room:room-ktx:2.4.0"
  1. 创建实体、DAO 和数据库类(如上所示)

  2. 在应用中使用

val db = AppDatabase.getDatabase(applicationContext)
val userDao = db.userDao()// 插入用户
lifecycleScope.launch {userDao.insert(User(0, "John", "Doe", 30))
}// 观察用户列表
userDao.getAllUsers().observe(this) { users ->// 更新 UI
}

Room 的高级特性

  1. 关系:使用 @Relation@ForeignKey 定义表间关系

  2. 类型转换器:使用 @TypeConverter 存储自定义类型

  3. 数据库迁移:使用 Migration 类处理数据库版本升级

  4. 预填充数据库:从 assets 或文件预加载数据

  5. RxJava/Coroutines 支持:异步操作支持

Room 数据库(Java 版)

一、基本设置

1. 添加依赖

在 build.gradle 文件中添加:

dependencies {def room_version = "2.4.3"implementation "androidx.room:room-runtime:$room_version"annotationProcessor "androidx.room:room-compiler:$room_version"// 可选 - Kotlin扩展和协程支持implementation "androidx.room:room-ktx:$room_version"// 可选 - RxJava支持implementation "androidx.room:room-rxjava2:$room_version"
}

二、核心组件(Java实现)

1. Entity(实体类)

@Entity(tableName = "users")
public class User {@PrimaryKey(autoGenerate = true)private int id;@ColumnInfo(name = "user_name")private String name;@ColumnInfo(name = "user_age")private int age;@Ignoreprivate String tempData; // 不会被存储到数据库// 构造方法public User(String name, int age) {this.name = name;this.age = age;}// Getter 和 Setter 方法public int getId() { return id; }public void setId(int id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }
}

2. DAO(数据访问对象)

@Dao
public interface UserDao {@Insertvoid insert(User user);@Insertvoid insertAll(User... users);@Updatevoid update(User user);@Deletevoid delete(User user);@Query("DELETE FROM users")void deleteAll();@Query("SELECT * FROM users")List<User> getAll();@Query("SELECT * FROM users WHERE id = :userId")User getUserById(int userId);@Query("SELECT * FROM users WHERE user_name LIKE :name LIMIT 1")User findUserByName(String name);// 使用LiveData观察数据变化@Query("SELECT * FROM users")LiveData<List<User>> getAllLiveUsers();
}

3. Database(数据库类)

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {public abstract UserDao userDao();private static volatile AppDatabase INSTANCE;public static AppDatabase getDatabase(final Context context) {if (INSTANCE == null) {synchronized (AppDatabase.class) {if (INSTANCE == null) {INSTANCE = Room.databaseBuilder(context.getApplicationContext(),AppDatabase.class,"app_database").fallbackToDestructiveMigration() // 数据库升级时清空数据.build();}}}return INSTANCE;}
}

三、数据库操作

1. 初始化数据库

AppDatabase db = AppDatabase.getDatabase(getApplicationContext());
UserDao userDao = db.userDao();

2. 插入数据

// 在主线程执行会抛出异常,必须在后台线程执行
new Thread(() -> {User user = new User("张三", 25);userDao.insert(user);
}).start();// 或者使用AsyncTask
new AsyncTask<Void, Void, Void>() {@Overrideprotected Void doInBackground(Void... voids) {User user = new User("李四", 30);userDao.insert(user);return null;}
}.execute();

3. 查询数据

// 同步查询(需在后台线程)
List<User> users = userDao.getAll();// 异步查询(使用LiveData观察)
userDao.getAllLiveUsers().observe(this, users -> {// 更新UIadapter.setUsers(users);
});

4. 更新和删除

new Thread(() -> {// 更新User user = userDao.getUserById(1);if (user != null) {user.setName("王五");userDao.update(user);}// 删除userDao.delete(user);
}).start();

四、高级功能

1. 数据库迁移

// 定义迁移策略
static final Migration MIGRATION_1_2 = new Migration(1, 2) {@Overridepublic void migrate(SupportSQLiteDatabase database) {database.execSQL("ALTER TABLE users ADD COLUMN email TEXT");}
};// 应用迁移
Room.databaseBuilder(context, AppDatabase.class, "app_database").addMigrations(MIGRATION_1_2).build();

2. 类型转换器

public class Converters {@TypeConverterpublic static Date fromTimestamp(Long value) {return value == null ? null : new Date(value);}@TypeConverterpublic static Long dateToTimestamp(Date date) {return date == null ? null : date.getTime();}
}// 在Database类中添加
@Database(entities = {User.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {// ...
}

3. 关系查询

// 一对多关系
public class UserWithPets {@Embeddedpublic User user;@Relation(parentColumn = "id",entityColumn = "user_id")public List<Pet> pets;
}// 在DAO中
@Transaction
@Query("SELECT * FROM users")
public List<UserWithPets> getUsersWithPets();

五、最佳实践

  1. 不要在主线程操作数据库:Room 默认不允许在主线程访问数据库

  2. 合理使用 LiveData/RxJava:简化异步操作

  3. 适当使用事务:对多个相关操作使用 @Transaction

  4. 合理设计数据库版本迁移策略:避免数据丢失

  5. 考虑使用 Repository 模式:将数据库操作与 ViewModel 解耦

六、完整示例

// 在ViewModel中使用
public class UserViewModel extends AndroidViewModel {private UserDao userDao;private LiveData<List<User>> allUsers;public UserViewModel(@NonNull Application application) {super(application);AppDatabase db = AppDatabase.getDatabase(application);userDao = db.userDao();allUsers = userDao.getAllLiveUsers();}public LiveData<List<User>> getAllUsers() {return allUsers;}public void insert(User user) {AppDatabase.databaseWriteExecutor.execute(() -> {userDao.insert(user);});}
}// 在Activity中使用
UserViewModel viewModel = new ViewModelProvider(this).get(UserViewModel.class);
viewModel.getAllUsers().observe(this, users -> {// 更新RecyclerViewadapter.submitList(users);
});// 插入新用户
User newUser = new User("赵六", 28);
viewModel.insert(newUser);

http://www.lryc.cn/news/620884.html

相关文章:

  • AI 赋能:从智能编码提速到金融行业革新的实践之路
  • 机器翻译:Hugging Face库详解
  • 【51单片机学习】定时器、串口、LED点阵屏、DS1302实时时钟、蜂鸣器
  • 深入解析Prompt缓存机制:原理、优化与实践经验
  • (第十五期)HTML文本格式化标签详解:让文字更有表现力
  • 若依前后端分离版学习笔记(十)——数据权限
  • 阿里云TranslateGeneral - 机器翻译SDK-自己封账单文件版本—仙盟创梦IDE
  • 在mysql> 下怎么运行 .sql脚本
  • LeetCode 分类刷题:2302. 统计得分小于 K 的子数组数目
  • AI引擎重构数据安全:下一代分类分级平台的三大技术跃迁
  • Keep-Alive 的 “爱情故事”:HTTP 如何从 “短命” 变 “长情”?
  • Qt TCP 客户端对象生命周期与连接断开问题解析
  • 从零开始学Python之数据结构(字符串以及数字)
  • 18.13 《3倍效率提升!Hugging Face datasets.map高级技巧实战指南》
  • C# 贪吃蛇游戏
  • PHP现代化全栈开发:微服务架构与云原生实践
  • 机器视觉的磁芯定位贴合应用
  • Linux命令大全-zip命令
  • AI Agent 为什么需要记忆?
  • C++ 23种设计模式的分类总结
  • 使用DevEco Studio运行鸿蒙项目,屏蔽控制台无关日志,过滤需要的日志
  • Lua 脚本在 Redis 中的应用
  • 【科研绘图系列】R语言绘制微生物丰度和基因表达值的相关性网络图
  • 构建Node.js单可执行应用(SEA)的方法
  • 01数据结构-最短路径Dijkstra
  • 【HarmonyOS】Window11家庭中文版开启鸿蒙模拟器失败提示未开启Hyoer-V
  • JavaScript方法借用技术详解
  • HarmonyOS ArkUI 实现商品分类布局
  • C++进阶:特殊类
  • Morph Studio-一站式AI视频创作平台