Android Architecture Components 之 Room 篇

}

@Dao
public interface ProductDao {

@Query(“select * from products”)
List getAllProducts();

@Query(“select * from products where id = :id”)
ProductEntity findProductById(int id);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertProduct(ProductEntity product);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAllProducts(List products);

@Delete
void deleteProduct(ProductEntity product);
}

@Database(entities = {ProductEntity.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract ProductDao productDao();
}

AppDatabase appDatabase = Room.databaseBuilder(this, AppDatabase.class, “product.db”).build();
ProductDao productDao = appDatabase.productDao();

List allProducts = productDao.getAllProducts();

productDao.insertProduct(productEntity);

每个 entity 都代表了一张表,其中的字段代表表中的一列。注解处理器会自动生成 AppDatabaseProductDao 对应的实现类 AppDatabase_ImplProductDao_Impl。可以通过调用Room.databaseBuilder()Room.inMemoryDatabaseBuilder()在运行时获取Database实例,但要注意,实例化 RoomDatabase 是相当昂贵的,最好按照单例模式只创建一个Database实例。

定义 Entity

为了让 Room 可以访问 entity,entity 中的字段必须是 public 的,或者提供了getter/setter方法。默认情况下,Room 会将 entity 中的每个字段作为数据库表中一列,如果你不想持久化某个字段,可以使用 @Ignore 注解。默认数据库表名为 entity 类名,你可以通过 @Entity 注解的 tableName 属性 更改,默认列名是字段名,你可以通过 @ColumnInfo 注解更改。

主键

每个 entity 必须至少有一个字段作为主键(primary key),即使该 entity 只有一个字段。使用 @PrimaryKey 注解来指定主键,如果你希望 SQLite 帮你自动生成这个唯一主键,需要将 @PrimaryKeyautoGenerate 属性设置成 true,不过需要改列是 INTEGER 类型的。如果字段类型是 longintInsert 方法会将 0 作为缺省值,如果字段类型是 IntegerLong 类型,Insert 方法会将 null 作为缺省值。
如果 entity 的主键是复合主键(composite primary key),你就需要使用 @Entity 注解的 primaryKeys 属性定义这个约束,如:

@Entity(primaryKeys = {“firstName”, “lastName”})
class User {
public String firstName;
public String lastName;
public String avatar;
}

索引

有些时候,我们需要添加索引以加快查询速度,可以使用 @Entity 注解的 indices 属性创建索引,如果某个字段或字段组是唯一的,可以将 @Index 注解的 unique 属性设置为 true 来强制这个唯一性,如:

@Entity(indices = {@Index(value = {“first_name”, “last_name”},
unique = true)})
class User {
@PrimaryKey
public int id;

@ColumnInfo(name = “first_name”)
public String firstName;

@ColumnInfo(name = “last_name”)
public String lastName;

@Ignore
Bitmap picture;
}

关系

SQLite 是关系型数据库,很多时候我们需要指定对象间的关系。即使大多数 ORM 库允许实体类对象间相互引用,但 Room 明确禁止这样做。因为级联查询不能发生在 UI 线程,UI 线程只有 16 ms 时间计算和绘制布局,所以

你可能感兴趣的:(程序员,android,jvm)