Android持久化技术,好内存不如烂存储

news2024/10/7 10:25:42

Android持久化技术,好内存不如烂存储

  • 前言
  • 六、Android持久化技术,好内存不如烂存储
    • 6.1 持久化技术介绍
    • 6.2 简单文件存储方案
    • 6.3 SharedPreferences存储方案
      • 6.3.1 获取SharedPreferences对象的三种方式
      • 6.3.2 使用SharedPreferences对象存储和读取数据
    • 6.4 SQLite数据库存储方案
      • 6.4.1 创建数据库
      • 6.4.2 添加数据
      • 6.4.3 更新数据
      • 6.4.4 删除数据
      • 6.4.5 查询数据
      • 6.4.6 直接只用SQL语句实现增删查改操作
    • 6.5 SQL太麻烦?LitePal让你不用SQL语句也能操作数据库
    • 7.1 配置LitePal
      • 7.1.1 下载LitePal包
      • 7.1.2 创建libs文件夹,并将jar丢进去
      • 7.1.3 创建assets资源文件夹,并创建litepal.xml配置文件
      • 7.1.4 litepal.xml配置数据库名称,版本,映射的表对象
    • 7.2 通过LitePal创建和升级数据库
      • 7.2.1 创建映射对象(数据库中的表结构)
      • 7.2.2 创建数据库
    • 7.3 通过LitePal进行数据库的增删改查
      • 7.3.1 添加数据
      • 7.3.2 更新数据
      • 7.3.3 删除数据
      • 7.3.4 查询数据
  • 参考书籍:第一行代码

前言

本文讲解Android中常用的持久化技术,包括SharedPreferences键值对存储方式、SQLite数据库持久化技术、LitePal开源数据库工具等。

六、Android持久化技术,好内存不如烂存储

6.1 持久化技术介绍

数据持久化简单来说就是将内存中暂时存储的数据转存到设备的存储单元中,使得数据处于持久状态。
Android系统提供了3中方式简单的实现数据持久化功能,即简单文件存储、SharedPreferences存储、数据库存储。

6.2 简单文件存储方案

简单文件存储就是以流的形式将数据存储到文件中,适用于简单的二进制数据,文本数据等。

  1. 保存数据到文件的示例代码
private void savaData(String persistencePath,String content)
    {
        FileOutputStream outputStream=null;
        BufferedWriter bufferedWriter=null;
        try {
            File file = new File(persistencePath);
            outputStream=new FileOutputStream(file);
            bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));
            bufferedWriter.write(content);
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (outputStream!=null)
                    outputStream.close();
                if (bufferedWriter!=null)
                    bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  1. 从文件中读取数据的示例代码
private String readData(string persistencePath)
    {
        FileInputStream fis = null;
        BufferedReader br = null;
        StringBuilder data = new StringBuilder();
        try {
            fis = new FileInputStream(persistencePath);
            br=new BufferedReader(new InputStreamReader(fis));
            String line="";
            while ((line=br.readLine())!=null)
                data.append(line);
        }catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (fis!=null)
                    fis.close();
                if (br!=null)
                    br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return data.toString();
    }

6.3 SharedPreferences存储方案

SharedPreferences采用键值对的方式存储多种数据类型的数据。SharedPreferences文件都存储在/data/data/< Package name>/shared_prefs/目录下。

6.3.1 获取SharedPreferences对象的三种方式

  1. Context类中的getSharedPreferences(文件名,模式)方法
    文件名:作为SharedPreferences文件的文件名。
    模式:只有MODE_PRIVATE一种表示只有当前应用程序才可以对这个SharedPreferences进行读写。
    示例:getSharedPreferences(“data”, MODE_PRIVATE);

  2. Activity类中getPreferences(模式)方法
    这个方法默认将当前活动的类名作为SharedPreferences的文件名。
    示例: getPreferences(MODE_PRIVATE);

  3. PreferenceManager类下的静态方法getDefaultSharedPreferences方法
    这个方法自动使用当前应用程序的包名作为前缀命名SharedPreferences的文件名。
    示例: PreferenceManager.getDefaultSharedPreferences(this);

