android数据的储存、文件的储存、SharedPreferences储存、SQLite的基本用法

一、文件的储存

1、将数据储存到文件中

Context类中提供了openfileOutput()方法,用来获取一个文件流,这个方法接收两个参数,第一个参数是文件名,在文件创建的时候使用的就是这个名称,注意这里指定的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data/iles/目录下的。第二个参数是文件的操作模式,主要有两种模式可选,MODE_PRIVATE和MODE_APPEND。

MODE_PRIVATE:会覆盖源文件数据

MODE_APPEND:在源文件后追加数据

将文本内容保存到文件的代码展示:

public void save(){String Data = "Data on save";//创建一个文件流FileOutputStream out = null;//创建一个缓存流BufferedWriter writer  = null;try {//打开这个文件流out = openFileOutput("data",MODE_PRIVATE);//将文件流转化转换流,在通过转换流得到缓存流writer = new BufferedWriter(new OutputStreamWriter(out));//通过缓存流写入数据writer.write(Data);}catch (IOException e){e.printStackTrace();}finally {if(writer != null){try {writer.close();} catch (IOException e) {e.printStackTrace();}}}
}

在这里插入图片描述

2、从文件中读取数据

Context类中还提供了一个openFileInput()方法,用于读取文件。只接收一个参数及要读取的文件名。

读取数据代码如下:

    private String load() {FileInputStream fileInputStream = null;BufferedReader bufferedReader = null;StringBuilder builder = new StringBuilder();try {fileInputStream = openFileInput("data");bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));String leng = "";while ((leng = bufferedReader.readLine()) != null){builder.append(leng);}} catch (IOException e) {e.printStackTrace();}finally {if(bufferedReader != null){try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}return builder.toString();}
  • bufferedReader.lines()用于处理大型文件,通过返回一个字符串流(Stream<String>)来处理每一行数据。直接返回所有内容,不需要判读是否读取结束。

  • bufferedReader.readLine()用于读取文件的一行文本数据,并返回一个字符串。读取结束时返回null

  • bufferedReader.read()用于逐个读取字符的整数值,并需要自己处理字符的连接以获取完整的文本数据。这种方法更适合处理二进制数据或特殊的文本处理场景。

  • int len = 0; //文件读取长度
    byte[] careBuffer = new byte[1024]; //1kb
    while ((len = buff.read(careBuffer)) != EOF) {buff1.write(careBuffer, 0, len);
    }
    

二、SharedPreferences

1、获取SharedPreferences对象的两种方式

1.1 Context类中的getSharedPreferences()

该方法接受两个参数,第一个参数是文件名,第二个参数是MODE_PRIVATE和直接传入0的效果一样,表示只有当前程序才可以对Sharedpreferences进行读写操作。

1.2 Activity类中的getPreferences()方法

这个方法和Context中的getSharedPreferences()方法很相似,不过它只接收一个操作模式参数(MODE_PRIVATE),因为使用这个方法时会自动将当前活动的类名作为SharedPreferences的文件名。

2、将数据储存到SharedPreferences

1.1实现步骤

a、得到SharedPreferences对象以后调用edit()方法获取一个内部类的SharedPreferences.Editor.

b、向Editor对象中添加数据,例如添加字符串就使用putString(),添加int类型数据就使用putInt()

c、使用apply()方法提交数据完成储存

2.2 实现代码

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText = findViewById(R.id.edit);SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();editor.putString("username", "lukecc0");editor.putString("age", "1");editor.putBoolean("married", false);editor.apply();}

image-20230726104314471

username就相当于key,在SharedPreferences中,每个数据都有一个关联的键(key),通过这个键可以访问相应的值(value)。通过SharedPreferences.Editor对象,你可以添加、编辑或删除这些键值对。

3、从SharedPrefrences中读取数据

SharedPreferences对象中提供了一系列的get方法,用于对存储的数据进行读取,每种get方法都对应SharedPreferences.Editor中的一种put方法

比如读取一个布尔型数据就使用getBoolean()方法,读取一个字符中就使用getString()方法。

这些get方法都接收两个参数,第一个参数是键,传入存储数据时使用的键就可以得到相应的值了,第二个参数是默认值,即表示当传入的键找不到对应的值时会以什么样的默认值进行返回。

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText = findViewById(R.id.edit);Button button = findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//读取数据SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE);editText.setText(pref.getString("username","admin")+"\n"+pref.getString("age","0")+"\n"+pref.getBoolean("marride",false));}});}

当点击按钮后就会出现数据,如下图:

image-20230726105720243

image-20230726105730897

三、SQLite

1、创建数据库

建立一个MyDatabase类继承SQLite

重写onCreate、onUPgrade方法

