(二十二)安卓开发中的数据存储之SQLite简单使用

news2025/4/15 23:01:17

在Android开发中,SQLite是一种非常常用的数据库存储方式。它轻量、简单,非常适合移动设备上的数据管理。本文将通过通俗易懂的语言,结合代码示例和具体场景,详细讲解SQLite在Android中的使用。


1. 什么是SQLite?

SQLite是一个开源的、嵌入式的关系型数据库。它不需要像MySQL那样运行一个独立的服务器,而是直接将数据存储在一个文件中。这个文件可以随着你的应用一起打包,方便管理。简单来说,SQLite就像一个“便携式笔记本”,你可以在里面记录和管理数据。


2. 为什么在Android中使用SQLite?

  • 轻量级: SQLite占用资源少,适合手机这种硬件资源有限的设备。
  • 无需服务器: 不需要额外的服务器支持,直接嵌入应用中使用。
  • 自包含: 数据库文件独立存在,易于备份和分发。
  • 支持SQL: 使用标准的SQL语法,如果你学过数据库,上手会很快。

总之,SQLite是Android开发中内置的“标配”数据库,特别适合存储结构化数据,比如用户信息、任务列表等。


3. SQLite在Android中的基本使用步骤

使用SQLite主要涉及以下几个步骤:

  1. 创建数据库: 通过SQLiteOpenHelper类来创建和管理数据库。
  2. 定义表结构: 在onCreate方法中用SQL语句创建表。
  3. 插入数据: 往表里添加数据。
  4. 查询数据: 从表中读取数据。
  5. 更新数据: 修改表中的数据。
  6. 删除数据: 删除表中的数据。

接下来,我们通过代码和一个具体的通讯录应用场景来详细讲解这些步骤。


4. 代码示例

4.1 创建数据库和表

首先,我们需要创建一个类继承SQLiteOpenHelper,用来管理数据库和表的创建。

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "my_database.db"; // 数据库文件名
    private static final int DATABASE_VERSION = 1; // 数据库版本号

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // 创建表的SQL语句
        String createTableSQL = "CREATE TABLE users (" +
                "id INTEGER PRIMARY KEY AUTOINCREMENT," + // 主键,自增
                "name TEXT," + // 姓名,文本类型
                "age INTEGER)"; // 年龄,整型
        db.execSQL(createTableSQL); // 执行SQL,创建表
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 数据库升级时执行,比如删除旧表并重建
        db.execSQL("DROP TABLE IF EXISTS users");
        onCreate(db);
    }
}
  • DATABASE_NAME: 数据库文件名,通常以.db结尾。
  • DATABASE_VERSION: 数据库版本号,如果表结构有变化,需要增加版本号。
  • onCreate: 第一次创建数据库时调用,定义表的结构。
  • onUpgrade: 当版本号变化时调用,用于处理旧数据迁移。

4.2 插入数据

插入数据可以用insert方法,简单高效。

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;

public void insertUser(String name, int age) {
    SQLiteDatabase db = getWritableDatabase(); // 获取可写数据库对象
    ContentValues values = new ContentValues(); // 用于存放键值对
    values.put("name", name); // 插入姓名
    values.put("age", age); // 插入年龄
    db.insert("users", null, values); // 插入到users表
    db.close(); // 关闭数据库连接
}
  • getWritableDatabase(): 获取一个可以读写的数据库对象。
  • ContentValues: 像一个“包裹”,把要插入的数据装进去。
  • insert: 将数据插入表中。

4.3 查询数据

查询数据可以用query方法,返回一个Cursor对象,类似于指针,指向查询结果。

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;