6.3.2 使用SharedPreferences对象存储和读取数据

  1. 存储数据示例
SharedPreferences sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);//获取SharedPreferences 对象
SharedPreferences.Editor edit = sharedPreferences.edit();//获取编辑对象
//通过set方法存储各种类型的数据
edit.putString("name","mekeater");
edit.putInt("age",18);
edit.putBoolean("sex",true);
edit.apply();//保存数据到 /data/data/package name/shared_prefs/data.xml文件
  1. 读取数据示例
SharedPreferences sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);//获取SharedPreferences 对象
//通过get方法读取数据
String name = sharedPreferences.getString("name", "");//第二个参数是键不存在的情况下,作为默认值
int age = sharedPreferences.getInt("age", 0);
boolean sex = sharedPreferences.getBoolean("sex", false);

6.4 SQLite数据库存储方案

上面讲到的不管是通过流方式将数据存储到文件中,还是说通过SharedPreferences以键值对形式将数据存储到文件中,都只是适合存储简单的数据,不适合逻辑复杂的数据。

术业有专攻,数据库就是设计来存储具有复杂关系的数据的,那么如果要存储具有复杂关系的数据,我们应该采用数据库进行存储,而Android系统提供一个轻量级的SQLite数据库,用于存储复杂的数据。

6.4.1 创建数据库

SQLite提供了一个SQLiteOpenHelper帮助类,通过该类可以非常简单的对数据库进行创建和升级等,但该类是一个抽象类,因此我们首先需要创建一个自己的帮助类去继承它。

  1. 自定义数据库帮助类继承SQLiteOpenHelper,重写onCreate和onUpgrade两个方法,示例代码如下:
public class MyDatabaseHelper extends SQLiteOpenHelper {

    private Context mContext;

    //创建Book表的SQL语句
    public static final String CREATE_BOOK_TABLE="create table Book(" +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text)";
    //删除Book表的SQL语句
    public static final String DROP_BOOK="drop table if exists Book";

    //创建Category表的SQL语句
    public static final String CREATE_CATEGORY_TABLE="create table Category(" +
            "id integer primary key autoincrement," +
            "category_name text," +
            "category_code integer)";
    
    //删除Category表的SQL语句
    public static final String DROP_CATEGORY="drop table if exists Category";

    public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        this.mContext=context;
    }

    //数据库不存在的前提下,创建数据库完成后会调用该方法
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(CREATE_BOOK_TABLE);//执行SQL语句,创建Book表
        sqLiteDatabase.execSQL(CREATE_CATEGORY_TABLE);//执行SQL语句,创建Category表
    }

    //数据库版本发生变化的时候,创建数据库操作后,会调用该方法
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL(DROP_BOOK);//执行SQL语句,删除Book表
        sqLiteDatabase.execSQL(DROP_CATEGORY);//执行SQL语句,删除Category表
        onCreate(sqLiteDatabase);
    }
}
  1. 实例化自定义的数据库帮助类,并创建数据库,核心代码如下:
    创建的SQLite数据库文件存放在 data/data/package name/databases/目录下
//参数1:context 参数2:数据库名 参数3:一般为null 参数4:数据库版本号
MyDatabaseHelper dbHelper=new MyDatabaseHelper(this,"BookStore.db",null,1);
//调用getWritableDatabase方法或者getReadableDatabase方法创建数据库(若数据不存在则创建,若已存着则直接获得已有数据库)
SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();

6.4.2 添加数据

核心示例代码如下:

SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
//以键值对存储数据
ContentValues contentValues = new ContentValues();
contentValues.put("name","我是如何成功的?");
contentValues.put("author","mekeater");
contentValues.put("pages",666);
contentValues.put("price",99);
//将键值对数据存储到Book表中
writableDatabase.insert("Book",null,contentValues);

6.4.3 更新数据

核心示例代码如下:

SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("price",16);
//参数1:表名 参数2:键值对值 参数3:where语句 参数4 where语句中需要的参数值
writableDatabase.update("Book",contentValues,"author = ?",new String[]{"sun"});

