Jetpack之RoomDatabase简介及其使用

Jetpack之RoomDatabase简介及其使用

2023年7月25日发(作者:)

Jetpack之RoomDatabase简介及其使⽤简介Room是SQLite之上的⼀个抽象层,通过Room,可以更加丝滑的使⽤SQLite的全部功能。并且,原本在运⾏期才能发现的SQL语句错误,现在在编译期就会报错,写过SQL的同学都懂,尤其是使⽤复杂语句的时候,这使得SQL语句纠错的时间⼤⼤缩短。Room主要由以下三个部分组成:DataBase ⽤ seBuilder() 或 ryDatabaseBuilder().⽅法获取DataBase实例Entity 可以看成是数据库中的表DAO 提供访问数据库的⽅法关系图1. Database1.1 定义数据库// entities是数据,有⼏个元素就建⽴⼏张表@Database(entities = {}, version = 1)public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao();}1.2 获取数据库AppDatabase db = seBuilder(getApplicationContext(), , "database-name").build();2. EntityEntity 默认为每个属性定义⼀列,可以使⽤@Ignore注解来忽略;属性必须为public或提供公有的getters和setters。以User为例:@Entitypublic class User { @PrimaryKey private int uid; @ColumnInfo(name = "first_name") private String firstName; @ColumnInfo(name = "last_name") private String lastName;

// 默认为每个属性定义⼀列,可以使⽤@Ignore注解来避免创建此列 @Ignore Bitmap picture; // 属性必须为public或提供公有的getters and setters,为了简洁,在此省略}2.1 主键:使⽤@PrimaryKey来定义主键,如果需要⼀个⾃增的主键,@PrimaryKey的autoGenerate置为true:@PrimaryKey(autoGenerate = true)