class User {
    int id;
    String name;
    int age;

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

public List<User> getAllUsers() {
    List<User> userList = new ArrayList<>();
    SQLiteDatabase db = getReadableDatabase(); // 获取只读数据库对象
    Cursor cursor = db.query("users", null, null, null, null, null, null); // 查询所有数据
    if (cursor.moveToFirst()) { // 移动到第一条数据
        do {
            int id = cursor.getInt(cursor.getColumnIndex("id"));
            String name = cursor.getString(cursor.getColumnIndex("name"));
            int age = cursor.getInt(cursor.getColumnIndex("age"));
            User user = new User(id, name, age);
            userList.add(user);
        } while (cursor.moveToNext()); // 移动到下一条数据
    }
    cursor.close(); // 关闭游标
    db.close(); // 关闭数据库
    return userList;
}
  • getReadableDatabase(): 获取只读数据库对象。
  • Cursor: 查询结果的“指针”,可以逐行读取数据。
  • moveToFirstmoveToNext: 控制游标移动,遍历所有数据。

4.4 更新数据

更新数据可以用update方法。

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;

public void updateUser(int id, String newName, int newAge) {
    SQLiteDatabase db = getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("name", newName);
    values.put("age", newAge);
    db.update("users", values, "id=?", new String[]{String.valueOf(id)}); // 根据id更新
    db.close();
}
  • update: 参数分别是表名、更新内容、条件和条件值。

4.5 删除数据

删除数据可以用delete方法。

import android.database.sqlite.SQLiteDatabase;

public void deleteUser(int id) {
    SQLiteDatabase db = getWritableDatabase();
    db.delete("users", "id=?", new String[]{String.valueOf(id)}); // 根据id删除
    db.close();
}
  • delete: 参数分别是表名、条件和条件值。

5. 具体使用场景:通讯录应用

假设我们要开发一个简单的通讯录应用,存储联系人的姓名和电话号码。以下是如何用SQLite实现这个功能。

5.1 创建数据库和表

修改DatabaseHelper中的表结构:

@Override
public void onCreate(SQLiteDatabase db) {
    String createTableSQL = "CREATE TABLE contacts (" +
            "id INTEGER PRIMARY KEY AUTOINCREMENT," +
            "name TEXT," +
            "phone TEXT)";
    db.execSQL(createTableSQL);
}

5.2 插入联系人

public void insertContact(String name, String phone) {
    SQLiteDatabase db = getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("name", name);
    values.put("phone", phone);
    db.insert("contacts", null, values);
    db.close();
}

5.3 查询所有联系人

class Contact {
    int id;
    String name;
    String phone;

    public Contact(int id, String name, String phone) {
        this.id = id;
        this.name = name;
        this.phone = phone;
    }
}

public List<Contact> getAllContacts() {
    List<Contact> contactList = new ArrayList<>();
    SQLiteDatabase db = getReadableDatabase();
    Cursor cursor = db.query("contacts", null, null, null, null, null, null);
    if (cursor.moveToFirst()) {
        do {
            int id = cursor.getInt(cursor.getColumnIndex("id"));
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String phone = cursor.getString(cursor.getColumnIndex("phone"));
            Contact contact = new Contact(id, name, phone);
            contactList.add(contact);
        } while (cursor.moveToNext());
    }
    cursor.close();
    db.close();
    return contactList;
}

5.4 更新联系人信息

public void updateContact(int id, String newName, String newPhone) {
    SQLiteDatabase db = getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("name", newName);
    values.put("phone", newPhone);
    db.update("contacts", values, "id=?", new String[]{String.valueOf(id)});
    db.close();
}

5.5 删除联系人

public void deleteContact(int id) {
    SQLiteDatabase db = getWritableDatabase();
    db.delete("contacts", "id=?", new String[]{String.valueOf(id)});
    db.close();
}

通过这些代码,我们可以实现一个简单的通讯录功能:添加联系人、查看所有联系人、修改联系人信息和删除联系人。


6. 注意事项