6.4.4 删除数据

核心示例代码如下:

SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
//参数1:表名 参数2:where语句 参数3 where语句中需要的参数值
writableDatabase.delete("Book",null,null);

6.4.5 查询数据

核心示例代码如下:

SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
Cursor cursor = writableDatabase.query("Book", null, null, null, null, null, null);
//Cursor cursor = writableDatabase.rawQuery("select * from Book", null);//不采用Sqlite提供的方法,直接采用SQL完成操作
if (cursor.moveToFirst())
{
	do {
		String name = cursor.getString(cursor.getColumnIndex("name"));
		String author = cursor.getString(cursor.getColumnIndex("author"));
		int pages = cursor.getInt(cursor.getColumnIndex("pages"));
		double price = cursor.getDouble(cursor.getColumnIndex("price"));
		Log.d(TAG, "==============="+name+"     "+author+"     "+pages+"     "+price+"===============");
    }while (cursor.moveToNext());
}

query方法包含7个参数,各个参数的意义如下表所示:
在这里插入图片描述

6.4.6 直接只用SQL语句实现增删查改操作

SQLiteDatabase类提供了execSQL方法直接执行SQL语句,也提供了rawQuery方法直接执行SQL查询语句。
示例代码如下:

db.execSQL ( "insert into Book (name,author,pages,price) values(?,?,?,?)",new String[] { "The Da Vinci Code","Dan Brown","454","16.96"});

6.5 SQL太麻烦?LitePal让你不用SQL语句也能操作数据库

通过SQLite数据库提供的方法结合SQL语句,我们就能完成对数据的管理及操作,但是SQL语句一般比较复杂,麻烦,影响开发效率,那么有没有不使用SQL语句就能操作SQLite数据库的方法呢?

有的!

本节学习的LitePal开源库采用对象关系映射(ORM)模式实现将我们开发中常用的一些功能进行封装,使得我们可以不用编写SQL语句就可以完成建表及增删改查的操作。

什么是对象关系映射呢?简单点说,我们使用的编程语言是面向对象语言,而使用的数据库则是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射了。

下面来应用一下你就懂了。

7.1 配置LitePal

7.1.1 下载LitePal包

链接:https://pan.baidu.com/s/1QKpEFUtJ7-d9lgzWiBWIQg?pwd=agjx
提取码:agjx

7.1.2 创建libs文件夹,并将jar丢进去

在这里插入图片描述

7.1.3 创建assets资源文件夹,并创建litepal.xml配置文件

在这里插入图片描述

7.1.4 litepal.xml配置数据库名称,版本,映射的表对象

示例配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<litepal>
    <dbname value="BookStore"/> <!--数据库名-->
    <version value="2"/> <!--数据库版本-->
    <list>
        <mapping class="com.xiaomi.litepaltest.Book"/> <!--映射的表对象类-->
    </list>
</litepal>

7.2 通过LitePal创建和升级数据库

7.2.1 创建映射对象(数据库中的表结构)

如在在数据库中创建一张Book表,只需要定义一个Book类,然后在litepal.xml文件的< list>标签内添加这个类即可。如果要对这张表进行CRUD,则还需要这个类继承DataSupport,如创建一个可以进行CRUD的Book表,定义Book类如下:

import org.litepal.crud.DataSupport;
public class Book extends DataSupport {
    private int id;
    private String author;
    private double price;
    private int pages;
    private String name;
    private String press;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }
}

7.2.2 创建数据库

只需要进行任意一次数据库操作就完成了数据库的创建,如下示例代码是最简单的一次数据库操作,它就完成了数据库的创建。

 Connector.getDatabase();//创建数据库

升级数据库,只需要在litepal.xml文件中修改版本号即可。

7.3 通过LitePal进行数据库的增删改查

7.3.1 添加数据

如为Book表添加数据,只需要创建Book对象,然后调用DataSupport的save方法即可,核心示例代码如下:

