Room Database完全使用手册

栏目: 数据库 · 发布时间: 5年前

内容简介:Android数据持久层直接使用SQLite很麻烦,Google官方推出了Room, Google对Room的定义: The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. Room是SQLite之上的一个抽象层,通过Room层来摆脱,繁琐的数据库操作,包括创建、更新数据库、

Android数据持久层直接使用 SQLite 很麻烦,Google官方推出了Room, Google对Room的定义: The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. Room是SQLite之上的一个抽象层,通过Room层来摆脱,繁琐的数据库操作,包括创建、更新数据库、表以及进行增删查改等。

Room数据库结构

如下图,Room数据库包含三个对象:

1、Entity: 对应数据库中的表,可以使用Entity注解将一个类变成数据库中的一张表结构。

2、DAO: 全称Database Access

Object,定义了对数据库中数据的读写等操作,DAO中可以使用 SQL 语句来操作数据库。

3、RoomDatabase: 数据库持有类,用于创建数据库或者连接到数据库。内部包含DAO和Entity。

Room Database完全使用手册

上面总体说了Room数据库的三个对象,下面分别介绍三个对象的作用和使用方法。

Entity

Room Database中的Entity表示一张数据表结构,一个Entity实例就是表中的一行,如定义一个Person类的Entity。

@Entity
public class Person{
    @PrimaryKey
    public int id;
    public String firstName;
    public String lastName;
}
复制代码

当有两个Person对象在表中时,表中的数据如下:

Room Database完全使用手册

其中Person和Entity及数据库的关系如下所示:

Room Database完全使用手册

重点:

1、一个Entity对象代表数据表中的一行,一个Entity类代表一张数据表。

2、Entity中的成员变量都是数据表中的列。

3、一个 Java 类定义成Entity只要加上Entity注解就可以了。

Entity的使用

1、定义一个Entity

@Entity(tableName = "person_table")
public class Person{
    @PrimaryKey
    public int id;

    public String firstName;
    public String lastName;
}
复制代码

如果想给Entity命名可以在@Entity注解的后面加上 (tableName = "person_table") ,如果不加会使用默认命名,上面的id,firstName, lastName都定义成了public类型,是为了数据库能够有操作这些数据的权限,也可以选择将这些都设置成private类型,然后通过setter和getter来操作。

2、定义主键

每一个Entity至少定义一个主键(primary key),哪怕Entity中只有一个变量也要将这个变量定义为主键,在Room数据库中使用注解 @PrimaryKey 来定义主键,@PrimaryKey 的使用方式有两种一种是在类变量前面加,如果主键比较复杂可以加在@Entity注解的后面。

@Entity(primaryKeys = {"firstName", "lastName"})
public class User {
    public String firstName;
    public String lastName;
}
复制代码

3、改变属性列名

和改变表名称tableName一样,可以改变表中的列名称,使用 @ColumnInfo来改变列的名称。如果不改的话默认使用变量名的小写形式。

@Entity(tableName = "person_table")
public class Person {
    @PrimaryKey
    public int id;

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

    @ColumnInfo(name = "last_name")
    public String lastName;
}
复制代码

4、使某些变量不生成数据表中的字段

由上面可知当一个类前加了Entity注解后类中的所有成员变量都会生成表中的属性列,如果我们不希望某个变量生成表中的属性列,可以使用注解 @Ignore。

@Entity
public class Person {
    @PrimaryKey
    public int id;
    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}
复制代码

如果有类继承上面的Person类,并且不想picture生成数据表中的列,那么可以ignoredColumns

@Entity(ignoredColumns = "picture")
public class RemotePerson extends Person {
    @PrimaryKey
    public int id;

    public boolean hasVpn;
}
复制代码

5、两个数据表关联

SQLite是关系数据库,可以明确两个对象间的关系,大多数的关系数据库都可以指定表之间的关联,但是Room数据库不能够之间指定两个表之间的关系,但是可以通过@ForeignKey注解来进行表的关联。

@Entity(foreignKeys = @ForeignKey(entity = Person.class,
                                  parentColumns = "id",
                                  childColumns = "user_id"))
public class Book {
    @PrimaryKey
    public int bookId;

    public String title;

    @ColumnInfo(name = "user_id")
    public int userId;
}
复制代码

6、嵌套Entity

如果定义的Entity类里面有个对象,并且希望定义的Entity中的表列字段包含Entity类对象中的变量,可以在Entity类对象中加@Embedded标注。

