欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Room SQLite持久层框架

程序员文章站 2022-05-14 13:05:12
...

原文链接

前言

Android中提供了SQLite数据库进行数据的持久化 ,并提供了对应API访问数据库,而Room框架提供了SQLite数据访问抽象层,为高效的数据库访问层带来便捷

APP可以缓存用户数据,当APP离线时便从SQLite读取数据,当重新连线时即可完成和服务器数据的同步

谷歌官方强烈推荐使用Room框架操作SQLite数据库

Room SQLite持久层框架

Hello World

首先在build.gradle中添加必要依赖

dependencies {
    def room_version = "1.1.1"

    implementation "android.arch.persistence.room:runtime:$room_version"
    annotationProcessor "android.arch.persistence.room:compiler:$room_version" // use kapt for Kotlin

    // optional - RxJava support for Room
    implementation "android.arch.persistence.room:rxjava2:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "android.arch.persistence.room:guava:$room_version"

    // Test helpers
    testImplementation "android.arch.persistence.room:testing:$room_version"
}

创建实体类User,@Entity表示该类对应数据库中的表,@ColumnInfo后面的name属性对应数据库中的字段名,并实现该实体类的GetterSetter方法

@Entity
public class User {
    @PrimaryKey
    private int uid;

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

    @ColumnInfo(name = "last_name")
    private String lastName;

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

创建实体类对应的daoUserDao,完成User的增删改查(CRUD)接口定义,@Dao注解定义一个dao层,参数赋值(传递)使用:clumn_name进行赋值


@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(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(User... users);

    @Delete
    void delete(User user);
}

创建AppDatabase@Database注解表示这是一个数据库操作类,entities对应Entity实体类,version用于数据库版本升级,并在该抽象类中定义一个返回dao层的抽象方法

@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

初始化用于操作数据库的实例对象AppDatabase,需要注意的是不能在主线程中初始化,必须新开启一个线程进行初始化,否则会报错,或者无法创建数据库

new Thread(new Runnable() {
    @Override
    public void run() {
        AppDatabase db = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class, "database-name").build();
    }
}).start();

测试

增加,也可以传一个User数组


for (int i = 0; i < 10; i++) {
    User user = new User();
    user.setUid(i);
    user.setFirstName("Shell" + i);
    user.setLastName("Hub" + i);
    insertAll(db, user);
}

如果报以下错误,修改dao层的注解为@Insert(onConflict = OnConflictStrategy.REPLACE)

android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: User.uid (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)

查询所有数据

for (User user : db.userDao().getAll()) {
    System.out.println(user);
}

other…

Room单例模式

最好使用设计模式中的单例模式获取数据库实例,因为每次获取数据库实例都很耗时并且耗内存,我们可以自定义一个类继承Application并定义一个public static方法获取数据库实例


public class App extends Application {
    private static Context context;
    private static final String DATABASE_NAME = "SHELLHUB";
    private static AppDatabase DB_INSTANCE;
    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();

        new Thread(new Runnable() {
            @Override
            public void run() {
                DB_INSTANCE = Room.databaseBuilder(getApplicationContext(),
                        AppDatabase.class, DATABASE_NAME).build();

            }
        }).start();
    }

    public static AppDatabase getDB() {
        return DB_INSTANCE;
    }
}