Book book = new Book();
book.setAuthor("mekeater");
book.setName("人性的弱点解读");
book.setPages(666);
book.setPrice(99);
book.setPress("Unknow");
book.save();

7.3.2 更新数据

核心示例代码如下:

Book book = new Book();
book.setPrice(99.99);
book.updateAll("author = ?","mekeater");

7.3.3 删除数据

核心示例代码如下:

DataSupport.deleteAll(Book.class,"price < ?","99.99");

7.3.4 查询数据

核心示例代码如下:

StringBuilder sb = new StringBuilder();
List<Book> books = DataSupport.findAll(Book.class);
for (Book book : books) {
	String name = book.getName();
	String author = book.getAuthor();
	double price = book.getPrice();
	String press = book.getPress();
	sb.append(name+"    "+author+"    "+pages+"    "+price+"    "+press+"\r\n");
}

参考书籍:第一行代码

链接:https://pan.baidu.com/s/1aXtOQCXL6qzxEFLBlqXs1Q?pwd=n5ag
提取码:n5ag

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

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

相关文章

Model Fusion of Heterogeneous Neural Networks via Cross-Layer Alignment论文阅读

论文地址点这里 一. 介绍 本文是针对异构的网络融合技术&#xff0c;是基于上一篇OTFusion的论文进行的工作&#xff0c;解决了神经元关联问题。当所有的网络都具有相同的架构时&#xff0c;OTFusion比普通平均算法有明显的改进。与其他基于平均的模型融合方法相比&#xff0…

如何制作一个实时在线显示评论

通过循环容器及数据表功能&#xff0c;制作一个发送评论实时显示的功能 效果展示 具体步骤 制作评论背景 制作评论样式 制作一个发送评论输入框 制作一个发送按钮 创建评论数据表 添加获取评论事件 创建发送评论触发器 数据绑定与设置 步骤分解 制作评论背景 拖拽 循环容器 到…

Go基础学习【2】

文章目录一&#xff1a;数组二&#xff1a;map集合三&#xff1a;包四&#xff1a;结构体一&#xff1a;数组 1.命名 var arrAge [5]int{1,2,3,4,5} var arrAge […]int{1,2,4,5,6} var arrAge [5]string{3:“sfd”,5:“asdf”} 2.传递 通过传递数组的指针 和 使用数组的切片…

[go学习笔记.第十六章.TCP编程] 2.项目-海量用户即时通讯系统

一.项目介绍 1.项目开发流程 需求分析->设计阶段->编码实现->测试阶段->实施阶段 2.需求分析 (1).用户注册 (2).用户登录 (3).显示在线用户列表 (4).群聊(广播) (5).点对点聊天 (6).离线留言 3.示意图 4.项目开发前技术准备 项目要保存用户信息和消息数据,因此需…

【Vue】vue项目用qrcodejs2生成带log的二维码图片,vue生成二维码图片中间带log,自定义log

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录系列文章目录前言一、安装qrcodejs2二、在页面中使用1.引入…

英国Paper写作思路和精髓如何了解?

第一学期即将结束&#xff0c;为了能帮助更多英国留学生顺利完成Paper&#xff0c;增加对英国Paper写作的理解&#xff0c;取得高分。本文小编为大家分享英国Paper写作的思路和精髓&#xff0c;帮助自己修改提升Paper质量。 The first semester is coming to an end.In order t…

flutter AnimatedSwitcher 动画切换过渡组件 跑马灯动画封装

flutter AnimatedSwitcher 动画切换过渡组件前言一、AnimatedSwitcher 简介二、AnimatedSwitcher 的简单使用三、AnimatedSwitcher 自定义跑马灯动画四、SlideTransitionX 的封装总结前言 本篇文章将记录 AnimatedSwitcher 过渡组件&#xff0c;这个组件动画是一个新的小部件来…

制作一个简单HTML宠物猫网页(HTML+CSS)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

在 Spring Boot中配置日志