获得MyDatabase的实例

选择打开方式打开

SQLiteOpenHelper是一个抽象类,这意味着如果我们想要使用它的话,就需要创建一个自己的帮助类去继承它。SQLiteOpenHelper中有两个抽象方法,分别是onCreate()onUpgrade()我们必须在自己的帮助类里面重写这两个方法,然后分别在这两个方法中去实现创建、升级数据库的逻辑。

SQLiteOpenHelper中还有两个重要的实例方法,getReadableDatabasegetwirtableDatabase,这两个方法的可以创建或打开一个数据库,不同的是如果磁盘满了的情况下:

  • getReadableDAtabase方法返回的对象将以只读的方式打开数据库

  • getWritableDatabase方法将会出现异常

SQL建立表语句:

create table Book(id integer primary key autoincrement,author text,price real,pages integer,name text)

integer表示整型,real表示浮点型,txt表示文本类型,blob表示二进制类型,primary key设置主键,autoincrement显示id是自动增长的。

public class MyDatabaseHelper extends SQLiteOpenHelper {public static final String CREATE_BOOK = "create table Book("+ "id integer primary key autoincrement,"+ "author text,"+ "price real,"+ "pages integer,"+ "name text)";public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);mContext = context;}@Overridepublic void onCreate(SQLiteDatabase sqLiteDatabase) {//创建数据库,参数为建库语句sqLiteDatabase.execSQL(CREATE_BOOK);Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();}@Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {}
}

**public SQLiteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version)**构造方法的含义:

  • context:Android 应用程序的上下文
  • name: 这是要创建或打开的数据库的名称。如果数据库不存在SQLiteOpenHelper 会创建一个新的数据库文件,如果数据库已经存在,它将尝试打开该数据库。这里传入的数据库名称可以是一个字符串,表示数据库的名称。
  • factory:这是一个用于创建游标对象的工厂。游标是用于查询数据库并遍历结果集的对象。通常情况下,你可以传入 null
  • version:这是数据库的版本号。当应用程序需要进行数据库结构的更改时,你需要增加数据库版本号。

在MainActivity中使用数据库

public class MainActivity extends AppCompatActivity {private MyDatabaseHelper dbHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建一个数据库的帮助类dbHelper = new MyDatabaseHelper(this,"BookStore.dp",null,2);Button button =findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {创建数据库dbHelper.getWritableDatabase();}});}
}

那么如何看到这个数据库呢?请参考android官方开发文档

查询数据库

2、更新数据库

使用onUpgrade更新数据库。

例如现在需要再建立一个表,如果已经建好表的情况下,onCreate是不会再继续执行的。因此这样的在onCreate中直接加入建表语句是不行的。

private static final String Category = "create table Category("+ "id integer primary key autoincrement,"+ "Category_name text,"+ "Category_code integer)";@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {//创建数据库,参数为建库语句sqLiteDatabase.execSQL(CREATE_BOOK);sqLiteDatabase.execSQL(Category);Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}

因此我们需要在onUpgrade中编写代码逻辑。

drop table if exists:是一个 SQL 语句,用于删除表,使用这个语句时要小心,因为一旦执行,表中的所有数据将被永久删除,并且无法恢复。这通常用于在数据库中不再需要某个表时进行清理。

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {sqLiteDatabase.execSQL("drop table if exists Book");sqLiteDatabase.execSQL("drop table if exists Gategory");onCreate(sqLiteDatabase);
}

在上述这段代码中,会先删除两个表,然后重新创建两个表。主要原表的数据将会被清空。如何实现不清空原表数据?如果有SQL基础请看下面这段代码,没有请自行忽略这个问题。

    @Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {// 备份旧表数据sqLiteDatabase.execSQL("CREATE TABLE Book_backup AS SELECT * FROM Book");// 删除旧的 Book 表sqLiteDatabase.execSQL("DROP TABLE IF EXISTS Book");// 创建新的 Book 表sqLiteDatabase.execSQL(CREATE_BOOK);// 将备份表数据复制到新表中sqLiteDatabase.execSQL("INSERT INTO Book (id, author, price, pages, name) SELECT id, author, price, pages, name FROM Book_backup");// 删除备份表sqLiteDatabase.execSQL("DROP TABLE IF EXISTS Book_backup");Toast.makeText(mContext, "Database upgraded successfully", Toast.LENGTH_SHORT).show();}

接下来我们需要让onUpgrade 可以执行,在使用MyDatabase的构造方法时,修改最后一个传递参数version,他显示的数据库版本,我们之前使用的是1,现在传递一个比1大的数即可。

3、添加数据——insert

前面我们已经知道,调用SQLiteOpenHelpergetReadableDatabase()getwritable-Datābase()方法是可以用于创建和升级数据库的。

不仅如此,这两个方法还都会返回一个SQLiteDatabase对象,借助这个对象就可以对数据进行CRUD操作了。

**SQLiteDatabase提供了一个insert方法,用于添加数据。**它需要三个参数。

第一个参数是表名,我们需要往哪个表加入数据就写哪个表名。

第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,一般我们用不到这个功能,直接传入null即可。

第三个参数是一个ContentValues对象,它提供了一系列的put()方法重载,用于向ContentValues中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。

binding.button1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();//将数据保存起来,第一条数据values.put("name","This is one");values.put("author","dow");values.put("pages",23);values.put("price",12);//添加数据db.insert("Book",null,values);//将数据保存起来,第二条数据values.put("name","This is two");values.put("author","dow1");values.put("pages",231);values.put("price",112);db.insert("Book",null,values);}
});