private int index;2.2 复合主键:@Entity(primaryKeys = {"firstName", "lastName"})public class User { public String firstName; public String lastName; @Ignore Bitmap picture;}2.3 表名:默认使⽤类名作为表名,也可以指定表名@Entity(tableName = "users")public class User { ……}2.4 列明默认使⽤属性名作为列名,可以⽤@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; @Ignore Bitmap picture;}2.5 使⽤索引@Entity(indices = {@Index("name"), @Index(value = {"last_name", "address"})})public class User { @PrimaryKey public int id; public String firstName; public String address; @ColumnInfo(name = "last_name") public String lastName; @Ignore Bitmap picture;}@Entity(indices = {@Index(value = {"first_name", "last_name"}, unique = true)})public class User { @PrimaryKey public int id; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; @Ignore Bitmap picture;}2.6 外键@Entity(foreignKeys = @ForeignKey(entity = , parentColumns = "id", childColumns = "user_id"))public class Book { @PrimaryKey public int bookId; public String title; @ColumnInfo(name = "user_id") public int userId;}2.7 混合型Entity例如有Address类,有三个属性:street、state、city,User表中⼜包含这个三个列,可以使⽤@Embedded注解public class Address { public String street; public String state; public String city; @ColumnInfo(name = "post_code") public int postCode;}@Entitypublic class User { @PrimaryKey public int id; public String firstName; @Embedded public Address address;}2.8 复杂类型的使⽤属性类型不局限于SQLite数据类型,可以使⽤使⽤任意类型,但在使⽤⾮SQLite数据类型时,需要定义Converter类,⽤于将数据转化为数据可以存储的类型1. 定义Convert类public class Converter1 { @TypeConverter public static Date fromTimestamp(Long value) { return value == null ? null : new Date(value); } @TypeConverter public static Long dateToTimestamp(Date date) { return date == null ? null : e(); }}2. 给Database加注解:@Database(entities = {}, version = 1)@TypeConverters({, })public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao();}3 o可以是interface也可以是abstract类,如果是abstract类,需要提供⼀个参数为RoomDatabase的构造函数。Room会在编译器⾃动我们⽣成DAO的实现类定义增删改查⽅法:3.1 增使⽤@Insert注解,通常Room会使⽤⼀次事务把所有数据都插⼊数据库中。@Daopublic interface MyDao { @Insert(onConflict = E) public void users); @Insert public void insertBothUsers(User user1, User user2); @Insert public void insertUsersAndFriends(User user, List friends);}3.2 删@Daopublic interface MyDao { @Delete public void users);}3.3 改@Daopublic interface MyDao { @Update public void users);}3.4 查@Query注解是DAO中最重要的注解,每⼀个@Query⽅法都在编译期⽣成,如果查询语句有误的话,会在编译期报错,⽽不是运⾏期操作失败。3.4.1 简单查询:@Daopublic interface MyDao { @Query("SELECT * FROM user") public User[] loadAllUsers();}3.4.2 查询语句中带参数,使⽤":"+参数名@Daopublic interface MyDao { @Query("SELECT * FROM user WHERE age > :minAge") public User[] loadAllUsersOlderThan(int minAge);}@Daopublic interface UserDao { @Query("SELECT * FROM user") List getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List 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 users); @Delete void delete(User user);}3.4.3 返回某⼏列数据:有时候,我们只需要Entity的某⼏个属性,例如,UI上只展⽰了⽤户姓名,只取UI需要的数据不仅节约宝贵的资源,并且还能使查询速度更快。Room允许@Query⽅法返回任意⼀个POJO,以此来获取部分咧的数据public class NameTuple { @ColumnInfo(name="first_name") public String firstName; @ColumnInfo(name="last_name") public String lastName;}3.4.4 使⽤集合来作为IN操作符的参数Room能够识别集合参数,并在运⾏时⾃动扩展@Daopublic interface MyDao { @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)") public List loadUsersFromRegions(List regions);}3.4.5 结合LiveData实时更新UI通常我们查询数据库都要更新到UI上,可以结合使⽤LiveData来帮助我们更新UI,Dao可以之间返回LiveData的数据。@Daopublic interface MyDao { @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)") public LiveData> loadUsersFromRegionsSync(List regions);}3.4.6 RxJava查询:@Daopublic interface MyDao { @Query("SELECT * from user where id = :id LIMIT 1") public Flowable loadUserById(int id);}3.4.7 直接获取Cursor有时候需求需要直接获取Cursor,那么可以这样做:@Daopublic interface MyDao { @Query("SELECT * FROM user WHERE age > :minAge LIMIT 5") public Cursor loadRawUsersOlderThan(int minAge);}3.4.8 查询关联表@Daopublic interface MyDao { @Query("SELECT * FROM book " + "INNER JOIN loan ON _id = " + "INNER JOIN user ON = _id " + "WHERE LIKE :userName") public List findBooksBorrowedByNameSync(String userName);}也可以使⽤POJO@Daopublic interface MyDao { @Query("SELECT AS userName, AS petName " + "FROM user, pet " + "WHERE = _id") public LiveData> loadUserAndPetNames(); // You can also define this class in a separate file, as long as you add the // "public" access modifier. static class UserPet { public String userName; public String petName; }}@Daopublic interface MyDao { @Query("SELECT first_name, last_name FROM user") public List loadFullName();}3.5 数据库版本控制Room使⽤Migration类版本的升级,Migration定义了两个变量,startVersion和endVersion,Room会调⽤每⼀个e()⽅法,使得数据库能按照正确的顺序升级数据库版本seBuilder(getApplicationContext(), , "database-name") .addMigrations(MIGRATION_1_2, MIGRATION_2_3).build();static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { L("CREATE TABLE `Fruit` (`id` INTEGER, " + "`name` TEXT, PRIMARY KEY(`id`))"); }};static final Migration MIGRATION_2_3 = new Migration(2, 3) { @Override public void migrate(SupportSQLiteDatabase database) { L("ALTER TABLE Book " + " ADD COLUMN pub_year INTEGER"); }};Room Database使⽤⼩结1. ⼀个抽象类或接⼝,继承 RoomDataBase,并使⽤@Database注解。1).@Database(entities = [Dog::class, Cat::class], version = 1, exportSchema = false) entities 数组中,⼀个Entity建⼀张表2). 如果Entity中有⾮直接插⼊表中的数据类型,需要@Convertes注解2. Entity ,⼏张表⼏个Entity,定义了表名、列名等,属性和表中字段完全对应,并在该类中提供 setter和getter⽅法来设置并获取该类中的属性。属性类型不局限于SQLite数据类型,可以使⽤使⽤任意类型, 但在使⽤⾮SQLite数据类型时,需要定义Converter类,⽤于将数据转化为数据可以存储的类型Entity注解:1).@Entity 声明表名、外键等2).@PrimaryKey 主键3).@ColumnInfo 列信息,不写的话,列名=变量名3. Dao,定义了所有的⽤户操作,如添加记录、删除记录及查询记录等。为⽅便管理,最好⼏张表⼏个Dao。4. Dao⼯⼚类推荐使⽤DAO⼯⼚类在没有DAO⼯⼚类的情况下,必须通过创建DAO实现类的实例才能完成数据库操作。这时就必须知道具体的⼦类,对于后期的修改⾮常不⽅便。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1690217856a316609.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信