jetpack--Room

(1)Room是jetpack的组件之一,是一个独立的数据库 ,是对sqlite(是用sql c 语言实现,使用比较复杂)数据库的封装,使用比较简单。
(2)可以结合liveDate lifecycle 使用
(3)使用APT注解处理器生成代码完成
(4)Room的三大角色:用户操作时只针对Dao进行操作即可,是Room设计的初衷
数据类(class student 一张表)@Entity 操作(增删改查StudentDao)@Dao 数据库()@DataBase(v = 3)数据库版本号为3

一、AS中安装database 插件

1、File->Settings->Plugins 中MarketPlace中搜索database 找到"Database Navigator" 点击安装,安装完成后点击重启AS按钮;
在这里插入图片描述
2、重启后,AS 界面左侧出现“DB Browser”,则插件安装完毕。

二、Room的使用(Java)

1、在app的build.gradle中添加包

// 下面是 ROOM依赖相关的代码
    def room_version = "2.0.0-beta01"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version" // use kapt for Kotlin

    // 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、新建表(用@Entity修饰)
注意:表中需要包含主键,且自增长;

// Student.java
package com.test.databindingtestjava.room.entity;

import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

/**
 * @ClassName Student
 * @Description TODO
 * @Author lili
 * @DATE 2022/11/5 14:19
 */
@Entity
public class Student {
    @PrimaryKey(autoGenerate = true) // PrimaryKey 主键;autoGenerate自增长
    private int uid;

    //下面定义表中包含的列(字段)
    @ColumnInfo(name="name") // ColumnInfo 列信息
    private String name;

    @ColumnInfo(name="age")
    private int age;

    @ColumnInfo(name="address")
    private String address;

    @ColumnInfo(name="number")
    private String number;

    //构造函数

    public Student() {}

    public Student(int uid,String name, int age, String address, String number) {
        this.uid = uid;
        this.name = name;
        this.age = age;
        this.address = address;
        this.number = number;
    }

    public Student(String name, int age, String address, String number) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.number = number;
    }

    //外部调用方法

    public void setUid(int uid) {
        this.uid = uid;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public int getUid() {
        return uid;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

    public String getNumber() {
        return number;
    }

    @Override
    public String toString() {
        return "Student{" +
                "uid=" + uid +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", address=" + address + '\'' +
                ", number = " + number + '\'' +
                '}';
    }
}


2、新建Dao接口(用@Dao修饰)
添加增 删 改 查 接口

// StudentDao.java 接口
package com.test.databindingtestjava.room.dao;

import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import com.test.databindingtestjava.room.entity.Student;

import java.util.List;

@Dao
public interface StudentDao {

    // 增
    @Insert
    void insert(Student...students);

    // 删
    @Delete
    void delete(Student student);

    // 改
    @Update
    void update(Student student);

    //查(所有)
    @Query("select *  from  Student")
    List<Student> getAll();

    //查(按姓名name查)
    @Query("select * from Student where name like :name ")
    Student getByName(String name);

    //查(按主键id查)
    @Query("select * from Student where id in(:ids)")
    List<Student> getById(int[] ids);
}

3、新建数据库(@Database(entities = {Student.class},version = 1,exportSchema = false))

由于 Room使用APT注解处理器 技术,会自动生成数据库实现代码,因此,该方法为抽象类。

//StudentDB.class
package com.test.databindingtestjava.room.db;

import androidx.room.Database;
import androidx.room.RoomDatabase;
import com.test.databindingtestjava.room.dao.StudentDao;
import com.test.databindingtestjava.room.entity.Student;

/**
 * @ClassName StudentDB
 * @Description TODO
 * @Author lili
 * @DATE 2022/11/5 15:01
 */

// entities = Student.class: 该数据库包含的表
// version = 1: 该数据库版本
// exportSchema = false : 尽量写,内部需要检测,如果没有写,会抛出异常,因为内部要记录升级的所有副本
@Database(entities = {Student.class},version = 1,exportSchema = false)
public abstract class TestDB extends RoomDatabase {
    // 暴露Dao
    public abstract StudentDao getDao();
}

4、使用Dao,完成数据库的增 删 改 查

//MainActivity.class
 package com.test.databindingtestjava;

import android.os.Bundle;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.room.Room;

import com.test.databindingtestjava.databinding.ActivityMaintestBinding;
import com.test.databindingtestjava.room.dao.StudentDao;
import com.test.databindingtestjava.room.db.TestDB;
import com.test.databindingtestjava.room.entity.Student;

import java.util.List;

/**
 * @ClassName MainActivityTest
 * @Description TODO
 * @Author lili
 * @DATE 2022/11/2 13:46
 */
public class MainActivityTest extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        testThread thread = new testThread();
        thread.start();
    }

    public class testThread extends Thread{
        @Override
        public void run() {
            super.run();
            // 创建数据库
            TestDB testDB = Room.databaseBuilder(getApplicationContext()
                    ,TestDB.class
                    ,"testDB")
                    //可以设置强制主线程,默认是让你用子线程
//                    .allowMainThreadQueries()
                    .build();

            // 获取Dao
            StudentDao dao = testDB.getDao();

            //增
            dao.insert(new Student("lily",20,"hrb","123456789")
                    ,new Student("liyu",24,"hrbcs","977336373")
                    ,new Student("yuh",26,"hrbdal","35363647474")
                    ,new Student("ddhfff",23,"hrbwuc","63736374848")
                    ,new Student("ffjdfjf",50,"hrbshuanc","12345645")
                    ,new Student("黄飞鸿",98,"哈尔滨","0987654"));

            //获取所有
            List<Student> all = dao.getAll();
            Log.d("testRoom","测试新增数据:" + all.toString());

            //更新数据
            dao.update(new Student(3,"合法",98,"黑龙江","0987654"));
            List<Student> updateAll = dao.getAll();
            Log.d("testRoom","测试更新数据:" + updateAll.toString());

            // 查询
            Student student = dao.getByName("黄飞鸿");
            Log.d("testRoom", "查询数据 :"+student.toString());

            //查询2
            List<Student> studens = dao.getById(new int[]{25,26,27});
            Log.d("testRoom","查询数据2 :" + studens.toString());

            // 删除
            //获取所有
            List<Student> allLast = dao.getAll();
            for (int i =0; i < allLast.size(); i ++) {
                dao.delete(allLast.get(i));
            }
        }
    }
}