public class Address {
    public String street;
    public String state;
    public String city;

    @ColumnInfo(name = "post_code")
    public int postCode;
}

@Entity
public class Person{
    @PrimaryKey
    public int id;

    public String firstName;

    @Embedded
    public Address address;
}
复制代码

这样Person表中的列字段有 id, firstName, street, state, city,和 post_code.

DAO

在DAO(data access object)中,可以使用SQL语句进行对数据库的操作并且将这些语句与Java中方法关联调用,编译器会检查SQL语句并且通过注解生成对应的查询语句,例如@Insert。

注意:

1、DAO必现是抽象类或者接口

2、所有的查询语句必须在单独的线程里面执行。

Room Database完全使用手册

DAO的使用

可以使用sql中的语句来实现DAO的操作。

1、插入数据

当在方法前使用@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 方法只插入一个参数时,插入会返回long数据代表插入的对象在数据表中的行号,当插入一个数组或者集合形式的数据时,会返回long数组或者集合。 2、更新数据

@Update标注的方法会查找表中与所给数据主键一样的数据进行更新。

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

3、查询数据

@Query 标注的查询方法是使用最多的方法,每个查询方法在编译期间就会被验证是否正确,如果错误就会报错,不会在运行时再提示失败。在

@Dao
public interface MyDao {
    @Query("SELECT * FROM user")
    public User[] loadAllUsers();
}
复制代码

如果存在查询语法错误,或者数据库中不存在user表,Room数据库会在编译时提示错误信息。 也可以使用SQL语句实现复杂的查询

@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);
}
复制代码

4、查询列表中的数据并返回子列表

有时候并不需要将查询数据的所有字段都返回,大部分时候只需要返回查询数据的一个子域。下面实现返回查询的一个子域。

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();
}
复制代码

RoomDatabase

上面已经介绍了DAO和Entity,Entity定义表,DAO定义对表中数据进行操作,RoomDatabase包含了DAO,并且提供创建和连接数据库的方法。

Room Database完全使用手册

创建Room database

创建Room database包括三个步骤: 1、创建继承RoomDatabase的抽象类。

2、在继承的类前使用注解@Database。

3、申明数据库结构的Entity,并且设置数据库的版本号。

@Database(entities = {Word.class}, version = 1)//申明Entity和数据库的版本号
public abstract class WordRoomDatabase 
                      extends RoomDatabase { 
   public abstract WordDao wordDao();//创建DAO的抽象类

   private static WordRoomDatabase INSTANCE;//创建单例
   
   static WordRoomDatabase getDatabase(final Context context) {
 		 if (INSTANCE == null) {
    			synchronized (WordRoomDatabase.class) {
      			if (INSTANCE == null)    {
       				    INSTANCE = Room.databaseBuilder(
						context.getApplicationContext(),
						WordRoomDatabase.class, "word_database")
						.addCallback(sOnOpenCallback)
						.fallbackToDestructiveMigration()
						.build();                
      			}
      		}
      }
  return INSTANCE;}

private static RoomDatabase.Callback sOnOpenCallback =
  new RoomDatabase.Callback(){
	@Override
	public void onOpen (@NonNull SupportSQLiteDatabase db){
		super.onOpen(db);
		initializeData();
	}};

}
复制代码

注意: 1、编译时会检查SQL语句是否正确

2、不要在主线程中进行数据库操作

3、RoomDatabase最好使用单例模式

最后上一张Android在使用Room数据库时和Room数据库交互的图

Room Database完全使用手册

application从RoomDatabase中获取DAO实例,并且通过DAO中定义的方法来操作数据库中Entity。获取设置entity的数据。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

让云落地

让云落地

【美】Michael J. Kavis(迈克尔 J.凯维斯) 著 / 陈志伟、辛敏 / 电子工业出版社 / 2016-3 / 65.00元

云计算落地已成事实。从前几年的概念普及,到如今越来越多的企业将业务迁移至云上,云计算正在改变整个社会的信息资源使用观念和方式。云计算还在不断成长,技术细节也在不断变化之中。对于使用者而言,能够基于自身的业务、技术和组织需求等各方面情况,选择正确的云服务模式,是成功使用云计算最关键的技术决策之一。 《让云落地:云计算服务模式(SaaS、PaaS和IaaS)设计决策》共有 16 章,作者有意避开......一起来看看 《让云落地》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具