Android --Room入门分析与学习

Room

Room 持久性库在 SQLite 的基础上提供了一个抽象层,让用户能够在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制

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层来摆脱,繁琐的数据库操作,包括创建、更新数据库、表以及进行增删查改等)


另外多说一句,就个人而言,androidx包一定会成为主流,来替代各种版本的support包,所以如果你还没有使用上androidx,那么请早些使用。

首先我们先搞清楚为什么学习room

1.先看jetpack的框架

在这里插入图片描述



在这里插入图片描述





2. 再看官方文档的说明.

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

处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的用例是缓存相关数据。这样,当设备无法访问网络时,用户仍可在离线状态下浏览相应内容。设备之后重新连接到网络后,用户发起的所有内容更改都会同步到服务器。

由于 Room 负责为您处理这些问题,因此我们强烈建议您使用 Room(而不是 SQLite)。


3. jetpack学习的必要

JetPack更多是一种概念和态度。相当于Google把自己的Android生态重新整理了一番。确立了Android未来的版图和大方向。

JetPack里目前包含的内容,未来也会是Google大力维护和扩展的内容。对应开发者来说也是值得去学习使用的且相对无后顾之忧的。JetPack里没有的,除开一些优秀的第三方库,未来应该也会慢慢被新的API替代,逐渐边缘化,直至打上Deprecate注解。

以当下的环境来说,要开发出一个完全摆脱JetPack的APP是很难做到的。但是反过来讲JetPack也远远没有到成熟的地步,目前也还存在亟待解决的问题,未来可以做的事情还有很多。

关于使用的话,并不是所有库都建议使用,因为目前还有很多库在alpha版本。但是作为学习还是很有必要的,能给你日常的开发中多提供一些思路,这些是无可厚非的。

总的来说,JetPack的推广对广大开发者而言是利远远大于弊的。


Room 包含 3 个主要组件:

Entity(实体)

Dao(访问数据库操作的一个接口

Database(数据库的实际操作)

  • 数据库:包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。

    使用 @Database 注释的类应满足以下条件:

    • 是扩展 RoomDatabase 的抽象类。
    • 在注释中添加与数据库关联的实体列表。
    • 包含具有 0 个参数且返回使用 @Dao 注释的类的抽象方法。

    在运行时,您可以通过调用 [Room.databaseBuilder()](https://developer.android.google.cn/reference/androidx/room/Room?hl=zh_cn#databaseBuilder(android.content.Context, java.lang.Class, java.lang.String)) 或 [Room.inMemoryDatabaseBuilder()](https://developer.android.google.cn/reference/androidx/room/Room?hl=zh_cn#inMemoryDatabaseBuilder(android.content.Context, java.lang.Class)) 获取 Database 的实例。

  • Entity:表示数据库中的表。

  • DAO:包含用于访问数据库的方法。

应用使用 Room 数据库来获取与该数据库关联的数据访问对象 (DAO)。然后,应用使用每个 DAO 从数据库中获取实体,然后再将对这些实体的所有更改保存回数据库中。最后,应用使用实体来获取和设置与数据库中的表列相对应的值。

Room 不同组件之间的关系如图 所示:

img

Room 具有以下注解处理器选项:

  • room.schemaLocation:配置并启用将数据库架构导出到给定目录中的 JSON 文件的功能。
  • room.incremental:启用 Gradle 增量注解处理器。
  • room.expandProjection:配置 Room 以重写查询,使其顶部星形投影在展开后仅包含 DAO 方法返回类型中定义的列。
   android {
        ...
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [
                        "room.schemaLocation":"$projectDir/schemas".toString(),
                        "room.incremental":"true",
                        "room.expandProjection":"true"]
                }
            }
        }
    }
    


room在jetpack中的位置

在这里插入图片描述

新建简单案例进行理解

1. 首先需要添加依赖

声明依赖项

要添加 Room 的依赖项,您必须将 Google Maven 代码库添加到项目中。

在应用或模块的 build.gradle 文件中添加所需工件的依赖项:

    dependencies {
      def room_version = "2.2.0-rc01"

      implementation "androidx.room:room-runtime:$room_version"
      annotationProcessor "androidx.room:room-compiler:$room_version" 
       // For Kotlin use kapt instead of annotationProcessor
             }

以下内容为Kotlin的内容,可以不添加,那样就减少下载库的量,会等的时间更短

----------------------------------------------------------------------------------------------------

      // optional - Kotlin Extensions and Coroutines support for Room
      implementation "androidx.room:room-ktx:$room_version"

      // optional - RxJava support for Room
      implementation "androidx.room:room-rxjava2:$room_version"

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

      // Test helpers
      testImplementation "androidx.room:room-testing:$room_version"

