Jetpack学习笔记:架构组件——Room基础使用

本文介绍了Android中Room持久性库,它在SQLite基础上提供抽象层,方便开发者访问数据库。详细阐述了使用Room框架的步骤,包括注入依赖、注解使用、实体类、数据访问对象、数据库类的定义,还提及了ViewModel和Repository的作用及数据展示方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

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

方便开发者流畅地访问SQLite数据库。

注入依赖

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"
}

Annotations(注解)

Room框架的使用过程中包含许多注解,以下链接指向官方文档的注解部分。

androidx.room | Android开发者 | Android Developers

Entity(实体类)

实体类对应数据库中“表”的概念,需用注解@Entity标记;成员变量对应表中的“列”,根据需求可用不同的注解标记。

@Entity
public class Report {

	//定义主键,设置自增
    @PrimaryKey(autoGenerate = true)
    private int id;

	//定义列名,默认为对象名小写
    @ColumnInfo(name = "student_name")
    private String stuName;

    private int grade;
	
	//省略构造方法及get/set方法
 }

DAO(Data Access Object, 数据访问对象)

在此定义对表中数据的操作,需用注解@Dao标记;方法则根据需求使用不同的注解标记。

/*
 * Data Access Object
 * 数据访问对象
 */
@Dao
public interface ReportDAO {

    @Insert
    void insert(Report... reports);

    @Update
    void update(Report... reports);

    @Delete
    void delete(Report... reports);

    @Query("DELETE FROM REPORT")
    void clear();

    @Query("SELECT * FROM REPORT ORDER BY ID ASC")
    LiveData<List<Report>> findAll();

}

Database(数据库类)

数据库类负责创建和连接数据库,并提供数据访问对象。需用@Database注解标记。

/**
 * entities: 数据库包含的实体类(表),有多个时用","隔开,同样地,getXXXDao也应该有多个
 * version: 版本号
 */
@Database(entities = {Report.class}, version = 1)
public abstract class ReportDatabase extends RoomDatabase {

    private static ReportDatabase INSTANCE;

    public static synchronized ReportDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            INSTANCE = Room.databaseBuilder(context, ReportDatabase.class, "report_database")
                    //.allowMainThreadQueries()	//允许在主线程中操作数据
                    .build();
        }
        return INSTANCE;
    }

    public abstract ReportDAO getReportDao();

}

ViewModel和Repository(仓库类)

ViewModel负责管理界面的数据,仓库类负责处理数据的获取。

此举是为了使逻辑功能最小化,避免某个类由于职责过多而显得臃肿。

Repository

对数据库操作一般要求在子线程中进行。由于AsyncTask于api 30中被弃用,故此处采用线程池结合Runable的方式处理,可能不是最优质的解决方案,但至少行得通。

public class ReportRepository {

    private LiveData<List<Report>> allReportsLive;

    private ReportDAO reportDAO;

    private ExecutorService fixedThreadPool;

    public ReportRepository(Context context) {
        //数据库
        ReportDatabase reportDatabase = ReportDatabase.getInstance(context.getApplicationContext());
        reportDAO = reportDatabase.getReportDao();
        //线程池
        fixedThreadPool = Executors.newFixedThreadPool(4);
        //LiveData
        allReportsLive = reportDAO.findAll();
    }

    public LiveData<List<Report>> getAllReportsLive() {
        return allReportsLive;
    }

    /**
     * 数据操作
     */
    void insert(Report... reports) {
        fixedThreadPool.execute(new InsertTask(reportDAO, reports));
    }

    void delete(Report... reports) {
        fixedThreadPool.execute(new DeleteTask(reportDAO, reports));
    }

    void update(Report... reports) {
        fixedThreadPool.execute(new UpdateTask(reportDAO, reports));
    }

    void clear() {
        fixedThreadPool.execute(new ClearTask(reportDAO));
    }

    /**
     * Runnable
     */
    static class InsertTask implements Runnable {

