Android Room 简单使用
Table of Contents
1 Android Room 简单使用
1.1 说明
这次没有用内置的 SQLite
库,而是直接使用了 Room
,原因之一是 SQLite
在创建数据库的时候出错了,排查不到哪一步出错
二是这个 Room
与 Flutter 中的 floor
框架非常相似,可以无缝迁移
1.2 添加依赖
在 src/build.gradle
中
dependencies { def room_version = "2.4.2" implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" }
1.3 配置类
Room
包含三个主要组件
- 数据库类
- 数据实体
- 数据访问对象(DAO)
他们的定义如下
1.3.1 数据实体
@Entity public class User { @PrimaryKey public int uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
1.3.2 数据访问对象
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User... users); @Delete void delete(User user); }
注意
- 他只需要一个接口来表示
DAO
类型,代码会自动生成,不需要担心 - 变量名替换用冒号
:
1.3.3 数据库类
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
1.4 投入使用
这里不使用官方教程提供的实例,而是
AppDatabase database = Room.databaseBuilder( getApplicationContext(), AppDatabase.class, "test.db") .allowMainThreadQueries().build(); UserDao userDao = database.userDao();
不知道为什么,直接使用 build
方法会产生错误,需要添加一个 allowMainThreadQueries
另外我们添加了一个 Button
和 TextView
来实现一些交互,简单来说,按钮来添加数据, TextView
来显示数据
Button button = findViewById(R.id.button_add); TextView textView = findViewById(R.id.textView); button.setOnClickListener(view -> { userDao.insertAll( new User(1, "hello", "world"), new User(2, "fuck", "you"), new User(3, "holy", "shit") ); List<User> users = userDao.getAll(); textView.setText(users.stream().map(x -> x.toString()).collect(Collectors.joining("\n"))); });
别忘了给 User
添加构造函数
现在问题来了,第一次点击按钮是没有问题的,第二次点击就会出错
这是因为数据库主键重复了,我们重新设置下数据模型类
@Entity public class User { @PrimaryKey(autoGenerate = true) public Integer uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
像 floor
框架一样,将主键的值设为 null
,程序会在数据库中自动添加主键,这样以后修改关于添加的代码
button.setOnClickListener(view -> { userDao.insertAll( new User("hello", "world"), new User("fuck", "you"), new User("holy", "shit") ); List<User> users = userDao.getAll(); textView.setText(users.stream().map(x -> x.toString()).collect(Collectors.joining("\n"))); });
再次运行你会发现 又出错了 ,错误有关数据库迁移 Migration
这时因为原来的数据表有更改,需要修改原来的数据来兼容现有的数据库版本,这里我们简单处理,直接删掉重建一个
在创建数据库时
AppDatabase database = Room.databaseBuilder( getApplicationContext(), AppDatabase.class, "test.db") .fallbackToDestructiveMigration() .allowMainThreadQueries().build();