福建师范大学Android Room 技术浅谈

福建师范大学Android Room 技术浅谈

## 前提告知该文章是用作课程评分,本文内容虽为原创,但也有参考。

1.Room的背景简介

处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的使用场景是缓存相关的数据,这样一来,当设备无法访问网络时,用户仍然可以在离线状态下浏览该内容。

Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。

2.Room的优点

  • 使用编译时注解,能够对@Query和@Entity里面的SQL语句等进行验证;
  • 与SQL语句的使用更加贴近,能够降低学习成本,提交开发效率,减少模板代码;
  • @Embedded 能够减少表的创建;
  • 对LiveData、Kotlin Coroutines的支持

3.Room三大组件

1.Database: 可以使用此组件创建数据库 holder,注释定义实体列表,和类的内容定义数据访问对象(DAO)数据库中的表。它也是基本连接的主要访问点。
2.Entity: 实体类对象模型,一般对应表结构。实体的每个字段在数据库中都是保存的,除非你用@Ignore 注解。
3.DAO:全称Database Access Object,定义了对数据库中数据的读写等操作,DAO中可以使用SQL语句来操作数据库。

4.android Room 依赖的配置

在build.gradle 文件的 dependencies添加一下代码:

    implementation fileTree(dir:'libs',include:['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.room:room-common:2.3.0'
    implementation 'androidx.room:room-runtime:2.3.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:esprsso-core:3.2.0'
    implementation 'com.google.andrid.material:material:1.1.0'
    implementation 'andrid.arch.presistence.room:runtime:1.1.1'
    annotationProcessor 'andrid.arch.presistence.room:compiler:1.1.1'
    annotationProcessor 'androidx.room:room-compiler:2.3.0'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HvvSwCVZ-1670507203385)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

5.1Entity(创建表)

@Entity(tableName = "table_name")
public class MainData implements Serializable {
    //创建ID列
    @PrimaryKey(autoGenerate = true)
    private  int ID;
    //创建下一列
    @ColumnInfo(name = "text")
    private String text;
    //生成getter和setter

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i7gB8tq1-1670507203387)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

5.2Dao

@Dao
public interface MainDao {
    //插入语句
    @Insert(onConflict = REPLACE)
    void insert(MainData mainData);

    //删除语句
    @Delete
    void delete(MainData mainData);

    //删除全部的语句
    @Delete
    void reset(List<MainData> mainData);

    //更新语句
    @Query("UPDATE table_name SET text= :sText WHERE ID = :sID" )
    void update(int sID,String sText);

    //查询所有数据
    @Query("select * from table_name")
    List<MainData> getAll();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AZrWnSFi-1670507203388)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

在这个里面定义了,对应数据库的操作。

@Insert@Delete@Update@Query 代表我们常用的插入、删除、更新、查询数据库操作。

@Query非常的强大,你可以编写任意sql语句并得到你想要的结果。

5.3DataBase

// 添加数据库 实体
@Database(entities = {MainData.class}, version = 1,exportSchema = false)
public abstract class RoomDB extends RoomDatabase{
    //创建 数据库 实例
    private  static RoomDB database;
    //定义数据库的名字
    private static String DATABSAE_NAME="database";
    public synchronized static RoomDB getInstance(Context context){
        //检测状态
        if(database==null){
            //数据库为空时就初始化数据库
            database = Room.databaseBuilder(context.getApplicationContext(),
                    RoomDB.class,DATABSAE_NAME).allowMainThreadQueries()
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return database;
    }

    //创建Dao
    public abstract MainDao mainDao();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmTccfjK-1670507203389)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

这里运用到数据库单例模式,下面会仔细讲讲为什么把数据库写成单例。

5.4单例模式简单介绍

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例模式有两种:饿汉式懒汉式

我使用的是懒汉式,这里先说一下饿汉式与懒汉式的区别:

饿汉式:类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了。

懒汉式:懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。

在线程安全上:

饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,

懒汉式本身是非线程安全的,为了实现线程安全有几种写法。

在资源加载和性能上:

饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成。

而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。

可以发现,两者各有缺点和优点,因为我自己写的是一个小案例,涉及不到多线程,所以就用的懒汉式模式。

6.使用

​ 1.注意事项:需要在工作线程中使用,否则耗时操作将会导致Application崩溃

​ 2.获取数据库

 //数据库变量赋值
 database = RoomDB.getInstance(this);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PQW1FF4U-1670507203389)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

​ 3.更新数据

String uText = editText.getText().toString().trim();
//更新数据库数据
database.mainDao().update(sID,uText);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pnbWX7mE-1670507203390)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

​ 4.插入数据

MainData data = new MainData();
data.setText(sText);
database.mainDao().insert(data);
//清空 edit text
editText.setText("");

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWIl2gDS-1670507203391)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

7.效果展示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7TcTrO3B-1670507203392)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]编辑

8.源码

肖学良
t.setText(“”);


[外链图片转存中...(img-JWIl2gDS-1670507203391)]

##  7.效果展示

![img](https://img-blog.csdnimg.cn/9cad2a3538bf4b1c8d9ed3e00b46826b.gif)[外链图片转存中...(img-7TcTrO3B-1670507203392)]编辑

##  8.源码
肖学良
https://download.csdn.net/download/weixin_53445186/87218017

你可能感兴趣的:(Android,android)