        private final ReportDAO reportDAO;
        private final Report[] reports;

        public InsertTask(ReportDAO reportDAO, Report... reports) {
            this.reportDAO = reportDAO;
            this.reports = reports;
        }

        @Override
        public void run() {
            reportDAO.insert(reports);
        }
    }

    static class DeleteTask implements Runnable {

        private final ReportDAO reportDAO;
        private final Report[] reports;

        public DeleteTask(ReportDAO reportDAO, Report... reports) {
            this.reportDAO = reportDAO;
            this.reports = reports;
        }

        @Override
        public void run() {
            reportDAO.delete(reports);
        }
    }

    static class UpdateTask implements Runnable {

        private final ReportDAO reportDAO;
        private final Report[] reports;

        public UpdateTask(ReportDAO reportDAO, Report... reports) {
            this.reportDAO = reportDAO;
            this.reports = reports;
        }

        @Override
        public void run() {
            reportDAO.update(reports);
        }
    }


    static class ClearTask implements Runnable {

        private final ReportDAO reportDAO;

        public ClearTask(ReportDAO reportDAO) {
            this.reportDAO = reportDAO;
        }

        @Override
        public void run() {
            reportDAO.clear();
        }
    }
}

ViewModel

public class MyViewModel extends AndroidViewModel {

    private ReportRepository reportRepository;

    public MyViewModel(@NonNull Application application) {
        super(application);
        reportRepository = new ReportRepository(application);
    }

    public LiveData<List<Report>> getAllReportsLive() {
        return reportRepository.getAllReportsLive();
    }

    /**
     * 数据操作
     */
    void insert(Report... reports) {
        reportRepository.insert(reports);
    }

    void delete(Report... reports) {
        reportRepository.delete(reports);
    }

    void update(Report... reports) {
        reportRepository.update(reports);
    }

    void clear() {
        reportRepository.clear();
    }

}

Activity

数据的展示一般使用列表效果更好,这里为了偷懒直接使用TextView了。

public class MainActivity extends AppCompatActivity {

    private Button insertBtn, deleteBtn, updateBtn, clearBtn;
    private TextView reportTv;

    private MyViewModel myViewModel;

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

        //ViewModel
        myViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);

        //View
        reportTv = findViewById(R.id.report_tv);
        insertBtn = findViewById(R.id.button_insert);
        deleteBtn = findViewById(R.id.button_delete);
        updateBtn = findViewById(R.id.button_update);
        clearBtn = findViewById(R.id.button_clear);

        //Event
        insertBtn.setOnClickListener(v -> {
            Report report1 = new Report("小王", 88);
            Report report2 = new Report("小红", 99);
            Report report3 = new Report("小朱", 75);
            Report report4 = new Report("小张", 91);
            Report report5 = new Report("小李", 100);
            Report report6 = new Report("小武", 72);
            Report report7 = new Report("小黑", 66);
            myViewModel.insert(report1, report2, report3, report4, report5, report6, report7);
        });

        deleteBtn.setOnClickListener(v -> {
            Report report = new Report();
            report.setId(91);
            myViewModel.delete(report);
        });

        updateBtn.setOnClickListener(v -> {
            Report report = new Report("小李", 0);
            report.setId(89);
            myViewModel.update(report);
        });

        clearBtn.setOnClickListener(v -> myViewModel.clear());

        //设置观察者
        myViewModel.getAllReportsLive().observe(this, new Observer<List<Report>>() {
            @Override
            public void onChanged(List<Report> reports) {
                StringBuilder sb = new StringBuilder();
                for (Report report : reports) {
                    sb.append("学号:");
                    sb.append(report.getId());
                    sb.append("  姓名:");
                    sb.append(report.getStuName());
                    sb.append("  得分:");
                    sb.append(report.getGrade());
                    sb.append("分");
                    sb.append("\n");
                }
                reportTv.setText(sb);
            }
        });
    }

}

最终效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值