android room数据库简单使用

news2024/11/16 11:53:33

Room来源
Android采用Sqlite作为数据库存储。由于Sqlite代码写起来繁琐且容易出错,因此,开源社区逐渐出现了各种ORM(Object Relational Mapping)库。常见的有ORMLite, GreenDAO等。Google也意识到推出自家ORM库的必要性,于是有了Room,Room同其他ORM库一样,也是在Sqlite上提供了一层封装。

Room 主要组件

  • Room 包含三个主要组件:
  • (1)(Entity)数据实体,用于表示应用的数据库中的表;
  • (2)(Dao)数据访问对象 (Data Access Objects),提供您的应用可用于插入、删除、更新和查询数据库中的数据的方法。
  • (3)Database数据库类,用于保存数据库并作为应用持久性数据底层连接的主要访问点;

三者关系
Entity:一个Entity对应数据库中的一张表。Entity类是Sqlite表结构对Java类的映射,在Java中可以看作一个Model类。
Dao:数据访问对象(Data Access Objects),我们通过它来访问数据。
一个Entity代表一张表,而每张表都需要一个Dao对象,用于对表进行增删改查;
Room数据库在被实例化之后我们就可以通过数据库实例获取Dao对象,然后通过Dao进行数据库操作。

Room 库架构的示意图

 

一、添加依赖

def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"

二、创建实体类,一个实体类对应数据库中的一张表

package com.example.savedata;

import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;

@Entity
public class Student {
    @PrimaryKey(autoGenerate = true)
    public int id;

    public String stuName;

    public int stuAge;

    public int score;
    @Ignore
    public Student(int id, String stuName, int stuAge, int score) {
        this.id = id;
        this.stuName = stuName;
        this.stuAge = stuAge;
        this.score = score;
    }
    //Ignore亦可注解字段,让Room忽略此方法或者字段
    //由于Room只能识别一个构造器,如果需要定义多个构造器,可以使用Ignore注解让Room忽略这个构造器
    //Room不会持久化被注解Ignore标记过的字段

    public Student(String stuName, int stuAge, int score) {
        this.stuName = stuName;
        this.stuAge = stuAge;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                ", score=" + score +
                '}';
    }
}

三、数据访问对象 (DAO)

  • 定义数据访问对象 (DAO),提供可用于插入、删除、更新和查询数据库中的数据的方法
package com.example.savedata;

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 {

    //插入数据
    @Insert
    public void insertStu(Student... students);

    @Delete
    public void deleteStu(Student... students);

    @Update
    public void updateStu(Student... students);

    //查询所有
    @Query("select * from student")
    public List<Student> queryStu();

    @Query("select * from student where stuName=:name")
    public  List<Student> queryStuByName(String name);

    @Query("select * from student where id=:id")
    public Student queryStuById(int id);
}

四、数据库类


定义数据库配置,并作为应用对持久性数据的主要访问点。
数据库类必须满足以下条件:
(1)该类必须带有 @Database 注解,该注解包含列出所有与数据库关联的数据实体的 entities 数组;
(2)该类必须是一个抽象类,用于扩展 RoomDatabase;
(3)对于与数据库关联的每个 DAO 类,数据库类必须定义一个具有零参数的抽象方法,并返回 DAO 类的实例。
注意:
(1)如果您的应用在单个进程中运行,在实例化 AppDatabase 对象时应遵循单例设计模式。每个 RoomDatabase 实例的成本相当高,而您几乎不需要在单个进程中访问多个实例;
(2)如果您的应用在多个进程中运行,请在数据库构建器调用中包含 enableMultiInstanceInvalidation()。这样,如果您在每个进程中都有一个 AppDatabase 实例,可以在一个进程中使共享数据库文件失效,并且这种失效会自动传播到其他进程中 AppDatabase 的实例。
 

package com.example.savedata;

import android.content.Context;

import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;

@Database(entities = {Student.class},version = 1)
public abstract class StuDatabase extends RoomDatabase {

    private static final String DATABASE_NAME = "student_db";

    private static StuDatabase databaseInstance;

    //结合单例模式完成创建数据库实例
    public static synchronized StuDatabase getDatabaseInstance(Context context) {
        if (databaseInstance == null) {
            databaseInstance = Room.databaseBuilder(context.getApplicationContext(),
                    StuDatabase.class,DATABASE_NAME).build();

        }
        return databaseInstance;
    }

    //将第四步创建的Dao对象以抽象方法的形式返回
    public abstract StudentDao getStudentDao();
}

五、界面

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


    <EditText
        android:id="@+id/etName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="请输入姓名"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/etAge"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="请输入年龄"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/etName" />

    <EditText
        android:id="@+id/etScore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="请输入成绩"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/etAge" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.24" />

    <Button
        android:id="@+id/btnInsertData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="插入数据"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline2" />

    <Button
        android:id="@+id/btnDeleteData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="删除数据"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.501"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnInsertData" />

    <Button
        android:id="@+id/btnQueryData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查询数据"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnDeleteData" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5" />

    <TextView
        android:id="@+id/tvData"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="数据表中的数据"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline4" />

