1.Andriod — JetPack (一):初识 JetPack

2.Andriod — JetPack (二):LifeCycle 的诞生

3.Andriod — JetPack (三):ViewModel 的诞生

4.Andriod — JetPack (四):BaseObservable 与 ObservableField 双向绑定

5.Andriod — JetPack (五):DataBinding + LiveData +ViewModel 简单实例

6.Andriod — JetPack (六):Room 增删改查

7.Andriod — JetPack (七):Room + ViewModel + LiveData 增删改查实例

一、前言

Android 采用 SQlit 作为数据库存储,开源社区常用的 ORM (Object Relational Mapping) 库有 ORMLite、GreenDao 等。Room 和其他库一样,也是在 SQLite 上提供了一成封装。

这个 ORM 我们解释一下,因为我们用 Java 写的程序都是面向对象编程的(oop),而数据库是面向关系的,表与表之间的关系等等,那么我们怎么把这两者之间串联起来的就有了ORM,对象-关系-映射,这个东西。

而 Room 是由谷歌提出的,可以说是一统天下了,也是像 ORMLite、GreenDao的 ORM 库。

二、Romm 的应用

  1. Room 的重要概念
    Entity:实体类,对应的是数据库的一张表的结构,使用注解 @Entity 标记。
    Dao:包含访问一系列访问数据库的方法,使用注解 @Dao 标记。
    Database:数据库持有者,作为与应用持久化相关数据的低层连接的主要接入点。使用注解 @Database 标记,另外需要满足一下条件:定义的类必须是一个继承于 RoomDatabase 的抽象类,在注解中需要定义域数据库相关联的实体类列表。包好一个没有参数的抽象方法并且返回一个 Dao 对象。

  2. 三者之间的关系

三、增删改查代码实例

build.gradle中添加 Room 依赖

// Room
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor "androidx.room:room-compiler:2.2.5"

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintGuide_percent="0.1" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintGuide_percent="0.2" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.5" /><Buttonandroid:id="@+id/button7"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="mInsert"android:text="增加"app:layout_constraintBottom_toTopOf="@+id/guideline2"app:layout_constraintEnd_toStartOf="@+id/guideline4"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/button8"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="mUpdate"android:text="修改"app:layout_constraintBottom_toTopOf="@+id/guideline2"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="@+id/guideline4"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/button9"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="mDelete"android:text="删除"app:layout_constraintBottom_toTopOf="@+id/guideline3"app:layout_constraintEnd_toStartOf="@+id/guideline4"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="@+id/guideline2" /><Buttonandroid:id="@+id/button10"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="mQuery"android:text="查询"app:layout_constraintBottom_toTopOf="@+id/guideline3"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="@+id/guideline4"app:layout_constraintTop_toTopOf="@+id/guideline2" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_01"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="@+id/guideline3" />
</androidx.constraintlayout.widget.ConstraintLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.2" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline5"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.8" /><TextViewandroid:id="@+id/tvId"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="1"app:layout_constraintBottom_toTopOf="@+id/guideline7"app:layout_constraintEnd_toStartOf="@+id/guideline"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Jack"app:layout_constraintBottom_toTopOf="@+id/guideline7"app:layout_constraintEnd_toStartOf="@+id/guideline5"app:layout_constraintStart_toStartOf="@+id/guideline"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/age"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="18"app:layout_constraintBottom_toTopOf="@+id/guideline7"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="@+id/guideline5"app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

首先创建实体类Student.java

package com.example.room;import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;@Entity(tableName = "student")
public class Student {@PrimaryKey(autoGenerate = true)@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)public int id;@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)public String name;@ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER)public int age;public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Ignorepublic Student(String name, int age) {this.name = name;this.age = age;}@Ignorepublic Student(int id) {this.id = id;}
}

StudentDao.java

package com.example.room;import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;import java.util.List;@Dao
public interface StudentDao {@Insertvoid insertStudent(Student... students); // 可以传入多个 Student@Deletevoid deleteStudent(Student... students);@Updatevoid updateStudent(Student... students);@Query("SELECT * FROM student")List<Student> getAllStudent();@Query("SELECT * FROM student WHERE id = :id")List<Student> getStudentById(Integer id);
}

MyDataBase.java

