• Android-第十三节04Room框架详解



    一、Room概述

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

    • 针对 SQL 查询的编译时验证。
    • 可最大限度减少重复和容易出错的样板代码的方便注解。
    • 简化了数据库迁移路径。
      出于这些方面的考虑,我们强烈建议您使用 Room,而不是直接使用 SQLite API。

    Room 包含三个主要组件:

    • 数据库类:用于保存数据库并作为应用持久性数据底层连接的主要访问点。
    • 数据实体:用于表示应用的数据库中的表。
    • 数据访问对象 (DAO):提供您的应用可用于查询、更新、插入和删除数据库中的数据的方法。
      数据库类为应用提供与该数据库关联的 DAO 的实例。反过来,应用可以使用 DAO 从数据库中检索数据,作为关联的数据实体对象的实例。此外,应用还可以使用定义的数据实体更新相应表中的行,或者创建新行供插入。图 1 说明了 Room 的不同组件之间的关系。
      在这里插入图片描述

    二、Room的使用

    1.添加依赖

    在这里插入图片描述

    dependencies {
        // Room
        implementation "androidx.room:room-runtime:2.2.5"
        annotationProcessor "androidx.room:room-compiler:2.2.5"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.创建实体类

    1.创建User类
    在这里插入图片描述

    在这里插入图片描述

    public class User {
        public int id;
        public int age;
        public String name;
        public String phone;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.添加注解

    • 默认情况下,Room 将类名称用作数据库表名称。如果您希望表具有不同的名称,请设置 @Entity 注解的 tableName 属性。
    • 同样,Room 默认使用字段名称作为数据库中的列名称。如果您希望列具有不同的名称,请将 @ColumnInfo 注解添加到该字段并设置 name 属性。
    • 每个 Room 实体都必须定义一个主键,用于唯一标识相应数据库表中的每一行。执行此操作的最直接方式是使用 @PrimaryKey 为单个列添加注解(注意:如果您需要 Room 为实体实例分配自动 ID,请将 @PrimaryKey 的 autoGenerate 属性设为 true。
    • 默认情况下,Room 会为实体中定义的每个字段创建一个列。 如果某个实体中有您不想保留的字段,则可以使用 @Ignore 为这些字段添加注解,

    在这里插入图片描述

    3.创建数据访问对象 (DAO)

    当您使用 Room 持久性库存储应用的数据时,您可以通过定义数据访问对象 (DAO) 与存储的数据进行交互。每个 DAO 都包含一些方法,这些方法提供对应用数据库的抽象访问权限。在编译时,Room 会自动为您定义的 DAO 生成实现。

    通过使用 DAO(而不是查询构建器或直接查询)来访问应用的数据库,您可以使关注点保持分离,这是一项关键的架构原则。DAO 还可让您在测试应用时更轻松地模拟数据库访问。

    您可以将每个 DAO 定义为一个接口或一个抽象类。对于基本用例,您通常应使用接口。无论是哪种情况,您都必须始终使用 @Dao 为您的 DAO 添加注解。DAO 不具有属性,但它们定义了一个或多个方法,可用于与应用数据库中的数据进行交互。
    以下代码是一个简单 DAO 的示例,它定义了在 Room 数据库中插入、删除和选择 User 对象的方法:

    在这里插入图片描述

    import androidx.room.Dao;
    import androidx.room.Delete;
    import androidx.room.Insert;
    import androidx.room.Query;
    
    import java.util.List;
    
    @Dao
    public interface UserDao {
        @Insert
        void insertAll(User user);
    
        @Delete
        void delete(User user);
    
        @Query("SELECT * FROM users")
        List getAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.创建数据库类(Database)

    以下代码定义了用于保存数据库的 AppDatabase 类。 AppDatabase 定义数据库配置,并作为应用对持久性数据的主要访问点。数据库类必须满足以下条件:

    • 该类必须带有 @Database 注解,该注解包含列出所有与数据库关联的数据实体的 entities 数组。
    • 该类必须是一个抽象类,用于扩展 RoomDatabase。
    • 对于与数据库关联的每个 DAO 类,数据库类必须定义一个具有零参数的抽象方法,并返回 DAO 类的实例。

    在这里插入图片描述

    import androidx.room.Database;
    import androidx.room.RoomDatabase;
    
    @Database(entities = User.class,version = 1)
    public abstract class UserDatabase extends RoomDatabase {
        public abstract UserDao getUserDao();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.使用

    Database的初始化需要先使用Room.databaseBuilder方法,这个方法几个参数:

    AppDatabase db = Room.databaseBuilder(getApplicationContext(),
            AppDatabase.class, "database-name").build();
    
    • 1
    • 2
    • 参数一:context,我们可以使用Application
    • 参数二:Class,即我们定义的Database的class
    • 参数三:name, 这个参数表示的就是数据库的名字

    Room.databaseBuilder方法生成的RoomDatabase.Builder对象调用build方法就生成了AppDatabase对象

    然后,您可以使用 AppDatabase 中的抽象方法获取 DAO 的实例,转而可以使用 DAO 实例中的方法与数据库进行交互:

    UserDao userDao = db.userDao();
    List users = userDao.getAll();
    
    • 1
    • 2

    在这里插入图片描述

    三、Room(增删改查)

    3.1增加数据

    1.在Dao层写增加的方法
    以下代码展示了将一个或多个 User 对象插入数据库的有效 @Insert 方法示例:

    @Dao
    public interface UserDao {
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        public void insertUsers(User... users);
    
        @Insert
        public void insertBothUsers(User user1, User user2);
    
        @Insert
        public void insertUsersAndFriends(User user, List friends);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    @Insert 方法的每个参数必须是带有 @Entity 注解的 Room 数据实体类的实例或数据实体类实例的集合。调用 @Insert 方法时,Room 会将每个传递的实体实例插入到相应的数据库表中。

    如果 @Insert 方法接收单个参数,则会返回 long 值,这是插入项的新 rowId。如果参数是数组或集合,则该方法应改为返回由 long 值组成的数组或集合,并且每个值都作为其中一个插入项的 rowId。

    在这里插入图片描述

    2.在main方法中调用
    在这里插入图片描述

            findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    User user=new User();
                    user.name="小冯";
                    user.age=20;
                    user.phone="123456789";
                    userDao.insertAll(user);
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果:
    在这里插入图片描述
    在这里插入图片描述

    3.2删除数据

    1.在Dao层中写删除方法

    借助 @Delete 注释,您可以定义从数据库表中删除特定行的方法。与 @Insert 方法类似,@Delete 方法接受数据实体实例作为参数。 以下代码展示了一个 @Delete 方法示例,尝试从数据库中删除一个或多个 User 对象:

    @Dao
    public interface UserDao {
        @Delete
        public void deleteUsers(User... users);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    2.在main方法中调用
    在这里插入图片描述

            findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    User user=new User();
                    user.id=1;
                    userDao.delete(user);
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    运行结果:
    在这里插入图片描述

    3.3更新数据

    1.在Dao层中写更新方法
    借助 @Update 注释,您可以定义更新数据库表中特定行的方法。与 @Insert 方法类似,@Update 方法接受数据实体实例作为参数。 以下代码展示了一个 @Update 方法示例,该方法尝试更新数据库中的一个或多个 User 对象:

    @Dao
    public interface UserDao {
        @Update
        public void updateUsers(User... users);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Room 使用主键将传递的实体实例与数据库中的行进行匹配。如果没有具有相同主键的行,Room 不会进行任何更改。

    @Update 方法可以选择性地返回 int 值,该值指示成功更新的行数。

    2.在main方法中调用
    在这里插入图片描述

            findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    User user=new User();
                    user.id=4;
                    user.name="xiao冯";
                    user.age=22;
                    user.phone="1111111";
                    userDao.update(user);
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果:
    在这里插入图片描述

    3.4查询数据

    查询全部数据

    1.在Dao层中写查询方法
    使用 @Query 注解,您可以编写 SQL 语句并将其作为 DAO 方法公开。使用这些查询方法从应用的数据库查询数据,或者需要执行更复杂的插入、更新和删除操作。

    Room 会在编译时验证 SQL 查询。这意味着,如果查询出现问题,则会出现编译错误,而不是运行时失败。

    @Query("SELECT * FROM user")
    public User[] loadAllUsers();
    
    • 1
    • 2

    在这里插入图片描述
    2.在main方法中调用

    在这里插入图片描述

            findViewById(R.id.button4).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    List userList=userDao.findAllUser();
                    for (User user:userList){
                        Log.i("Usertag","id:   "+user.id+"    name:"+user.name+"   电话号:"+user.phone);
                    }
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行结果:
    在这里插入图片描述

    查询单个数据(根据主键查询)

    1.增加布局控件
    在这里插入图片描述

    
    
        

    2.增加Dao层方法
    在这里插入图片描述

        @Query("SELECT * FROM users where id= :userId")
        List findUserById(int userId);
    
    • 1
    • 2

    3.在main方法中调用

    在这里插入图片描述

     EditText editText=findViewById(R.id.editTextTextPersonName);
            findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    List userList=userDao.findUserById(Integer.parseInt(String.valueOf(editText.getText())));
                    for (User user:userList){
                        Log.i("Usertag","id:   "+user.id+"    name:"+user.name+"   电话号:"+user.phone);
                    }
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果:
    在这里插入图片描述

    Room框架入门基本上就已经讲完了,更多详情请参考官方文档 Room 官方文档

  • 相关阅读:
    E. Cross Swapping(并查集变形/好题)
    win10连接远程服务访问文件提示:文件共享不安全,不能连接文件共享
    大二学生基于Html+Css+javascript的网页制作——动漫设计公司响应式网站模板 (10个页面)
    Java学习笔记整理总结:Spring+tomcat+Kafka+多线程面试笔记
    【不规范bug注意】2023.9.26
    SpringBoot整合Shiro环境搭建与配置拦截器
    13.Python模块与包
    你是否还记得有一款游戏叫做“魔塔”?
    说说Flink双流join
    【网络】OSI七层模型,HTTP、Cookie和Session、GET和POST,HTTPS
  • 原文地址:https://blog.csdn.net/qq_48435252/article/details/126000028