点击这个按钮,我们每次向数据库中保存两条数据。

image-20230726164911477

为什么没有给id赋值?因为我们在建表时已经设置为了自动增长

id integer primary key autoincrement

4、更新数据——updata

binding.button2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put("price",110);//更新所有名为This is one的书db.update("Book",values,"name = ?",new String[]{"This is one"});}
});

5、删除数据——delete

//删
binding.button3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {SQLiteDatabase db = dbHelper.getWritableDatabase();db.delete("Book","pages > ?",new String[]{"200"});}
});

指定删除pages大于200的书。

6、查询数据——query

query具有7个参数

image-20230726180033182

它会返回一个Cursor对象,这个对象中保存了数据库的信息,查询的所有数据都从这个对象中取出。

//查
binding.button4.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {SQLiteDatabase db = dbHelper.getWritableDatabase();Cursor cursor = db.query("Book",null,null,null,null,null,null);if(cursor.moveToFirst()){do {String name = cursor.getString(cursor.getColumnIndex("name"));int price = cursor.getInt(cursor.getColumnIndex("price"));Log.d("TAG1",name);Log.d("TAG1",price+"");}while (cursor.moveToNext());}}
});

image-20230726180206424

moveToFirst方法,将数据的指针移到开头第一行的位置。然后进入一个循环读取数据,在while中使用moveToNext方法每次将数据指针向下移动一位。getColumnIndex方法用于获取指定某一列在表中的位置。

如下表,先获取了name、price的位置,然后通过这个位置取得了该位置上的数据。

image-20230726180541150

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

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

相关文章

FPGA XDMA 中断模式实现 PCIE3.0 AD7606采集 提供2套工程源码和QT上位机源码

目录 1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案AD7606数据采集和缓存XDMA简介XDMA中断模式QT上位机及其源码 5、vivado工程1--BRAM缓存6、vivado工程2--DDR4缓存7、上板调试验证8、福利&#xff1a;工程代码的获取 1、前言 PCIE&#xff08;PCI Express&am…

redis之Bitmap

位图数据结构其实并不是一个全新的玩意&#xff0c;我们可以简单的认为就是个数组&#xff0c;只是里面的内容只能为0或1而已(二进制位数组)。 GETBIT用于返回位数组在偏移量上的二进制位的值。值得我们注意的是&#xff0c;GETBIT的时间复杂度是O(1)。 GETBIT命令的执行过程如…

matplotlib从起点出发(6)_Tutorial_6_Animations

1 在matplotlib中使用动画 基于其绘图功能&#xff0c;matplotlib还提供了一个使用动画模块生成动画animation的接口。动画是一系列帧&#xff0c;其中每个帧对应于图形Figure 上的一个绘图。本教程介绍了有关如何创建此类动画的一般准则以及可用的不同选项。 import matplot…

行为型设计模式之观察者模式【设计模式系列】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 设计模式系列 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everythi…

解决报错Avoid using non-primitive value as key, use string/number value instead.

找到图中画圈的文件这个错误信息的意思是要避免使用非基本值作为键&#xff0c;而是使用字符串/数字值代替。 [1] 这个错误通常出现在使用<el-select>中的<el-option>进行循环遍历值时。 [2] 这个错误的解决方案是检查是否有重复的键值&#xff0c;并确保使用字符…