三、Room的使用(kotlin)
四、使用database 插件查看数据库
1、AS 右侧 ,点击 “device File Explore”,选择 /data/data/包名,找到databases该路径下面保存的即为代码中创建的数据库。
在这里插入图片描述

2、将databases下面的三个文件导出到电脑桌面;
3、按下面步骤操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
五、数据库升级
以本文为例。当数据表中需要新增一列数据时,需要数据库升级,下面是数据库升级的方法。
1、在Studen.java中新增一个字段int grade:

//定义字段
@ColumnInfo(name="grade")
    private int grade;

//构造函数
public Student(int uid,String name, int age, String address, String number,int grade) {
        this.uid = uid;
        this.name = name;
        this.age = age;
        this.address = address;
        this.number = number;
        this.grade = grade;
    }

    public Student(String name, int age, String address, String number,int grade) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.number = number;
        this.grade = grade;
    }

//开放方法
public void setGrade(int grade) {
        this.grade = grade;
    }

public int getGrade() {
        return grade;
    }

2、修改TestDB.java,使用SQL脚本完成数据变化

static final Migration MIGRATION_1_2 = new Migration(1,2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //在这里使用SQL脚本完成数据的变化
            database.execSQL("alter table Student add column grade integer not null default 1");
        }
    };

3、修改TestDB.java,创建数据库方法

private static  TestDB mInstance;

    public static synchronized TestDB getTestDB(Context context) {
        if (mInstance == null) {
            mInstance =  Room.databaseBuilder(context.getApplicationContext()
                            ,TestDB.class
                            ,"testDB")
                    //可以设置强制主线程,默认是让你用子线程(如果运行在主线程,需要加上下面这句话)
//                    .allowMainThreadQueries()
                    // 2、修改版本号:标记修改版本号(正常方式升级)
                    .addMigrations(MIGRATION_1_2)

                    //暴力版本升级(会丢失数据)
//                    .fallbackToDestructiveMigration()
                    .build();
        }
        return mInstance;
    }

4、修改TestDB.java,修改数据库版本号

@Database(entities = {Student.class},version = 2/*1、修改版本号:从1 修改到2*/,exportSchema = false)

5、Activity中重新创建数据库

 // 创建数据库
           /* TestDB testDB = Room.databaseBuilder(getApplicationContext()
                    ,TestDB.class
                    ,"testDB")
                    //可以设置强制主线程,默认是让你用子线程
//                    .allowMainThreadQueries()
                    .build();*/
            TestDB testDB = TestDB.getTestDB(MainActivityTest.this);

六、数据库升级(删掉一列数据–一个字段)

 // ROOM 是不能降级的,我非要删除一个字段,却要保证数据的稳定性,这个是特殊情况
    // 特殊手法降级(不验证了,需要的时候再验证)
    static final Migration MIGRATION_2_3 = new Migration(2, 3) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            // SQL 四步法

            // 1.先建立临时表
            //  database.execSQL("create table student_temp (uid integer primary key not null,name text,pwd text,addressId)");

            // 2.把之前表的数据(SQL语句的细节,同学们可以上网查询下)
            // database.execSQL("insert into student_temp (uid,name,pwd,addressid) " + " select uid,name,pwd,addressid from student");

            // 3.删除student 旧表
            // database.execSQL("drop table student");

            // 4.修改 临时表 为 新表 student
            // database.execSQL("alter table student_temp rename to student");
        }
    };
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值