2.创建实体类 Word

@Entity  //进行注解操作,绝对不能少


public class Word {

    //这个是设置主键,让他自动生成,自动递增id进行标号
    @PrimaryKey(autoGenerate = true)
    private int id;

/************************只能英文************************/
    //@ColumnInfo以你写的作为记忆,如果你不写的话,他会以你的变量名称word作为记忆
    @ColumnInfo(name = "english_word")
    private String word;
    @ColumnInfo(name = "chinese_meaning")
    private String chineseMeaning;

    /*************第二步,重写方法,id不用重写,因为他是主键,是自动生成的*********/

    public Word(String word, String chineseMeaning) {
        this.word = word;
        this.chineseMeaning = chineseMeaning;
    }
    /********************第三步,重写方get,set方法,id可以写**********************/
    public String getWord() {
        return word;
    }

    public void setWord(String word) {
        this.word = word;
    }

    public String getChineseMeaning() {
        return chineseMeaning;
    }

    public void setChineseMeaning(String chineseMeaning) {
        this.chineseMeaning = chineseMeaning;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

3. 创建抽象类 WordDao (Interface)

 //进行注解操作,绝对不能少
@Dao    //访问数据库操作的一个接口


//所有数据库的操作都要在里面进行
public interface WordDao {


    /*****************************修饰词的意义是,编译的时候会给我们生成代码***************/
    @Insert
    //允许传递多个数,如果一个的话,他是Word word ,  多个的话是Word ...words
    void insertWords(Word... words);

    @Update
        //当你定义int  update时,他会给你回复你修改了几个结果
    void update(Word... words);

    @Delete
    void delete(Word... words);

    @Query("DELETE FROM WORD")
        //这是清空全部
    void deletall();

    @Query("SELECT*FROM WORD ORDER BY ID DESC")
        //降序排列,表示最新的值将放在最前面
    List<Word> getall();
}

4. 创建WordDatabase 声明为抽象,并且继承自自己的父类RoomDatabase。(Abstract)

//entity 实体,如果有多个,要用  , 分割开,第二个是版本
@Database(entities = {Word.class},version = 1,exportSchema = false) //进行注解操作,绝对不能少
public abstract class WordDatabase extends RoomDatabase {
    //如果有多个Entity 应该写多个Dao
    public abstract WordDao getWordDao();
}

5. 进行测试,查看效果

public class MainActivity extends AppCompatActivity {

    WordDatabase wordDatabase;
    WordDao wordDao;
    Button buttoninsert, buttonupdate, buttondelte, buttondelteall;
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //第三个第数据库名称
        //  wordDatabase= 
        Room.databaseBuilder(this,WordDatabase.class,"shujvkumingcheng").build();
        //.allowMainThreadQueries()强制在主线程执行,这个是错误的,应该是上一个语句才是正确,但是因         为为了看效果,所以简单的过一下
        wordDatabase = Room.databaseBuilder(this, WordDatabase.class,       "shujvkumingcheng").allowMainThreadQueries().build();
        wordDao = wordDatabase.getWordDao();

        //添加数据
        textView = findViewById(R.id.textView);
        buttoninsert = findViewById(R.id.buttoninsert);
        buttoninsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Word word1 = new Word("zhang", "张");
                Word word2 = new Word("qian", "前");
                wordDao.insertWords(word1, word2);
                updateView();
            }
        });
        
        //删除数据
        buttondelte = findViewById(R.id.buttondelterone);
        buttondelte.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //这里的里面设置什么都行,因为是依靠主键删除
                Word word=new Word("1","2");
                word.setId(27);
              wordDao.delete(word);
              updateView();
            }
        });
        
        buttondelteall = findViewById(R.id.buttondelterAll);
        buttondelteall.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                wordDao.deletall();
                updateView();
            }
        });
        
        //更新数据
        buttonupdate = findViewById(R.id.buttonupdate);
        buttonupdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Word word = new Word("aaa", "A");
                word.setId(25);
                wordDao.delete(word);
                updateView();
            }
        });

        updateView();
    }

    //显示数据集合
    void updateView() {
        List<Word> list = wordDao.getall();
        String text = "";
        for (int i = 0; i < list.size(); i++) {
            Word word = list.get(i);
            text = text + word.getId() + word.getWord() + "----" +    			word.getChineseMeaning() + "\n";
        }
        textView.setText(text);
    }
}

发布了1 篇原创文章 · 获赞 1 · 访问量 73

猜你喜欢

转载自blog.csdn.net/qq_45056715/article/details/105034139