使用 Room 操作 SQLite (Android 开发)

使用 Room 操作 SQLite (Android 开发)

  • 总结放在前面

    • 现在还没有学过数据库,说一下我自己的理解

    • Room 可以把类的对象存储到数据库中

    • 每一个对象就是一行(row),对象中被存储的属性就是列(column)

    • 行 : 对象 列:属性属性1属性 2
      对象 1(PrimaryKey)对象 1 的属性1 的值对象 1 的属性2的值
      对象 2(PrimaryKey)对象 2 的属性1 的值对象 2的属性2 的值
    • 这样就组成一张表,一张表就是一个数据库

    • 要操作这个数据库就使用 Dao 中的方法来增查删改

如需在应用中使用 Room,请将以下依赖项添加到应用的 build.gradle 文件

dependencies {
  def room_version = "2.2.6"

  implementation "androidx.room:room-runtime:$room_version"
  annotationProcessor "androidx.room:room-compiler:$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"

  // optional - Test helpers
  testImplementation "androidx.room:room-testing:$room_version"
}
  • Room 的三个组件

    • Database : 数据库holder,持有者
    • Data entities : 数据实体,要存储的类
    • Data access objects ( DAOs ) :数据库访问方法
  • 三个组件之间的关系

    • 开发者使用 DAO的方法 将 Data entities的对象 放入 Database
    • 下面这个图为谷歌官方图(一坨 shit)
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-816fXoI4-1612184598904)(image-20210131113357612.png)]
  • 使用例子(Sample)

    1. 定义Data entity , Data access object 以及 Database 具体对象

      Data entity (更多使用细节 使用 Room 实体定义数据 )

      @Entity
      public class User {
          @PrimaryKey
          public int uid;
      
          @ColumnInfo(name = "first_name")
          public String firstName;
      
          @ColumnInfo(name = "last_name")
          public String lastName;
      }
      

      Data access object (更多使用细节 使用 Room DAO 访问数据 )

      @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
          void insertAll(User... users);
      
          @Delete
          void delete(User user);
      }
      

      Database

      @Database(entities = {User.class}, version = 1)
      public abstract class AppDatabase extends RoomDatabase {
          public abstract UserDao userDao();
      }
      
    2. 使用 Dao 操作数据库

      创建或者打开数据库

      AppDatabase db = Room.databaseBuilder(getApplicationContext(),
              AppDatabase.class, "database-name").build();
      

      获取数据库访问方法

      UserDao userDao = db.userDao(); // 获取 Dao 对象
      List<User> users = userDao.getAll(); // 获取数据库所有对象
      

      使用 Data access object 增,查,删,改

  • Room entities 详细使用方法

    1. 主键(PrimaryKey)
        @Entity
        public class User {
            @PrimaryKey
            public int id;
    
            public String firstName;
            public String lastName;
        }
        
    

    要存储类中的属性,必须将属性设为 public , 或者给出 getter 和 setter

    每个 entity 必须将一个属性定义为主键(PrimaryKey) , 且每一个实例对象必须有不同的主键值才可以放入数据库 , 就是说每个 entity 的对象都要有一个唯一的编号,不然不好找

    如果您想让 Room 为实体分配自动 ID,则可以设置 @PrimaryKeyautoGenerate 属性。如果实体具有复合主键,您可以使用 @Entity 注释的 primaryKeys 属性,如以下代码段所示:

       @Entity(primaryKeys = {"firstName", "lastName"})
        public class User {
            public String firstName;
            public String lastName;
        }
        
    
    1. 数据库表名称

    默认情况下,Room 将类名称用作数据库表名称。如果希望表具有不同的名称,请设置 @Entity 注释的 tableName 属性,如以下代码段所示:

        @Entity(tableName = "users")
        public class User {
            // ...
        }
        
    

    表名称不区分大小写

    1. 数据库列名称

    Room 将属性名称用作数据库中的列名称。如果希望列具有不同的名称,请将 @ColumnInfo 注释添加到字段,如以下代码段所示:

        @Entity(tableName = "users")
        public class User {
            @PrimaryKey
            public int id;
    
            @ColumnInfo(name = "first_name")
            public String firstName;
    
            @ColumnInfo(name = "last_name")
            public String lastName;
        }
        
    
    1. 忽略属性

    默认情况下,Room 会为实体中定义的每个属性创建一个列。如果实体(要存储的类)中有您不想保留的属性,则可以使用 @Ignore 为这些字段添加注释,如以下代码段所示:

        @Entity
        public class User {
            @PrimaryKey
            public int id;
    
            public String firstName;
            public String lastName;
    
            @Ignore
            Bitmap picture;
        }   
    

    如果实体类继承了父类的属性,则使用 @Entity 属性的 ignoredColumns 属性来忽略:

        @Entity(ignoredColumns = "picture")
        public class RemoteUser extends User {
            @PrimaryKey
            public int id;
    
            public boolean hasVpn;
        }
        
    
    1. 让表支持搜索功能,以后再学习(https://developer.android.google.cn/training/data-storage/room/defining-data#java)
  • 使用 Dao 访问数据库

    1. 插入 insert

      @Dao
      public interface UserDao {
      		@Insert(onConflict = OnConflictStrategy.REPLACE)
        	//OnConflictStrategy.ABORT(默认)在发生冲突时回滚事务
      		//OnConflictStrategy.REPLACE 现有行替换为新行
      		//OnConflictStrategy.IGNORE 持现有行  
        	public void insertUsers(User... users);
          @Insert
          public void insertBothUsers(User user1, User user2);
          @Insert
          public void insertUsersAndFriends(User user, List<User> friends);
      }
      

      如果 @Insert 方法只接收 1 个参数,则它可以返回 long,这是插入项的新 rowId

      如果参数是数组或集合,则应返回 long[]List<Long>

    2. 更新 Update

      @Dao
      public interface UserDao {
          @Update
          public void updateUsers(User... users);
      }
      

      传入的对象的会替换在数据库中有相同 id 的那一行

      可以让此方法返回一个 int 值,以指示数据库中更新的行数

    3. 删除 delete

          @Dao
          public interface MyDao {
              @Delete
              public void deleteUsers(User... users);
          }
          
      

      可以让此方法返回一个 int 值,以指示从数据库中删除的行数

    4. 查询 query

      • 简单查询

      •     @Dao
            public interface MyDao {
                @Query("SELECT * FROM user")
                public User[] loadAllUsers();
            }
            
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值