package com.example.room;import android.content.Context;import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
// 一定是抽象类
@Database(entities = {Student.class}, version = 1, exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {private static final String DATABASE_NAME = "my_db.db";private static MyDataBase mInstance;// 构建 database 单例public static synchronized MyDataBase getInstance(Context context) {if(mInstance == null) {mInstance = Room.databaseBuilder(context.getApplicationContext(), MyDataBase.class, DATABASE_NAME)//.allowMainThreadQueries() // 允许在主线程操作数据库.build();}return mInstance;}public abstract StudentDao getStudentDao();
}

StudentRecycleViewAdapter.java

package com.example.room;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import java.util.List;public class StudentRecycleViewAdapter extends RecyclerView.Adapter<StudentRecycleViewAdapter.MyViewHolder> {List<Student> students;public void setStudents(List<Student> students) {this.students = students;}public StudentRecycleViewAdapter(List<Student> students) {this.students = students;}@NonNull@Overridepublic MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent, false);return new MyViewHolder(root);}@Overridepublic void onBindViewHolder(@NonNull MyViewHolder holder, int position) {Student student = students.get(position);holder.tvId.setText(String.valueOf(student.id));holder.name.setText(student.name);holder.age.setText(String.valueOf(student.age));}@Overridepublic int getItemCount() {return students == null ? 0 :students.size();}public class MyViewHolder extends RecyclerView.ViewHolder {private TextView tvId, name, age;public MyViewHolder(View view) {super(view);tvId = view.findViewById(R.id.tvId);name = view.findViewById(R.id.name);age = view.findViewById(R.id.age);}}
}

MainActivity.java

package com.example.room;import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private StudentRecycleViewAdapter adapter;private StudentDao studentDao;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);List<Student> students = new ArrayList<>();RecyclerView recyclerView = findViewById(R.id.rv_01);adapter = new StudentRecycleViewAdapter(students);recyclerView.setLayoutManager(new LinearLayoutManager(this));recyclerView.setAdapter(adapter);MyDataBase myDataBase = MyDataBase.getInstance(this);studentDao = myDataBase.getStudentDao();}// Room 不允许在主线程操作数据库,如果非在主线程操作数据库,请修改 MyDataBase 文件// 增加public void mInsert(View view) {Student s1 = new Student("Jack", 20);Student s2 = new Student("Rose", 22);new  InsertStudentTask(studentDao).execute(s1,s2);}// 删除public void mDelete(View view) {Student s1 = new Student(1);new DeleteStudentTask(studentDao).execute(s1);}// 修改public void mUpdate(View view) {Student s1 = new Student(3, "Jason", 21);new UpdateStudentTask(studentDao).execute(s1);}// 查询public void mQuery(View view) {new GetAllStudentTask(studentDao).execute();}// 异步线程添加学生class InsertStudentTask extends AsyncTask<Student, Void, Void> {private StudentDao studentDao;public InsertStudentTask(StudentDao studentDao) {this.studentDao = studentDao;}@Overrideprotected Void doInBackground(Student... students) {studentDao.insertStudent(students);return null;}}// 异步修改学生class UpdateStudentTask extends AsyncTask<Student, Void, Void> {private StudentDao studentDao;public UpdateStudentTask(StudentDao studentDao) {this.studentDao = studentDao;}@Overrideprotected Void doInBackground(Student... students) {studentDao.updateStudent(students);return null;}}// 异步删除学生class DeleteStudentTask extends AsyncTask<Student, Void, Void> {private StudentDao studentDao;public DeleteStudentTask(StudentDao studentDao) {this.studentDao = studentDao;}@Overrideprotected Void doInBackground(Student... students) {studentDao.deleteStudent(students);return null;}}// 异步获取学生信息class GetAllStudentTask extends AsyncTask<Student, Void, Void> {private StudentDao studentDao;public GetAllStudentTask(StudentDao studentDao) {this.studentDao = studentDao;}@Overrideprotected Void doInBackground(Student... students) {List<Student> list = studentDao.getAllStudent();adapter.setStudents(list);return null;}// 更新主线程@Overrideprotected void onPostExecute(Void aVoid) {super.onPostExecute(aVoid);adapter.notifyDataSetChanged();}}
}

效果图如下:


学习内容来自动脑学院~

