Android--Jetpack--数据库Room详解二

本是青灯不归客,却因浊酒恋红尘

一,基本使用

关于Room数据库的基本使用,请参考文章Android--Jetpack--数据库Room详解一-CSDN博客

二,Room与ViewModle,LiveData的结合使用

LiveData与ViewModle的使用,请参考文章Android--Jetpack--LiveData-CSDN博客

我们通过结合Room与LiveData和ViewModle的使用,可以使当我们的数据库发生变化的时候,自动的去更新UI。

下面来看一个简单的使用案例:

1,还是 Android--Jetpack--数据库Room详解一-CSDN博客

中创建的数据库,表还是YuanZhen这张表, 我们把YuanZhenDao这个Dao类添加一个新的方法,使得可以查询到LiveData包装的集合:

@Dao
public interface YuanZhenDao {@Insertvoid insert(YuanZhen... yuanzhens);@Deletevoid delete(YuanZhen yuanZhen);@Updatevoid update(YuanZhen yuanZhen);@Query("select * from YuanZhen")List<YuanZhen> getAll();@Query("select * from YuanZhen where name like :name")YuanZhen getByName(String name);@Query("select * from YuanZhen where age in(:ages)")List<YuanZhen> getByAges(int[] ages);@Query("select name,address from YuanZhen ")public List<YuanZhenNew> getNew();@Query("select * from YuanZhen")LiveData<List<YuanZhen>> getAllLiveDataYZ();
}

2,将数据库MyDatabase修改为单例模式:

@Database(entities = {YuanZhen.class},version = 1)
public abstract class MyDatabase extends RoomDatabase {private static MyDatabase instance;public static synchronized MyDatabase getInstance(Context context){if(instance==null){instance= Room.databaseBuilder(context.getApplicationContext(),MyDatabase.class,"YuanZhenDb").build();}return instance;}public abstract YuanZhenDao yuanZhenDao();}

3,创建一个包装类,包装LiveData给ViewModel使用:

public class YuanZhenDecorate {private LiveData<List<YuanZhen>> liveDataAllYZ;private YuanZhenDao yuanZhenDao;public YuanZhenDecorate(Context context) {yuanZhenDao =MyDatabase.getInstance(context).yuanZhenDao();if(liveDataAllYZ==null){liveDataAllYZ=yuanZhenDao.getAllLiveDataYZ();}}void insert(YuanZhen... yuanZhens){yuanZhenDao.insert(yuanZhens);}void delete(YuanZhen yuanZhen){yuanZhenDao.delete(yuanZhen);}void update(YuanZhen yuanZhen){yuanZhenDao.update(yuanZhen);}List<YuanZhen> getAll(){return yuanZhenDao.getAll();}LiveData<List<YuanZhen>> getAllLiveDataYZ(){return yuanZhenDao.getAllLiveDataYZ();}}

4,创建一个viewmodle:

public class YZViewModdel extends AndroidViewModel {private YuanZhenDecorate yuanZhenDecorate;public YZViewModdel(@NonNull Application application) {super(application);yuanZhenDecorate =new YuanZhenDecorate(application);}void insert(YuanZhen... yuanZhens){yuanZhenDecorate.insert(yuanZhens);}void delete(YuanZhen yuanZhen){yuanZhenDecorate.delete(yuanZhen);}void update(YuanZhen yuanZhen){yuanZhenDecorate.update(yuanZhen);}List<YuanZhen> getAll(){return yuanZhenDecorate.getAll();}LiveData<List<YuanZhen>> getAllLiveDataYZ(){return yuanZhenDecorate.getAllLiveDataYZ();}}

5,创建一个recyclerview的adapter:

public class MyAdapter extends RecyclerView.Adapter {private LayoutInflater mLayoutInflater;private List<YuanZhen> mList;public MyAdapter(Context context,List<YuanZhen> mList) {mLayoutInflater =LayoutInflater.from(context);this.mList =mList;}public void setData(List<YuanZhen> mList) {this.mList = mList;}@NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {return new ViewHolder(mLayoutInflater.inflate(R.layout.item, parent, false));}@Overridepublic void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {((ViewHolder)holder).mTxt.setText(mList.get(position).getName());}@Overridepublic int getItemCount() {if(mList!=null){return mList.size();}return 0;}class ViewHolder extends RecyclerView.ViewHolder {TextView mTxt;public ViewHolder(@NonNull View itemView) {super(itemView);mTxt = (TextView) itemView.findViewById(R.id.txt);}}}

 6,activity的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.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_room"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

7,item的xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"><TextViewandroid:id="@+id/txt"android:layout_width="match_parent"android:layout_height="30dp"android:textSize="16sp"/></RelativeLayout>

 8,使用:

public class MainActivity extends AppCompatActivity {StudentViewModel studentViewModel;ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView = findViewById(R.id.listView);studentViewModel = ViewModelProviders.of(this).get(StudentViewModel.class);studentViewModel.getAllLiveDataStudent().observe(this, new Observer<List<Student>>() {@Overridepublic void onChanged(List<Student> students) {listView.setAdapter(new GoodsAdapter(MainActivity.this, students));}});for (int i = 0; i < 50; i++) {studentViewModel.insert(new Student("jett", "123", 1));}new Thread() {@Overridepublic void run() {for (int i = 0; i < 50; i++) {try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}studentViewModel.update(new Student(6, "jett" + i, "123", 1));}}}.start();}
}

 9,运行:

 