Spring Boot 在引擎盖下使用Apache Commons Logging。但是&#xff0c;它允许您选择所需的日志记录库。让我们来看看使用 Spring Boot 时的一些配置和最佳实践。 目录 概述简单日志记录示例配置日志记录 更改日志级别将日志写入文件在 Spring 引导中更改日志记录模式对日志条…

基于小波域的隐马尔可夫树模型的图像去噪方法的matlab实现代码

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 为适应图像的空域非平稳变化, 提出了一种基于小波域分类隐马尔可夫树(CHMT)模型的图像去噪方法.该模型中,图像在每一尺度每一子带的小波系数均被分成C组以突出其空域非平稳变化 的特征,这…

MySQL有哪些锁

这次&#xff0c;来说说 MySQL 的锁&#xff0c;主要是 Q&A 的形式&#xff0c;看起来会比较轻松。 在 MySQL 里&#xff0c;根据加锁的范围&#xff0c;可以分为全局锁、表级锁和行锁三类。 全局锁 全局锁是怎么用的&#xff1f; 要使用全局锁&#xff0c;则要执行这条命…

彻底搞明白概率论:事件间的关系与运算;频率与概率

文章目录事件间的关系事件间的运算事件间的运算法则概率描述性定义统计性定义频率频率的性质频率是否能够作为概率呢&#xff1f;公理化定义概率的重要性质事件间的关系 注意互斥关系和对立关系&#xff1a; 互斥关系是&#xff1a;只要 A,BA,BA,B 不同时发生&#xff08;不存在…

山东菏泽家乡网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

MindFusion JavaScript R2 套件 Crack

MindFusion JavaScript R2将您的 JAVASCRIPT 应用程序更快地推向市场 MindFusion JavaScript 库旨在显着缩短开发任何类型的交互式 JS 应用程序所需的时间。它们还使开发更加容易。 用于 JavaScript 的 MindFusion 包 JavaScript 数据视图 数据网格JavaScript 图 绘图JavaScr…

DJYGUI系列文章八:GDD绘图系统

目录 1 GDD绘图系统概述 1.1绘图上下文 1.2 DrawColor&#xff0c;FillColor&#xff0c;TextColor的作用与区别 2 API说明 2.1 SetRopCode&#xff1a; 设置当前光栅码 2.2 GetRopCode&#xff1a; 获得当前光栅码 2.3 MoveTo&#xff1a; 设置当前坐标位置 2.4 SetDr…

Web基础习题

1.语义化标签 1.现需要设置一个按钮&#xff0c;请填写语义化标签补全代码片段&#xff08;仅填写一个标签名即可&#xff09; <_____>点我!</_____> 2.在HTML中一般用哪个语义化标签表示斜体文本效果 3.在HTML中一般用哪个语义化标签表示头部导航 4.在HTML中一…

web前端-html-css-字体(字体的样式,字体的分类,字体其他样式,字体简写样式,文本样式)

字体的样式 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><style type"text/css">.p1 {font-size: 30px;font-family: "curlz mt";}</style></head><body>…

vite+ts前期准备(尽量详细在更新)

创建和准备vitets项目 打开命令行或进入vscode打开终端 输入命令:npm init vite 选择vuets cd 进入项目 cnpm/yarn/npm install 初次运行项目 终端输入命令:cnpm run dev 可以设置运行之后自动打开浏览器 目录打开package.json dev:vite --open 添加–open 查看环境变量 目录打…

Latex IEEE模板导入中文问题

IEEE模板下载 下载IEEE的conference的latex模板文件&#xff1a; conference&#xff1a;https://www.ieee.org/conferences/publishing/templates.html 模板包括以下文件 编译 IEEE模板需要用pdflatex编译&#xff0c;否则英文的粗体等无法正常显示。 使用pdflatex编译 …

select......for update会锁表还是锁行?

select查询语句是不会加锁的&#xff0c;但是select .......for update除了有查询的作用外&#xff0c;还会加锁呢&#xff0c;而且它是悲观锁。 那么它加的是行锁还是表锁&#xff0c;这就要看是不是用了索引/主键。 没用索引/主键的话就是表锁&#xff0c;否则就是是行锁。…