Andriod --- JetPack (六):Room 增删改查相关推荐

  1. Mysql学习笔记(六)增删改查

    原文:Mysql学习笔记(六)增删改查 PS:数据库最基本的操作就是增删改查了... 学习内容: 数据库的增删改查 1.增...其实就是向数据库中插入数据.. 插入语句 insert into tab ...

  2. Andriod --- JetPack (七):Room + ViewModel + LiveData 增删改查实例

    1.Andriod - JetPack (一):初识 JetPack 2.Andriod - JetPack (二):LifeCycle 的诞生 3.Andriod - JetPack (三):Vie ...

  3. Java+MyEclipse+Tomcat (六)详解Servlet和DAO数据库增删改查操作

    此篇文章主要讲述DAO.Java Bean和Servlet实现操作数据库,把链接数据库.数据库操作.前端界面显示分模块化实现.其中包括数据的CRUD增删改查操作,并通过一个常用的JSP网站前端模板界面 ...

  4. 测试开发面经(六)SQL增删改查

    文章目录 测试开发面经(六)SQL增删改查 6. 查询(续) 53).查询未授课教师的姓名和系 54).按职称显示软件学院的教师人数. 55).查询成绩高于<数据结构>平均成绩的学生信息. ...

  5. SQL Server学习之路(六):“增删改查”之“查”

    0.目录 1.前言 2.最基本的SQL查询语句 3.select...from... 3.1 "*"与"Top num *" 3.2 查询指定列 3.3 Isn ...

  6. servlet增删改查实例_SpringBoot系列(2)整合MongoDB实现增删改查(完整案例)

    自己本科时候一直使用的是Mysql,目前的课题组使用的是MongoDB,因此就花了一部分时间整理了一下,实现springboot与MongoDB的整合,并且实现基本的增删改查操作,从头到尾给出一个完整 ...

  7. mongodb基本操作=增删改查

    这两天总算清闲下来了,这里只介绍mongodb的一些基本增删改查,从大到小,从数据库到下面的集合表等,这里推荐一个mongodb的可视化工具Robo3T,在上面操作增删改查使用起来也简单 数据库相关的 ...

  8. GZFramwork数据库层《四》单据主从表增删改查

    同GZFramwork数据库层<三>普通主从表增删改查 不同之处在于:实例 修改为: 直接上效果: 项目源码下载地址:https://github.com/GarsonZhang/GZFr ...

  9. Java对象转JSON时如何动态的增删改查属性

    1. 前言 日常开发中少不了 JSON 处理,少不了需要在 JSON 中添加额外字段或者删除特定字段的需求.今天我们就使用Jackson类库来实现这个功能. 2. JSON 字符串增加额外字段 假如我 ...

最新文章

  1. Dell遇载软件出问题!可能被安装软件含有病毒
  2. Histogram of Oriented Gridients(HOG) 方向梯度直方图
  3. hdu 1811(拓扑排序+并查集)
  4. (视频+图文)机器学习入门系列-第3章 逻辑回归
  5. 12 种主流编程语言输出“ Hello World ”,把我给难住了!
  6. /etc/fstab 文件配置项简单介绍
  7. 是时候“抛弃”谷歌 BERT 模型了!新型预训练语言模型问世
  8. vue : 无法加载文件 C:\Users\1111111\AppData\Roaming\npm\vue.ps1,因为在此系统禁止运行脚本
  9. 思科模拟器:网络安全实验
  10. 《学习笔记》在AngularJS视图中实现指令
  11. Python全栈自动化测试--Pycharm专业版安装
  12. 基于xsh的vbs脚本的使用(简介)
  13. Pytorch介绍以及基本使用
  14. 取得平均薪水最高的部门的部门编号
  15. Base64在线加密解密
  16. 数据结构c语言课程设计报告,(数据结构c语言课程设计报告.doc
  17. layer.open打不开弹窗的问题
  18. 究极小白的第一篇csdn博客
  19. 金山毒霸:猫癣病毒“服务器”现身广东
  20. CIR,CBS,EBS,PIR,PBS 名词解释 令牌桶应用

热门文章

  1. oracle创建表空间脚本
  2. Vim改装编辑器的安装与使用简介
  3. Nginx 学习笔记(四) Nginx+keepalived
  4. iOS crash 崩溃问题的追踪方法
  5. 两台xenserver 同一个vlan中的vm 不能ping通?
  6. 基于opengl的复杂图形三维建模实现
  7. h.265编码库x265实例
  8. FFmpeg RTMP推HEVC/H265流
  9. 面试前必看:Redis 和 Memcached 的区别
  10. 论文笔记:Group Equivariant Convolutional Networks