三,数据库的升级

1,强制升级,执行之后数据库的结构会发生变化,但是数据库的数据会丢失。

这种情况比较适合toB开发,数据库版本高降到低的情况,紧急发一版新的程序给现场升级。

使用 :fallbackToDestructiveMigration()

@Database(entities = {YuanZhen.class},version = 2)
public abstract class MyDatabase extends RoomDatabase {private static MyDatabase instance;public static synchronized MyDatabase getInstance(Context context){if(instance==null){instance= Room.databaseBuilder(context.getApplicationContext(),MyDatabase.class,"YuanZhenDb")//强制升级.fallbackToDestructiveMigration().build();}return instance;}public abstract YuanZhenDao yuanZhenDao();}

 2,一般的升级方式

假如我们要增加一个字段price:

@Entity
public class YuanZhen {@PrimaryKey(autoGenerate = true)private int id;@ColumnInfo(name ="name")private String name;@ColumnInfo(name ="age")private int age;@ColumnInfo(name ="address")private String address;@ColumnInfo(name = "price")private int price;@Ignoreprivate String sex;public YuanZhen(String name, int age, String address) {this.name = name;this.age = age;this.address = address;}public void setId(int id) {this.id = id;}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 int getId() {return id;}public String getName() {return name;}public int getAge() {return age;}public String getAddress() {return address;}@Overridepublic String toString() {return "YuanZhen{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", address='" + address + '\'' +", sex='" + sex + '\'' +'}';}
}

在MyDatabase中增加升级功能:

@Database(entities = {YuanZhen.class},version = 2,exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {private static MyDatabase instance;public static synchronized MyDatabase getInstance(Context context){if(instance==null){instance= Room.databaseBuilder(context.getApplicationContext(),MyDatabase.class,"YuanZhenDb")//强制升级// .fallbackToDestructiveMigration().addMigrations(MIGRATION_1_2).build();}return instance;}public abstract YuanZhenDao yuanZhenDao();static final Migration MIGRATION_1_2=new Migration(1,2) {@Overridepublic void migrate(@NonNull SupportSQLiteDatabase database) {//在这里用sql脚本完成数据变化database.execSQL("alter table yuanzhen add column price integer not null default 1");}};}

这里和greendao最大的不同就是,这里需要自己去写升级脚本,虽然增加了工作量,但是也更加灵活了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑移动式储能调度的配电网灾后多源协同孤岛运行策略》

这篇文章的标题表明研究的主题是在配电网发生灾害后&#xff0c;采用一种策略来实现多源协同孤岛运行&#xff0c;并在这个过程中特别考虑了移动式储能的调度。 让我们逐步解读标题的关键词&#xff1a; 考虑移动式储能调度&#xff1a; 文章关注的焦点之一是移动式储能系统的…

国标GB28181安防监控系统/磁盘阵列EasyCVR(V.3.4)新亮点:免保活功能

TSINGSEE青犀近日发布了EasyCVR安防管理平台的V.3.4版本&#xff0c;其中一大亮点就是很多朋友都在咨询的“免保活”功能&#xff0c;那么&#xff0c;什么是“免保活”功能&#xff1f;又该如何配置呢&#xff1f; 在EasyCVR平台有个【按需直播】按钮&#xff0c;顾名思义&…

ARM流水灯

.text .global _start _start: LED1 1.RCC时钟使能GPIOE RCC_MP_AHB4ENSETR[4]->1 LDR R0,0x50000a28 LDR R1,[R0] ORR R1,R1,#(0x1<<4) STR R1,[R0] 2.设置PE10为输出模式 GPIOE_MODER[21:20]->01 先清0 LDR R0,0x50006000 LDR R1,[R0] BIC R1,R1,#(0x3<&…

Linux | 多线程

前言 本文主要介绍多线程基础知识&#xff0c;以及使用多线程技术进行并发编程&#xff1b;最后会介绍生产者消费者模型&#xff1b; 一、线程基本认识 1、什么是线程 如果你是科班出生&#xff0c;你肯定听过线程相关概念&#xff1b;但是你可能没有真正搞懂什么是线程&#…

集群监控Zabbix和Prometheus

文章目录 一、Zabbix入门概述1、Zabbix概述2、Zabbix 基础架构3、Zabbix部署3.1 前提环境准备3.2 安装Zabbix3.3 配置Zabbix3.4 启动停止Zabbix 二、Zabbix的使用与集成1、Zabbix常用术语2、Zabbix实战2.1 创建Host2.2 创建监控项&#xff08;Items&#xff09;2.3 创建触发器&…

以太网协议与DNS

以太网协议 以太网协议DNS 以太网协议 以太网用于在计算机和其他网络设备之间传输数据,以太网既包含了数据链路层的内容,也包含了物理层的内容. 以太网数据报: 其中目的IP和源IP不是网络层的目的IP和源IP,而是mac地址.网络层的主要负责是整体的转发过程,数据链路层负责的是局…

Data Mining数据挖掘—2. Classification分类

3. Classification Given a collection of records (training set) – each record contains a set of attributes – one of the attributes is the class (label) that should be predicted Find a model for class attribute as a function of the values of other attribu…

Vue3中使用tinymce, tinymce上传图片,tinymce使用emoji表情

1.效果图 2. 安装 npm i tinymce npm i tinymce/tinymce-vue在node_modules文件夹中找到tinymce下的skins复制到项目public文件夹中子组件 <template><editor v-model"myValue" :init"init" :disabled"disabled" :id"tinymceId&…

小型洗衣机哪个牌子质量好?五款高性价比内衣洗衣机推荐

随着内衣洗衣机的流行&#xff0c;很多小伙伴在纠结该不该入手一款内衣洗衣机&#xff0c;专门来洗一些贴身衣物&#xff0c;答案是非常有必要的&#xff0c;因为我们现在市面上的大型洗衣机只能做清洁&#xff0c;无法对我们的贴身衣物进行一个高强度的清洁&#xff0c;而小小…

浅谈 USB Bulk 深入浅出 (3) - USB Bulk 装置传输的注意事项

来源&#xff1a;大大通 作者&#xff1a;冷氣團 1 USB Bulk 是什么 USB 是即插即用使用差动信号的装置界面&#xff0c;是以 端点 ( Endpoint )&#xff0c;做为传输装置的输出入端&#xff0c;透过不同的端点 ( Endpoint ) 和模式&#xff0c;来进行与装置的沟通&#xff…

antv - G6 绘制1:N N:1 跨节点的graph

文章目录 hover时候&#xff0c;当前节点高亮&#xff0c;且直接相连的线和节点也高亮展示&#xff08;展示直接关系&#xff09;节点的label超过10个字的时候&#xff0c;文本溢出&#xff0c;且hover有tooltip&#xff1b;小于10个字&#xff0c;没有tooltiptootip使用插件mo…

getchar的功能和用法

getchar()是C语言中的一个标准库函数&#xff0c;用于从标准输入&#xff08;通常是键盘&#xff09;读取一个字符&#xff0c;并将其作为int类型返回。它通常用于从键盘获取用户输入。 getchar()函数在程序中等待用户输入&#xff0c;当用户输入一个字符并按下回车键后&#…

Vue路由跳转重定向动态路由VueCli

Vue路由跳转&重定向&动态路由&VueCli 一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话&#xff0c;需要给当前跳转的导航加样式&#xff0c;同时要移除上一个a标签的样式&#xff0c;太麻烦&#xff01;&#xff01;&#xff01; …

做题总结 160.链表相交

160.链表相交 我的思路代码改进 LeetCode&#xff1a;给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 我的思路 计算链表A、B的长度count1、count2。临时指针curA、curB要同时指向…

SpringMVC学习笔记

先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;❤️ ❤️ ❤️ 资源收集不易&#xff0c;如果喜欢可以关注我哦&#xff01; ​如果本篇内容对你有所启发&#xff0c;欢迎访问我的个人博客了解更多内容&#xff1a;链接地址 是什么 Spring MVC是Spring框架…

C++面向对象(OOP)编程-友元(友元函数和友元类)

本文主要介绍面向对象编程的友元的使用&#xff0c;以及友元的特性和分类&#xff0c;提供C代码。 1 为什么引进友元 面向对象编程&#xff08;OOP&#xff09;的三大特性中的封装&#xff0c;是通过类实现对数据的隐藏和封装。一般定义类的成员变量为私有成员&#xff0c;成员…

模拟目录管理 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 200分 题解: Java / Python / C++ 题目描述 实现一个模拟目录管理功能的软件,输入一个命令序列,输出最后一条命令运行结果。 支持命令: 1)创建目录命令: mkdir 目录名称,如mkdir abc为在当前目录创建abc目录,如果已存在同名目录则不执行任何操作…

CentOS7安装 Docker Compose

docker系列 CentOS7安装 Docker Compose docker系列前言1、下载 Docker Compose2、 授权执行权限3、添加软链接4、验证安装 前言 下面的操作是在centos7中完成的。这里安装的是2.23.3版本的docker-compose。 1、下载 Docker Compose 确保你具有 curl 工具&#xff0c;然后使用…

每个开发人员都想使用的编程语言

在任何时候&#xff0c;一些编程语言都会把大量的开发人员变成热情的布道者&#xff0c;试图说服世界其他地方的人相信它的伟大。 当热起来的时候&#xff0c;这种语言可能会成为行业标准&#xff0c;但其他时候&#xff0c;这种受欢迎程度就会消失。 在这个故事中&#xff0…

【JVM从入门到实战】(五)类加载器

一、什么是类加载器 类加载器&#xff08;ClassLoader&#xff09;是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。 类加载器只参与加载过程中的字节码获取并加载到内存这一部分。 二、jdk8及之前的版本 类加载器分为三类&#xff1a; 启动类加载器-加载Ja…