Android 官方数据库Room --- 数据调用

源文档链接

数据调用

可以使用DAO来查询存储数据。这一些列的DAO使用Room的重要组件,每个DAO都提供抽象的数据操作方法

使用DAO操作时,不使用查询构建者或者直接的查询,可以根据自己的数据库结构划分不同的组件。更多的,DAO允许模拟数据库来测试

使用@DAO定义
在添加DAO之前,先将配置添加到build.gradle中

DAO可以是接口或者抽象类。如果是个抽象类,可以拥有仅包含RoomDatabase的构造器。Room在编译期实现每个DAO

Room不允许在主线程使用,除非调用了allowMainThreadQueries,因为可能锁的问题使得UI无响应。

异步查询 – 返回LiveData或者Flowable实例的查询 - 免于此规则,因为会在后台线程中进行查询

简单方法定义

Room包括很多方便的查询,这里对常见查询举例

Insert

当定义一个DAO方法并使用@Insert注解时,Room会生成实现代码,并在一个事务中间所有的参数插入数据库

例:

@Dao
public interface MyDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public void insertUsers(User... users);

    @Insert
    public void insertBothUsers(User user1, User user2);

    @Insert
    public void insertUsersAndFriends(User user, List<User> friends);
}

如果@Insert方法只接受一个参数,可以返回一个代表新插入数据的rowId的long类型值。如果参数是个数组或者集合,会同样的返回long[]或者List<Long>

更多参考@Insert,关于rowId

Update

Update方法会重新定义表中对应参数中的一系列实体。使用主键来查询每个实体

@Dao
public interface MyDao {
    @Update
    public void updateUsers(User... users);
}

虽然不是必须的,这个方法可以返回int类型的值,标明表中有多少条数据更新

Delete

Delete方法会移除方法中的一系列实体。使用主键来查询并且移除

@Dao
public interface MyDao {
    @Delete
    public void deleteUsers(User... users);
}

同样不是必须的,这个方法可以返回int类型的值,表明移除了多少条数据

查询信息

Query是DAO类中使用的主要注解。允许自定义对表进行读写操作。每个@Query方法会在编译器进行验证,避免在运行时出错

Room也验证了查询的返回值,如果返回对象中的属性和表中的字段名不匹配是,Room会通过两种方式提示:

  1. 如果只有一些属性名匹配,会发出warning
  2. 如果没有属性名匹配,会发出error
简单查询
@Dao
public interface MyDao {
    @Query("SELECT * FROM user")
    public User[] loadAllUsers();
}

这是一个非常简单所有user的查询,在编译器,Room知道会查询user表中的所有列。如果查询中包括了符号错误,或者是user表根本不存在,Room会在app编译时提示异常

参数占位

大多数情况,sql语句应该是动态的,Room允许使用占位符,并使用方法的参数进行填充

@Dao
public interface MyDao {
    @Query("SELECT * FROM user WHERE age > :minAge")
    public User[] loadAllUsersOlderThan(int minAge);
}

编译器,Room会使用参数中的minAge来绑定:minAge值。如果这里两个名称不匹配,Room会报错

多个参数

@Dao
public interface MyDao {
    @Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge")
    public User[] loadAllUsersBetweenAges(int minAge, int maxAge);

    @Query("SELECT * FROM user WHERE first_name LIKE :search "
           + "OR last_name LIKE :search")
    public List<User> findUserWithName(String search);
}
返回列的子集

大多数情况,仅仅需要获取实体的一部分属性。例如,UI中可能只是展示first name和last name,而不是user的所有信息。可以只保存有价值的信息,还能加快查询速度

Room允许查询时返回任意可以将查询列结果包装的java对象,可以使用POJO取用户的first name和last name

public class NameTuple {
    @ColumnInfo(name="first_name")
    public String firstName;

    @ColumnInfo(name="last_name")
    public String lastName;
}

作为查询的返回

@Dao
public interface MyDao {
    @Query("SELECT first_name, last_name FROM user")
    public List<NameTuple> loadFullName();
}

Room能够理解返回first_namelast_name的值,并填充到NameTuple对象中。因此,Room可以生成合适的代码。如果查询的返回具有更多的列,或者某个列不再NameTuple中,Room会提示warning

这些POJO也可以使用@Embedded注解

使用集合声明

一些查询可能需要一组参数,而且运行时不确定个数。例如:想获取所有users中一个地区的子集。Room允许使用集合参数,并在运行时按照内容个数将集合展开

@Dao
public interface MyDao {
    @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
    public List<NameTuple> loadUsersFromRegions(List<String> regions);
}
可观察的查询

查询时,UI可能需要根据数据的改变而改变。为此,提供了LiveData的返回类型。Room生成了必须的代码保证数据库更新时更新LiveData

@Dao
public interface MyDao {
    @Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
    public LiveData<List<User>> loadUsersFromRegionsSync(List<String> regions);
}

Note:1.0版本,Room使用查询中表的列表来决定是否更新LiveData

响应式查询 – Rxjava

Room可以返回Rxjava2PublisherFlowable对象,需要添加android.arch.persistence.room:rxjava2的依赖

@Dao
public interface MyDao {
    @Query("SELECT * from user where id = :id LIMIT 1")
    public Flowable<User> loadUserById(int id);
}

更多

直接使用游标
@Dao
public interface MyDao {
    @Query("SELECT * FROM user WHERE age > :minAge LIMIT 5")
    public Cursor loadRawUsersOlderThan(int minAge);
}

注意:强烈不建议使用Cursor API,因为无法保证行是否存在或者行中包含的值。

多表联查

Room允许使用任意的查询语句,包括join。如果是观察式查询,如返回值为Flowable或者LiveData,Room会监视查询中涉及的所有表

@Dao
public interface MyDao {
    @Query("SELECT * FROM book "
           + "INNER JOIN loan ON loan.book_id = book.id "
           + "INNER JOIN user ON user.id = loan.user_id "
           + "WHERE user.name LIKE :userName")
   public List<Book> findBooksBorrowedByNameSync(String userName);
}

也可以返回POJO

@Dao
public interface MyDao {
   @Query("SELECT user.name AS userName, pet.name AS petName "
          + "FROM user, pet "
          + "WHERE user.id = pet.user_id")
   public LiveData<List<UserPet>> 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;
   }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值