一、简介
Room 是一个强大的对象关系映射库,它允许你将 SQLite 数据库中的表映射到 Java 或 Kotlin 的对象(称为实体)上。你可以使用简单的注解(如 @Entity
、@Dao
和 @Database
)来定义数据库表、数据访问对象(DAO)和数据库类。
二、使用方法
引入依赖
android {
defaultConfig {
javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] } }
..........
implementation 'androidx.room:room-runtime:2.4.3'
annotationProcessor 'androidx.room:room-compiler:2.4.3'
implementation "androidx.room:room-ktx:2.4.3"
......
编写实体类
package com.test.proxy.entity;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "student")
public class Student {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
private String name;
@ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER, defaultValue = "0")
private int age;
@ColumnInfo(name = "score", typeAffinity = ColumnInfo.INTEGER, defaultValue = "0")
private long score;
public Student() {
}
public Student(int id, String name, int age, long score) {
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}
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;
}
public long getScore() {
return score;
}
public void setScore(long score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
编写Dao接口
package com.test.proxy.room;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import com.test.proxy.entity.Student;
import java.util.List;
@Dao
public interface StudentDao {
@Insert
void insert(Student student);
@Query("SELECT * FROM student")
List<Student> getAllStudents();
@Query("SELECT * FROM student WHERE name LIKE :searchName")
List<Student> findStudentsByName(String searchName);
}
编写数据库配置类
package com.test.proxy.room;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import com.test.proxy.entity.Student;
@Database(entities = {Student.class} , version = 1, exportSchema = false)
public abstract class AppDataBase extends RoomDatabase {
public abstract StudentDao studentDao();
// 单例模式获取数据库实例
public static AppDataBase INSTANCE;
public static AppDataBase getInstance(Context context) {
if (INSTANCE == null) {
synchronized (AppDataBase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context,
AppDataBase.class,
"app_database")
.allowMainThreadQueries().build();
}
}
}
return INSTANCE;
}
}
使用数据库
public void execute(Context context) {
AppDataBase db = AppDataBase.getInstance(context.getApplicationContext());
StudentDao studentDao = db.studentDao();
Student student = new Student();
student.setName("Tom");
student.setAge(9);
student.setScore(100);
studentDao.insert(student);
Student student2 = new Student();
student2.setName("Amy");
student2.setAge(9);
student2.setScore(60);
studentDao.insert(student2);
List<Student> list = studentDao.getAllStudents();
for (Student stu : list) {
Log.e("TestRoom", "Student :" + stu.toString());
}
}
打印输出
E Student :Student{id=1, name='Tom', age=9, score=100}
E Student :Student{id=2, name='Amy', age=9, score=60}
三、优点
数据的持久化和管理
- Room 提供了方便的 API 来执行插入、更新、删除和查询操作。你可以方便地使用 DAO 接口中的方法,例如
@Insert
、@Update
、@Delete
和@Query
注解的方法。
数据库迁移
- 当需要更新数据库的结构(如添加新表或修改列)时,Room 提供了迁移机制,允许你在数据库版本升级时执行 SQL 语句,确保数据的安全性和一致性。
易于使用
- Room 提供了简洁明了的注解和 API,大大简化了数据库操作。对于熟悉 Java 或 Kotlin 的开发者来说,很容易上手。
- 示例:通过几个简单的注解和接口定义,就能实现数据库的基本操作,而不需要手动编写大量的 SQL 和 SQLite 操作代码。
编译时检查
- 由于 Room 在编译时会检查 SQL 语句和数据库配置,所以可以提前发现错误,减少运行时错误的风险。
- 例如,如果你的 SQL 语句中存在语法错误,编译时会给出相应的错误信息,避免了在运行时出现难以排查的问题。
与 LiveData 和 RxJava 集成
- Room 可以方便地与 LiveData 集成,允许你观察数据库的变化并自动更新 UI。同时,也可以和 RxJava 集成,使用 RxJava 的操作符处理数据库操作的结果。
四、缺点
学习曲线
对于初学者来说,虽然 Room 已经很简单,但仍然需要一定的时间来熟悉其注解和操作模式,尤其是涉及到数据库迁移等高级功能时。
功能限制
Room 虽然强大,但本质上还是建立在 SQLite 之上,对于一些非常复杂的 SQL 操作或存储过程,可能仍然需要直接编写 SQL 语句,并且一些 SQLite 的高级特性可能不直接被 Room 支持。