本文章涉及到SQLite语法,对SQLite语法不了解的朋友可以先学习一下它的基本使用再来阅读本文章。
介绍
Room是Android Jetpack中用于操作数据库的库,本篇文章将讲解Room的使用方法,并简单介绍如何使用Database Inspector调试(Android Studio 4.1+)。
基本使用方法
使用Room,我们要完成三个工作,定义实体类,定义DAO,定义数据库。
首先把Room的相关库导进来,前面两项是必要的,后面的optional是可选项,它们是Room对其他三方库的拓展。
def room_version = "2.4.1"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// optional - RxJava2 support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - RxJava3 support for Room
implementation "androidx.room:room-rxjava3:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
// optional - Paging 3 Integration
implementation "androidx.room:room-paging:2.4.1"
接着来定义数据实体User。
@Entity是Room的一个注解,标记在实体类上才能在编译的时候识别。
@PrimaryKey即主键。autoGenerate = true时,每次插入主键都会自动加1,默认为false。
@ColumnInfo表示它在数据库里面的名字(如user_name),这个标记不是必须的。
@Entity
public class User {
@PrimaryKey(autoGenerate = true)
private long id;
@ColumnInfo(name = "user_name")
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@NonNull
@Override
public String toString() {
return "id=" + id + " name=" + name;
}
}
如果希望成员变量不出现在数据库表里,可以使用@Ignore。
@Entity
public class User {
@PrimaryKey(autoGenerate = true)
private long id;
@ColumnInfo(name = "user_name")
private String name;
@Ignore
private String nickName;
...
}
下面来定义DAO(Data Access Objects 数据存取对象)。
类似地,在接口上标记@Dao
@Insert是插入标记。
@Delete是删除标记。
@Query是查询标记,也可以用于更新。方法里的参数对应于注解里的SQL参数(前面加一个冒号)
@Dao
public interface UserDao {
@Insert
void insertUser(User user);
@Delete
void deleteUser(User user);
@Query("SELECT * FROM user")
List<User> getAllUser();
@Query("SELECT * FROM user WHERE user_name = :name")
List<User> getUserByName(String name);
@Query("UPDATE user SET user_name = :name where id=:id")
void update(String name, int id);
}
接着定义Database。entities 中包含所有实体类,version是版本号。注意定义的数据库类必须是抽象类。
@Database(entities = {User.class},version = 1)
public abstract class UserDatabase extends RoomDatabase {
public abstract UserDao getUserDao();
}
至此,定义实体类,定义DAO,定义数据库三个工作就完成了,rebuild一下工程就能自动生成相关代码。
Android Studio可能会提示警告信息。
警告: Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide `room.schemaLocation` annotation processor argument OR set exportSchema to false.
public abstract class UserDatabase extends RoomDatabase {
在Gradle中添加如下内容,rebuild即可。
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
}
}
通过以下方式就能获取到UserDatabase。需要注意的是,Activity或Fragment不应该持有UserDatabase对象引用,因为UserDatabase的存活时间要比Activity和Fragment长,持有UserDatabase引用可能导致内存泄漏。我们可以把UserDatabase的创建放在Application的onCreate方法上。
UserDatabase userDatabase = Room.databaseBuilder(applicationContext,UserDatabase.class,"user_db").build();
最后就可以进行数据库表的增删改查了。
User user = new User();
user.setName("user-" + mCount++);
userDatabase.getUserDao()
.insertUser(user);
注意,增删改查不能在主线程上进行,否则会抛出异常。其实这也很合理,因为数据库操作本就是耗时的。当然也可以在Database创建的时候允许在主线程操作。
mUserDatabase = Room.databaseBuilder(applicationContext,UserDatabase.class,"user_db")
.allowMainThreadQueries()
.build();
Database Inspector调试
完成了代码的编写,接下来就是调试了。Android Studio 4.1提供了一个调试数据库的工具,叫Database Inspector。
首先在真机或虚拟机上启动App,在红色框选择调试的App,点击橙色框的Database Inspector进入数据库界面。此时是看不到数据的,只有插入或更新数据时,下面的数据框才会出现。
蓝色框是自动更新选项,勾上它,在数据库表增删改时就能自动更新下面数据框的内容。不勾上它,双击数据框的数据就能在Android Studio上修改App的数据库数据了。
最后
本篇文章讲解了Room的基本使用方法以及Database Inspector的调试步骤。
参考文章
《Schema export directory is not provided to the annotation processor so we cannot export the schema.》
《Android开发者文档》