android Room数据库框架使用流程整理

前言

    因为遇到需求需要保存数据到本地数据库,一起开发的同事选用了Room数据库框架移植到项目中,于是我也只能去学习使用这种框架。了解之后发现这个框架建库、建表、数据库升级等操作都十分简单,很适合怕麻烦的攻城狮们使用。

正文

    1.建表

      这里以常用的存储用户信息的user表为例:

      

/**
 * @Description: 存储用户信息到本地数据库
 * @author: jesse_android
 * @date: 2019/4/19
 */
@Entity(tableName = "user")
public class UserInfo {

    @PrimaryKey(autoGenerate = true)
    private int id;

    private int userId;
    private String mobile;
    private String nickname;
    private String avatar;
    private String category;
    private String instituteId;
    private int role;
    private int certify;//认证状态 0未认证 1已认证
    private int partner;//是否是合伙人 0不是 1是

    public UserInfo(int userId, String mobile) {
        this.userId = userId;
        this.mobile = mobile;
    }

    @Ignore
    public UserInfo(){}

    @Ignore
    public UserInfo(OrgLoginBean loginBean) {
        this.userId = loginBean.getData().getUserId();
        this.mobile = loginBean.getData().getMobile();
        this.nickname = loginBean.getData().getNickname();
        this.avatar = loginBean.getData().getAvatar();
        this.certify = loginBean.getData().getCertify();
        this.partner = loginBean.getData().getPartner();
    }

    @Ignore
    public UserInfo(int userId, String mobile, String nickname, String avatar, String category, String instituteId) {
        this.userId = userId;
        this.mobile = mobile;
        this.nickname = nickname;
        this.avatar = avatar;
        this.category = category;
        this.instituteId = instituteId;
    }

    @Ignore
    public UserInfo(int userId, String mobile, String nickname, String avatar, int certify) {
        this.userId = userId;
        this.mobile = mobile;
        this.nickname = nickname;
        this.avatar = avatar;
        this.certify = certify;
    }

    public int getId() {
        return id;
    }

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

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getInstituteId() {
        return instituteId;
    }

    public void setInstituteId(String instituteId) {
        this.instituteId = instituteId;
    }

    public int getRole() {
        return role;
    }

    public void setRole(int role) {
        this.role = role;
    }

    public int getCertify() {
        return certify;
    }

    public void setCertify(int certify) {
        this.certify = certify;
    }

    public int getPartner() {
        return partner;
    }

    public void setPartner(int partner) {
        this.partner = partner;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "id=" + id +
                ", userId=" + userId +
                ", mobile='" + mobile + '\'' +
                ", nickname='" + nickname + '\'' +
                ", avatar='" + avatar + '\'' +
                ", category='" + category + '\'' +
                ", instituteId='" + instituteId + '\'' +
                ", role=" + role +
                ", certify=" + certify +
                ", partner=" + partner +
                '}';
    }
}

细节解析:

1.@Entity(tableName = "user")--定义表明为user;

2.@PrimaryKey(autoGenerate = true)--将下方字段设置为主键并且自增;autoGenerate = true--自增;

3.@Ignore--编译时忽略下方的构造方法;(一个实体类只允许有一个构造方法进入编译,否则报错。因此只能留一个构造方法,其余的都要加上@Ignore标签!!!加上这个标签并不会影响你正常调用)

2.建库

    为什么先说建表再说建库?因为建库的时候会用到表。

    

@Database(entities = {UserInfo.class}, version = 1, exportSchema = false)
public abstract class CoursewareDataBase extends RoomDatabase {

    private static final String DB_NAME = "CoursewareDatabase.db";
    private static volatile CoursewareDataBase instance;

    static synchronized CoursewareDataBase getInstance(Context context) {
        if (instance == null) {
            instance = create(context);
        }
        return instance;
    }

    private static CoursewareDataBase create(final Context context) {
        return Room.databaseBuilder(context, CoursewareDataBase.class, DB_NAME)
                .addMigrations(migration_1_2)
                .addMigrations(migration_2_3)
                .addMigrations(migration_3_4)
                .addMigrations(migration_4_5)
                .build();
    }

    //@{版本号升级后一定要加migration
    private static Migration migration_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE user ADD certify INTEGER NOT NULL DEFAULT 0");
        }
    };

    private static Migration migration_2_3 = new Migration(2, 3) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE video_list ADD stage TEXT DEFAULT ''");
        }
    };
    private static Migration migration_3_4 = new Migration(3, 4) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE video_list ADD views INTEGER NOT NULL DEFAULT 0");
        }
    };
    private static Migration migration_4_5 = new Migration(4, 5) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE user ADD partner INTEGER NOT NULL DEFAULT 0");
        }
    };
    //@}

    public abstract UserDao getUserDao();
}

细节解析:

1.@Database(entities = {UserInfo.class}, version = 1, exportSchema = false)--声明该类作为一个本地数据库;entities={}--你建的表的实体类必须在花括号中声明;version = 1--当前数据库版本为1,要升级数据库版本的话,需要填入比当前数字更大的数字,比如2;exportSchema = false--如果设置为true,在app目录下会生成一个Schema文件夹,里面会生成数据库版本.json文件,设置为true有报错风险,建议设为false。