  1. 数据库版本管理: 如果表结构变了(比如增加字段),需要更新DATABASE_VERSION,并在onUpgrade中处理旧数据。
  2. 线程安全: 数据库操作不要阻塞主线程,可以用AsyncTask或线程池来处理。
  3. 关闭连接: 操作完数据库后,记得调用close()释放资源。
  4. 异常处理: 操作数据库时可能会出错,要用try-catch捕获异常,比如SQLiteException

7. 总结

SQLite是Android开发中强大又简单的数据库工具。通过SQLiteOpenHelperSQLiteDatabase,我们可以轻松实现数据的增删改查。结合通讯录这个例子,你应该已经掌握了SQLite的基本用法。在实际开发中,还可以根据需要使用更复杂的查询语句或事务管理,进一步提升应用的性能和功能。

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

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

相关文章

图像形态学操作对比(Opencv)

形态学基于图像的形状进行操作&#xff0c;用于处理二值化图像&#xff0c;主要包括腐蚀和膨胀两种基本操作。这些操作通常用于去除噪声、分隔或连接相邻的元素以及寻找图像中显著的最大点和最小点。 1. 形态学操作 import cv2 import numpy as np import matplotlib.pyplot …

复刻系列-星穹铁道 3.2 版本先行展示页

复刻星穹铁道 3.2 版本先行展示页 0. 视频 手搓&#xff5e;星穹铁道&#xff5e;展示页&#xff5e;&#xff5e;&#xff5e; 1. 基本信息 作者: 啊是特嗷桃系列: 复刻系列官方的网站: 《崩坏&#xff1a;星穹铁道》3.2版本「走过安眠地的花丛」专题展示页现已上线复刻的网…

Linux:进程理解1(查看进程,创造进程,进程状态)

进程理解 &#xff08;一&#xff09;查看进程通过系统调用获取进程标示* &#xff08;二&#xff09;创造进程&#xff08;fork&#xff09;1. 创造的子进程的PCB代码数据怎么来&#xff1f;2.一个函数为什么有两个返回值&#xff1f;3. 为什么这里会有 两个 id值&#xff1f;…

异形遮罩之QML中的 `OpacityMask` 实战

文章目录 &#x1f327;️ 传统实现的问题&#x1f449; 效果图 &#x1f308; 使用 OpacityMask 的理想方案&#x1f449;代码如下&#x1f3af; 最终效果&#xff1a; ✨ 延伸应用&#x1f9e0; 总结 在 UI 设计中&#xff0c;经常希望实现一些“异形区域”拥有统一透明度或颜…

如何为您的设计应用选择高速连接器

电气应用的设计过程需要考虑诸多因素&#xff0c;尤其是在设计高速网络时。许多连接器用户可能没有意识到&#xff0c;除了在两个互连之间组装导电线路之外&#xff0c;还需要考虑各种工艺。在建立高速连接并确保适当的信号完整性时&#xff0c;必须考虑蚀刻、公差、屏蔽等因素…

【论文阅读】UniAD: Planning-oriented Autonomous Driving

一、Introduction 传统的无人驾驶采用了区分子模块的设计&#xff0c;即将无人驾驶拆分为感知规划控制三个模块&#xff0c;这虽然能够让无人驾驶以一个很清晰的结构实现&#xff0c;但是感知的结果在传达到规划部分的时候&#xff0c;会导致部分信息丢失&#xff0c;这势必会…

upload-labs二次打

1(前端js绕过) 弹窗&#xff0c;先看看有没有js有&#xff0c;禁用js 禁用后就可以上传php文件了&#xff0c;然后我们就去访问文件&#xff0c;成功 2&#xff08;MIME绕过&#xff09; 先上传一个php文件试试&#xff0c;不行&#xff0c;.htaccess不行, 试试MIME类型&am…

提权实战!

就是提升权限&#xff0c;当我们拿到一个shell权限较低&#xff0c;当满足MySQL提权的要求时&#xff0c;就可以进行这个提权。 MySQL数据库提权&#xff08;Privilege Escalation&#xff09;是指攻击者通过技术手段&#xff0c;从低权限的数据库用户提升到更高权限&#xff…

ChromeOS 135 版本更新

ChromeOS 135 版本更新 一、ChromeOS 135 更新内容 1. ChromeOS 电池寿命优化策略 为了延长 Chromebook 的使用寿命&#xff0c;ChromeOS 135 引入了一项全新的电池充电限制策略 —— DevicePowerBatteryChargingOptimization&#xff0c;可提供更多充电优化选项&#xff0c…

javaSE.Lambda表达式

如果一个接口中有且只有一个待实现的抽象方法&#xff0c;那么我们可以将匿名内部类简写为Lambda表达式。 简写规则 标准格式&#xff1a; &#xff08;【参数类型 参数名称&#xff0c;】...&#xff09; -> {代码语句&#xff0c; 包括返回值} 只有一行花括号{}可以省略。…

【随身wifi】青龙面板保姆级教程

0.操作前必看 本教程基于Debian系统&#xff0c;从Docker环境。面板安装&#xff0c;到最后拉取脚本的使用。 可以拉库跑狗东京豆&#xff0c;elm红包等等&#xff0c;也可以跑写自己写的脚本&#xff0c;自行探索 重要的号别搞&#xff0c;容易黑号&#xff0c;黑号自己负责…

Android 之美国关税问题导致 GitHub 403 无法正常访问,责任在谁?

这几天各国关税问题导致世界动荡不安&#xff0c;如今GitHub又无法正常访问&#xff0c;是不是Google到时候也无法正常使用了。

4月13日星期日早报简报微语报早读

4月13日星期日&#xff0c;农历三月十六&#xff0c;早报#微语早读。 1、北京处置倒伏树木843棵&#xff0c;已全部处置完毕&#xff1b; 2、山西大同“订婚强奸案”本月16日二审宣判&#xff0c;一审男方被判3年刑&#xff1b; 3、今年我国快递业务量已突破500亿件&#xf…

动态路由, RIP路由协议,RIPv1,RIPv2

动态路由 1、回顾 路由&#xff1a;从源主机到目标主机的过程 源主机发送数据给目标主机&#xff0c;源主机会查看自身的路由信息 如果目标主机是自己同网段&#xff0c;源主机查看的是直连路由 如果目标主机和自己不同网段&#xff0c;源主机查看的是静态路由、动态路由、默…

【已更新完毕】2025泰迪杯数据挖掘竞赛B题数学建模思路代码文章教学:基于穿戴装备的身体活动监测

基于穿戴装备的身体活动监测 摘要 本研究基于加速度计采集的活动数据&#xff0c;旨在分析和统计100名志愿者在不同身体活动类别下的时长分布。通过对加速度数据的处理&#xff0c;活动被划分为睡眠、静态活动、低强度、中等强度和高强度五类&#xff0c;进而计算每个志愿者在…

212、【图论】字符串接龙(Python)

题目描述 题目链接&#xff1a;110. 字符串接龙 代码实现 import collectionsn int(input()) beginStr, endStr input().split() strList [input() for _ in range(n)]deque collections.deque() # 使用队列遍历结点 deque.append([beginStr, 1]) # 存储当前字符串和遍…

【UE5】RTS游戏的框选功能+行军线效果实现

目录 效果 步骤 一、项目准备 二、框选NPC并移动到指定地点 三、框选效果 四、行军线效果 效果 步骤 一、项目准备 1. 新建一个俯视角游戏工程 2. 新建一个pawn、玩家控制器和游戏模式,这里分别命名为“MyPawn”、“MyController”和“MyGameMode” 3. 打开“MyGam…

设计模式 四、行为设计模式(2)

五、状态模式 1、概述 状态设计模式是一种行为型设计模式&#xff0c;它允许对象在其内部状态发生时改变其行为&#xff0c;这种模式可以消除大量的条件语句&#xff0c;并将每个状态的行为封装到单独的类中。 状态模式的主要组成部分如下&#xff1a; 1&#xff09;上…

FEA 仿真助力高速连接器设计中的信号完整性

各行各业高速信号软件和硬件的快速发展&#xff0c;带来了更高的频率和带宽。因此&#xff0c;对连接器组件的整体性能要求也更加严格。同时&#xff0c;器件和封装形式、互连以及系统内其他设备的小型化也带来了额外的设计挑战。所有这些都对信号传输完整性产生重大影响。 高速…

yum的基本操作和vim指令

在我们的手机端或者Windows上下载软件&#xff0c;可以在相应的应用商店或者官网进行下载&#xff0c;这样对于用户来说十分的方便和便捷。而在Linux上&#xff0c;也有类似的安装方式&#xff0c;我们来一一了解一下。 Linux安装软件的3种方法 源代码安装 在Linux下安装软件…