</androidx.constraintlayout.widget.ConstraintLayout>

六、实现(对数据的操作必须在子线程中,否则程序崩溃)

package com.example.savedata;

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    private EditText etName;
    private EditText etAge;
    private EditText etScore;
    private Button btnInsertData;
    private Button btnDeleteData;
    private Button btnQueryData;
    private TextView tvData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        btnInsertData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                insertData();
            }
        });
        btnDeleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                deleteData();
            }
        });

        btnQueryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                queryData();
            }
        });
    }

    private void insertData() {

        new Thread(new Runnable() {
            @Override
            public void run() {
                String stuName = etName.getText().toString();
                int stuAge = Integer.parseInt(etAge.getText().toString());
                int score = Integer.parseInt(etScore.getText().toString());
                Student student1= new Student(stuName,stuAge,score);

                StudentDao dao = StuDatabase.getDatabaseInstance(MainActivity.this).getStudentDao();
                dao.insertStu(student1);
            }
        }).start();


    }
    private void deleteData() {

    }
    private void queryData() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                StudentDao dao = StuDatabase.getDatabaseInstance(MainActivity.this).getStudentDao();
                List<Student> students = dao.queryStu();
                String studentsAll ="";
                for(int i =0;i<students.size();i++){
                    String studentInfo = students.get(i).toString();
                    studentsAll = studentsAll+"\n"+studentInfo;
                }
                dispalayData(studentsAll);

            }
        }).start();

    }

    private void dispalayData(String studentsAll) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                tvData.setText(studentsAll);
            }
        });
    }

    private void initView() {
        etName= findViewById(R.id.etName);
        etAge = findViewById(R.id.etAge);
        etScore = findViewById(R.id.etScore);
        btnInsertData = findViewById(R.id.btnInsertData);
        btnDeleteData = findViewById(R.id.btnDeleteData);
        btnQueryData = findViewById(R.id.btnQueryData);
        tvData = findViewById(R.id.tvData);

    }




}

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

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

相关文章

FE_Vue学习笔记 - 计算属性 监视属性

1 计算属性 1.1 计算属性的引入 组件模板应该只包含简单的表达式&#xff0c;复杂的表达式则应该重构为计算属性或方法。复杂表达式会让你的模板变得不那么声明式。我们应该尽量描述应该出现的是什么&#xff0c;而非如何计算那个值。而且计算属性和方法使得代码可以重用。 …

论文解读|MetaAI图像分割基础模型SAM——解锁数字大脑“视觉区”

原创 | 文 BFT机器人 内容提要 事件背景: 2023年4月5日&#xff0c;MetaAI研究团队发布论文“分割一切”一《Segment Anything》并在官网发布了图像分割基础模型一Segment Anything Model(SAM)以及图像注释数据集Segment-Anything 1-Billion(SA-1B)。 论文核心观点 : 目…

数据库安全+触发器与存储过程

数据库安全触发器与存储过程 目录 数据库安全触发器与存储过程选择题填空题简答题1、建立city值为上海、北京的顾客视图题目代码题解 2、建立城市为上海的客户2016年的订单信息视图题目代码题解 3、创建触发器&#xff0c;当更改商品价格(price列)时&#xff0c;记录价格题目代…

【网络安全】——区块链安全和共识机制

区块链安全和共识机制 摘要&#xff1a;区块链技术作为一种分布式去中心化的技术&#xff0c;在无需第三方的情况下&#xff0c;使得未建立信任的交易双方可以达成交易。因此&#xff0c;区块链技术近年来也在金融&#xff0c;医疗&#xff0c;能源等多个行业得到了快速发展。然…

Medical Image Analyse

NC2022: Federated learning enables big data for rare cancer boundary detection 尽管机器学习&#xff08;ML&#xff09;在各个学科领域都显示出了潜力&#xff0c;但样本外泛化仍然令人担忧。目前通过共享多个站点的数据来解决这个问题&#xff0c;但由于各种限制&#…

内网渗透之linuxwindows密码读取haschcat破解sshrdp

0x00 说明 微软为了防止明文密码泄露发布了补丁KB2871997&#xff0c;关闭了Wdigest功能。 当系统为win10或2012R2以上时&#xff0c;默认在内存缓存中禁止保存明文密码&#xff0c;此时可以通过修改注册表的方式抓取明文&#xff0c;但需要用户重新登录后才能成功抓取。 wind…

知识变现海哥:知识变现的本质就是卖

知识变现的本质就是卖&#xff0c;而有人买的本质&#xff0c;就是你解决了某方面的需求。 好的成交&#xff0c;从来都是相互的&#xff0c; 只靠一边主动推销来维系是远远不够的。 绝对不是靠忽悠&#xff0c;而是靠实力。 先讲一个故事。 19世纪时&#xff0c;一个年轻的…

IOS开发指南之UITableView控件使用