2.public abstract class CoursewareDataBase extends RoomDatabase--注意这里必须要设置该类为抽象类,然后继承RoomDataBase类;

3.创建数据库、数据库版本升级:

private static CoursewareDataBase create(final Context context) {
        return Room.databaseBuilder(context, CoursewareDataBase.class, DB_NAME)
                .addMigrations(migration_1_2)
                .addMigrations(migration_2_3)
                .addMigrations(migration_3_4)
                .addMigrations(migration_4_5)
                .build();
    }

    //@{版本号升级后一定要加migration
    private static Migration migration_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE user ADD certify INTEGER NOT NULL DEFAULT 0");
        }
    };

--版本升级照着这样写就行了,不用我多说应该能看懂,如果是初始数据库版本,则不用写addMigrations,直接return Room.databaseBuilder(context, CoursewareDataBase.class, DB_NAME).build();即可。

4.public abstract UserDao getUserDao();--需要用到的Dao文件必须在类中声明。

3.创建Dao文件

@Dao
public interface UserDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertUser(UserInfo... userinfo);

    @Query("SELECT * FROM user")
    List<UserInfo> queryAll();

    @Query("SELECT * FROM user where userId = :userId")
    UserInfo queryUser(int userId);

    @Query("DELETE FROM user where userId = :userId")
    void deleteUser(int userId);

}

细节解析:

1.@Dao--声明该类为Dao文件(用来操作表增删改查的文件);

2.@Insert(onConflict = OnConflictStrategy.REPLACE)--插入一条新数据到表中;onConflict = OnConflictStrategy.REPLACE--如果插入的新数据在表中已经存在,即如果遇上数据冲突的情况,新数据直接替换旧数据;

3.@Query("SELECT * FROM user")--@Query标签后方的括号里可用的语句不仅仅限于查询语句,其他所有SQL语句都可以写在里面,比如你可以使用这个标签做delete操作:@Query("DELETE FROM user where userId = :userId");--:userId 表示使用下方传入的userId参数。

4.使用Dao文件操作数据库

    

private CoursewareDataBase coursewareDataBase;
private UserDao userDao;

coursewareDataBase = CoursewareDataBase.getInstance(context);
userDao = coursewareDataBase.getUserDao();

        new Thread(new Runnable() {
            @Override
            public void run() {
                List<UserInfo> userInfoList =  userDao.queryAll();
            }
        }).start();

这里特别要注意的就是userDao.queryAll()这句代码必须放在子线程中,否则会报错。以上是以调用queryAll方法作为例子,调用其他userDao中的方法同样。

附上博主使用的room项目依赖添加代码:

implementation('android.arch.persistence.room:runtime:1.0.0') {
    exclude group: 'com.android.support'
}
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

结语

    从创建到数据库升级到使用Dao文件操作数据库,流程相当简单,这就是Room这个框架的优势,但是只能在子线程中进行数据库操作是它的硬伤,如果你能接受这一点的话,那么Room也不失为一个好的android本地数据库框架。

    如果这篇文章对你有帮助,点下免费的赞和关注鼓励一下吧,这些都是我更博的动力,谢啦~

    有不懂或者使用过程中遇到什么问题的,欢迎下方留言。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Android Room是Google为Android平台开发的一个SQLite对象映射数据库框架,它提供了一种简单的方式来访问SQLite数据库。下面是使用Room进行SQLite查询的基本步骤: 1. 定义实体类:在Room中,表是通过实体类来表示的。你需要定义一个Java类来表示数据库中的每个表,并使用注释来指定表名、列名等信息。 2. 定义DAO接口:DAO(Data Access Object)是用于访问数据库的接口。你需要定义一个接口来提供对实体类的CRUD操作。 3. 创建数据库使用Room,你可以在应用程序中创建一个SQLite数据库。你需要创建一个继承自RoomDatabase的抽象类,并定义抽象方法来获取DAO对象。 4. 执行查询操作:在DAO接口中定义查询语句,并在应用程序中调用该方法来执行查询操作。以下是一个使用Room进行查询的示例: ```java @Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :userId") User getUserById(int userId); @Query("SELECT * FROM user WHERE name LIKE :name") List<User> getUsersByName(String name); @Insert void insertUser(User user); } ``` 在上面的示例中,@Query注释指定了查询语句,getUserById方法根据用户ID查询用户,getUsersByName方法根据名称查询用户,insertUser方法将用户插入数据库。 要使用上述查询方法,你需要创建一个RoomDatabase实例并获取UserDao对象。以下是一个使用Room进行查询的示例: ```java UserDatabase db = Room.databaseBuilder(getApplicationContext(), UserDatabase.class, "user.db").build(); UserDao userDao = db.userDao(); // 根据ID查询用户 User user = userDao.getUserById(1); // 根据名称查询用户 List<User> users = userDao.getUsersByName("John"); // 插入用户 User newUser = new User("Alice", "alice@example.com"); userDao.insertUser(newUser); ``` 在上面的示例中,我们创建了一个UserDatabase实例,并使用其userDao()方法获得UserDao对象。然后我们可以使用UserDao对象的方法来执行查询和插入操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JesseAndroid

每一份支持都是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值