【分布鲁棒、状态估计】分布式鲁棒优化电力系统状态估计研究[几种算法进行比较](Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

基于BIM+AI的建筑能源优化模型【神经网络】

推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 AEC&#xff08;建筑、工程、施工&#xff09;行业的BIM 技术&#xff0c;允许在实际施工开始之前虚拟地建造建筑物&#xff1b; 这带来了许多有形和无形的好处&#xff1a;减少成本超支、更有效的协调、增强决策权等等。…

C#实现数据库数据变化监测(sqlservermysql)

监测数据库表数据变化&#xff0c;可实现数据库同步&#xff08;一主一从&#xff08;双机备份&#xff09;&#xff0c;一主多从&#xff08;总部数据库&#xff0c;工厂1&#xff0c;工厂2&#xff0c;工厂数据合并到总部数据&#xff09;&#xff09; sqlserver 启用数据库…

Flowable-服务-消息任务

文章目录 定义图形标记XML内容集成Rabbitmq引入pom包配置rabbitmq 操作界面 定义 Mq 任务不是 BPMN 2.0 规范定义的官方任务&#xff0c;在 Flowable 中&#xff0c;Mq 任务是作为一种特殊的服务 任务来实现的&#xff0c;主要做Mq消息发送。 图形标记 由于 Mq 任务不是 BPM…

用CSS和HTML写一个水果库存静态页面

HTML代码&#xff1a; <!DOCTYPE html> <html> <head><link rel"stylesheet" type"text/css" href"styles.css"> </head> <body><header><h1>水果库存</h1></header><table>…

list与sort()

运行代码&#xff1a; //list与sort() #include"std_lib_facilities.h" //声明Item类 struct Item {string name;int iid;double value;Item():name(" "),iid(0),value(0.0){}Item(string ss,int ii,double vv):name(ss),iid(ii),value(vv){}friend istre…

【Golang 接口自动化01】使用标准库net/http发送Get请求

目录 发送Get请求 响应信息 拓展 资料获取方法 发送Get请求 使用Golang发送get请求很容易&#xff0c;我们还是使用http://httpbin.org作为服务端来进行演示。 package mainimport ("bytes""fmt""log""net/http""net/url&qu…

Shell 排序法 - 改良的插入排序

说明 插入排序法由未排序的后半部前端取出一个值&#xff0c;插入已排序前半部的适当位置&#xff0c;概念简单但速度不快。 排序要加快的基本原则之一&#xff0c;是让后一次的排序进行时&#xff0c;尽量利用前一次排序后的结果&#xff0c;以加快排序的速度&#xff0c;Shel…

ZLMediaKit+wvp-GB28181-pro 安装文档

文章目录 前言1. 安装zlm1.1 镜像说明1.2 docker安装1.2.1 docker安装命令1.2.2 docker-compose安装 1.3. zlm配置和日志重点说明 2. 安装wvp2.1 目录结构说明2.1.1 导入idea2.1.2 sql文件夹自带初始化库脚本2.1.3 进入web_src 编译静态资源2.1.4 修改resources配置 2.2 wvp 启…

DHCP中继代理原理(第二十八课)

当客户机和DHCP服务器不在一个广播域时,DHCP服务器无法接收到客户机的DHCP discover广播数据包,客户机就无法获得IP地址 第一步配置DHCP服务器的信息 <Huawei>u t m //清除日志 Info: Current terminal monitor is off. <Huawei>sys [Huawei]sysname DHCP-R…

IOS开发:去除TabView的底部留白

我最近在做IOS开发的时候&#xff0c;使用SwiftUI中的TabView做左右滚动的页面切换&#xff0c;遇到了页面底部有大量留白无法去除的问题&#xff1a; 我查了很多资料都没有看到网上有人记录这个问题的解决方案&#xff0c;后来查阅apple developer的文档&#xff0c;我发现.ed…

【计算机视觉|人脸建模】深度学习时代的3D人脸重建调查报告

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;3D Face Reconstruction in Deep Learning Era: A Survey 链接&#xff1a;3D Face Reconstruction in Deep Learning Era: A Survey - PubMed (nih.gov) 摘要 随着深度学习的出现和图形…

前端学习--vue2--2--vue指令基础

写在前面&#xff1a; 前置内容 - vue配置 文章目录 插值表达式v-html条件渲染v-show和v-ifv-ifv-if的扩展标签复用组件 v-show v-on /事件v-bind /&#xff1a;属性v-modelv-for 循环元素v-slotv-prev-cloak vue指令只的是带有v-前缀的特殊标签属性 插值表达式 插值表达式{…

cglib动态代理、jdk动态代理及spring动态代理使用

1.项目初始化 1.1 pom.xml <dependencies><!-- spring依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.5.RELEASE</version></dependency>&l…

从源程序到可执行文件的四个过程

从源程序到可执行文件的四个过程 预处理编译汇编链接 程序要运行起来&#xff0c;必须要经过四个步骤&#xff1a;预处理、编译、汇编和链接&#xff0c;如下图所示&#xff1a; -E选项&#xff1a;提示编译器执行完预处理就停下来&#xff0c;后边的编译、汇编、链接就先不执…