1.创建一个IOS单页应用 2.双击Main.storyboard然后拖放UITableView到视图中 3.添加TableViewCell 成功添加Table View Cell 4.修改Table View Cell属性 选中Table View Cell 在右边的Image栏输入default.png回车 到此布局设计完成,现在运行还是显示 空白,要在代码中做相关的实…

B.【机器学习实践系列二】数据挖掘-二手车价格交易预测(含EDA探索、特征工程、特征优化、模型融合等)

【机器学习入门与实践】入门必看系列&#xff0c;含数据挖掘项目实战&#xff1a;数据融合、特征优化、特征降维、探索性分析等&#xff0c;实战带你掌握机器学习数据挖掘 专栏详细介绍&#xff1a;【机器学习入门与实践】合集入门必看系列&#xff0c;含数据挖掘项目实战&…

Spellman高压电源X射线发生器维修XRB160PN480X4593

spellman高压发生器维修VMX40P5X4629&#xff1b;Spellman X射线发生器维修X4593系列 X射线源维修。 Spellman所拥有的变频器架构可以使高压电源获得高利用率的效率和功率密度。固体密封的高压模块进一步减少了尺寸和重量。 基于表面贴装控制电路的数字信号处理器提供通讯接口…

2023,谁还在花钱减肥?

【潮汐商业评论/原创】 “这是益生菌、酵素、0蔗糖酸奶&#xff0c;促进肠胃蠕动的&#xff1b;这是蒟蒻果冻、魔芋零食&#xff0c;嘴馋占嘴用的&#xff1b;这是全麦面包&#xff0c;饱腹感强&#xff0c;不易发胖&#xff1b;这是我刚办的健身卡&#xff1b;这是……”Lily…

【Qt编程之Widgets模块】-007:QTextStream类及QDataStream类

1 概述 QTextStream和QDataStream都是对流进行操作 QTextStream只能普通类型的流操作像QChar、QString、int…&#xff0c;其实就很类似我们c或者c中读写文件的感觉&#xff0c; QDataStream就厉害了&#xff0c;无论是QTextStream的普通类型的流操作还是一些特殊类型的流操作…

设计模式之【外观/门面模式】,不打开这扇门永远不知道门后有多少东西

文章目录 一、什么是外观模式&#xff08;门面模式&#xff09;1、外观模式的结构2、使用场景3、外观模式的优缺点4、外观模式注意事项 二、实例1、外观模式的通用写法2、智能家居案例3、积分换礼品案例 参考资料 一、什么是外观模式&#xff08;门面模式&#xff09; 外观模式…

yoloV5项目工程源码解读(2)(未完成)

概述 将主要从三个部分对源码进行解读。 数据层面&#xff0c;dataloader 和 数据增强网络模型&#xff0c;模型细节和逻辑模型训练&#xff0c;训练策略等 数据源解读 utils 中有&#xff0c;在train.py中能跳到该函数。 train.py中 # Trainloader 创建dataloader就是我们…

网络安全工程师辛苦吗?

“人生如寄&#xff0c;何事辛苦怨斜晖”&#xff0c;意思是人活着就像寄生在这个世界上&#xff0c;为什么一定要劳碌奔波&#xff0c;最后还抱怨人生苦短呢&#xff1f; 但说到辛苦二字&#xff0c;什么工作不辛苦呢&#xff1f;除了体制内的一些工作稍微轻松一些&#xff0c…

打家劫舍问题

题目&#xff1a; 打家劫舍https://leetcode.cn/problems/house-robber/ 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上…

重写Properties类,实现对properties文件的有序读写,数据追加,解决中文乱码

前言 *.properties文件&#xff0c;是 Java 支持的一种配置文件类型&#xff0c;并且 Java 提供了 properties 类来读取 properties 文件中的信息。文件中以键值对 "键值"的形式&#xff0c;存储工程中会多次重复使用的配置信息&#xff0c;通过“Properties”类来读…

【Mysql实战】使用存储过程和计算同比环比

背景 同环比&#xff0c;是基本的数据分析方法。在各类调研表中屡见不鲜&#xff0c;如果人工向前追溯统计数据&#xff0c;可想而知工作量是非常大的。 标题复制10行&#xff0c;并且每行大于10个字符【源码解析】SpringBoot接口参数【Mysql实战】使用存储过程和计算同比环比…

超全总结:硬件设计基础60条

硬件是一个非常复杂的系统&#xff0c;在设计过程中都会遇到或多或少的问题&#xff0c;本文中总结了非常基础的60个问题&#xff0c;供大家参考。 1、请说明一下滤波磁珠和滤波电感的区别。 磁珠由导线穿过铁氧体组成&#xff0c;直流电阻很小&#xff0c;在低频时阻抗也很小…

数字化转型,目的是为了转型还是数字化?

受第四次工业革命浪潮的影响&#xff0c;传统工业经济社会快速向数字经济转型过渡&#xff0c;企业创新面临的经济环境发生根本性变革。数字技术广泛应用于生产、交换、消费等经济环节&#xff0c;为企业产品创新、服务创新以及数字化开放式创新提供了动力源泉。数字经济背景下…