使用 Room 操作 SQLite (Android 开发)
总结放在前面
现在还没有学过数据库,说一下我自己的理解
Room 可以把类的对象存储到数据库中
每一个对象就是一行(row),对象中被存储的属性就是列(column)
行 : 对象 列:属性 属性1 属性 2 … 对象 1(PrimaryKey) 对象 1 的属性1 的值 对象 1 的属性2的值 对象 2(PrimaryKey) 对象 2 的属性1 的值 对象 2的属性2 的值 … 这样就组成一张表,一张表就是一个数据库
要操作这个数据库就使用 Dao 中的方法来增查删改
如需在应用中使用 Room,请将以下依赖项添加到应用的 build.gradle
文件
dependencies {
def room_version = "2.2.6"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// optional - RxJava support for Room
implementation "androidx.room:room-rxjava2:$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"
}
-
Room 的三个组件
- Database : 数据库holder,持有者
- Data entities : 数据实体,要存储的类
- Data access objects ( DAOs ) :数据库访问方法
-
三个组件之间的关系
- 开发者使用 DAO的方法 将 Data entities的对象 放入 Database
- 下面这个图为谷歌官方图(一坨 shit)
-
使用例子(Sample)
-
定义Data entity , Data access object 以及 Database 具体对象
Data entity (更多使用细节 使用 Room 实体定义数据 )
@Entity public class User { @PrimaryKey public int uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
Data access object (更多使用细节 使用 Room DAO 访问数据 )
@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); }
Database
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
-
使用 Dao 操作数据库
创建或者打开数据库
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build();
获取数据库访问方法
UserDao userDao = db.userDao(); // 获取 Dao 对象 List<User> users = userDao.getAll(); // 获取数据库所有对象
使用 Data access object 增,查,删,改
-
-
Room entities 详细使用方法
- 主键(PrimaryKey)
@Entity public class User { @PrimaryKey public int id; public String firstName; public String lastName; }
要存储类中的属性,必须将属性设为 public , 或者给出 getter 和 setter
每个 entity 必须将一个属性定义为主键(PrimaryKey) , 且每一个实例对象必须有不同的主键值才可以放入数据库 , 就是说每个 entity 的对象都要有一个唯一的编号,不然不好找
如果您想让 Room 为实体分配自动 ID,则可以设置
@PrimaryKey
的autoGenerate
属性。如果实体具有复合主键,您可以使用@Entity
注释的primaryKeys
属性,如以下代码段所示:@Entity(primaryKeys = {"firstName", "lastName"}) public class User { public String firstName; public String lastName; }
- 数据库表名称
默认情况下,Room 将类名称用作数据库表名称。如果希望表具有不同的名称,请设置
@Entity
注释的tableName
属性,如以下代码段所示:@Entity(tableName = "users") public class User { // ... }
表名称不区分大小写
- 数据库列名称
Room 将属性名称用作数据库中的列名称。如果希望列具有不同的名称,请将
@ColumnInfo
注释添加到字段,如以下代码段所示:@Entity(tableName = "users") public class User { @PrimaryKey public int id; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
- 忽略属性
默认情况下,Room 会为实体中定义的每个属性创建一个列。如果实体(要存储的类)中有您不想保留的属性,则可以使用
@Ignore
为这些字段添加注释,如以下代码段所示:@Entity public class User { @PrimaryKey public int id; public String firstName; public String lastName; @Ignore Bitmap picture; }
如果实体类继承了父类的属性,则使用
@Entity
属性的ignoredColumns
属性来忽略:@Entity(ignoredColumns = "picture") public class RemoteUser extends User { @PrimaryKey public int id; public boolean hasVpn; }
- 让表支持搜索功能,以后再学习(https://developer.android.google.cn/training/data-storage/room/defining-data#java)
-
使用 Dao 访问数据库
-
插入 insert
@Dao public interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) //OnConflictStrategy.ABORT(默认)在发生冲突时回滚事务 //OnConflictStrategy.REPLACE 现有行替换为新行 //OnConflictStrategy.IGNORE 持现有行 public void insertUsers(User... users); @Insert public void insertBothUsers(User user1, User user2); @Insert public void insertUsersAndFriends(User user, List<User> friends); }
如果
@Insert
方法只接收 1 个参数,则它可以返回long
,这是插入项的新rowId
如果参数是数组或集合,则应返回
long[]
或List<Long>
-
更新 Update
@Dao public interface UserDao { @Update public void updateUsers(User... users); }
传入的对象的会替换在数据库中有相同 id 的那一行
可以让此方法返回一个
int
值,以指示数据库中更新的行数 -
删除 delete
@Dao public interface MyDao { @Delete public void deleteUsers(User... users); }
可以让此方法返回一个
int
值,以指示从数据库中删除的行数 -
查询 query
-
简单查询
-
@Dao public interface MyDao { @Query("SELECT * FROM user") public User[] loadAllUsers(); }
-
-