安卓数据存储——SQLite

news2024/9/25 9:33:54

一、SQLite数据库

创建表

	CREATE TABLE IF NOT EXISTS user_info (
		_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
		name VARCHAR NOT NULL,
		age INTEGER NOT NULL,
		height LONG NOT NULL,
		weight FLOAT NOT NULL
	);
注:
  • IF NOT EXISTS:如果该表不存在则创建,若存在该表则不创建
  • AUTOINCREMENT:自动增长
  • sqlite数据库不支持布尔类型,如果直接存布尔类型会被自动转为数字 0(false)、1(true)

删除表

	DROP TABLE IF EXISTS user_info;
注:
  • IF EXISTS:如果该表存在则删除

修改表结构

	ALTER TABLE user_info ADD COLUMN phone VARCHAR;
注:
  • sqlite只支持增加字段,不支持修改、删除字段
  • sqlite每次只能添加一个字段,若要添加多个字段,需分多次添加

添加记录

	INSERT INTO user_info ( name, age, height, weight, phone )
	VALUES
		( '张三', 18, 180, 70.2, 1101201120 );

删除记录

	DELETE 
	FROM
		user_info 
	WHERE
		name = '张三';

修改记录

	UPDATE user_info 
	SET height = 188 
	WHERE
		name = '张三';

查询记录

	SELECT * FROM user_info ORDER BY age ASC;
注:

ORDER BY:根据age字段排序
ASC:升序
DESC:降序

二、SQLiteDatabase数据库管理器

SQLiteDatabase是SQLite的数据库管理类,它提供了若干操作数据表的API,常用的方法有3类。

管理类主要API

  • openDatabase:打开指定路径的数据库
  • isOpen:判断数据库是否已打开
  • close:关闭数据库
  • getVersion:获取数据库的版本号
  • setVersion:设置数据库的版本号

创建数据库

String mDatabaseName = getFilesDir() + "/test.db";
SQLiteDatabase db = openOrCreateDatabase(mDatabaseName, Context.MODE_PRIVATE, null);

删除数据库

boolean result = deleteDatabase(mDatabaseName);

案例代码

注:
  • getFilesDir():返回该包下的files路径(/data/data/包名/files/)在这里插入图片描述

三、SQLiteOpenHelper数据库帮助器

SQLiteOpenHelper是Android提供的数据库辅助工具,用于指导开发者进行SQLite的合理使用。

数据处理类主要API

  • execSQL:执行拼接好的SQL语句
  • delete:删除符合条件的记录
  • update:更新符合条件的记录
  • insert:插入一条记录
  • query:执行查询操作,返回结果集的游标
  • rawQuery:执行拼接好的SQL查询语句,返回结果集的游标

创建步骤

  • 新建一个继承自SQLiteOpenHelper的数据库操作类,提示重写onCreate和onUpgrade两个方法。
  • 封装保证数据库安全的必要方法
  • 提供对表记录进行增加、删除、修改、查询的操作方法。
public class UserDBHelper extends SQLiteOpenHelper {
    private static final String DB_NAME = "user.db";
    private static final String TABLE_NAME = "user_info";
    private static final int DB_VERSION = 1;

    private static UserDBHelper mHelper = null;
    private SQLiteDatabase mRDB = null;
    private SQLiteDatabase mWDB = null;

    private UserDBHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    //单例
    public static UserDBHelper getInstance(Context context) {
        if (mHelper == null) {
            mHelper = new UserDBHelper(context);
        }
        return mHelper;
    }
}

在onCreate中创建表

    // 创建数据库,执行建表语句
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" + "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + "name VARCHAR NOT NULL);";
        db.execSQL(sql);
    }

SQLiteDatabase对数据库操作分为读和写,所以要提供两个实例

    private SQLiteDatabase mRDB = null;
    private SQLiteDatabase mWDB = null;

读连接:getReadableDatabase()

    public SQLiteDatabase openReadLink() {
        if (mRDB == null || !mRDB.isOpen()) {
            mRDB = mHelper.getReadableDatabase();
        }
        return mRDB;
    }

写连接:getWritableDatabase()

    public SQLiteDatabase openWriteLink() {
        if (mWDB == null || !mWDB.isOpen()) {
            mWDB = mHelper.getWritableDatabase();
            return mWDB;
        }
        return mWDB;
    }

关闭连接

    public void closeLink() {
        if (mRDB != null && mRDB.isOpen()) {
            mRDB.close();
            mRDB = null;
        }
        if (mWDB != null && mWDB.isOpen()) {
            mWDB.close();
            mWDB = null;
        }
    }

添加

    public long insert(User user) {
        ContentValues values = new ContentValues();
        values.put("name", user.name);
		//执行插入记录动作,该语句返回插入记录的行号
		//如果第三个参数values 为Null或者元素个数为0, 由于insert()方法要求必须添加一条除了主键之外其它字段为Null值的记录,
		//为了满足SQL语法的需要, insert语句必须给定一个字段名 ,如:insert into person(name) values(NULL),
		//倘若不给定字段名 , insert语句就成了这样: insert into person() values(),显然这不满足标准SQL的语法。
		//如果第三个参数values 不为Null并且元素的个数大于0 ,可以把第二个参数设置为null 。
        return mWDB.insert(TABLE_NAME, null, values);
    }

删除

    public long deleteByName(User user) {
//        删除多个 name=? and age=?
//        删除所有 1=1
        return mWDB.delete(TABLE_NAME, "name=?", new String[]{user.name});
    }

修改

    public long update(User user) {
        ContentValues values = new ContentValues();
        values.put("name", user.name);
        return mWDB.update(TABLE_NAME, values, "name=?", new String[]{user.name});
    }

查询

    public List<User> queryAll() {
        List<User> list = new ArrayList<>();
        Cursor cursor = mRDB.query(TABLE_NAME, null, null, null, null, null, null);
        
        while (cursor.moveToNext()) {
            User user = new User();
            user.id = cursor.getInt(0);
            user.name = cursor.getString(1);
            list.add(user);
        }
        return list;
    }
注:
  • Cursor:游标

使用

public class SQLiteHelperActivity extends : {
    private UserDBHelper mHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sqlite_helper);

        Button save = findViewById(R.id.save);

        save.setOnClickListener(view -> {
            User user = new User("张三");
//            插入
//            long res = mHelper.insert(user);

//            删除
//            long res = mHelper.deleteByName(user);

//            修改
//            long res = mHelper.update(user);

//            查询
            List<User> list=mHelper.queryAll();
            
            for(User u: list){
                Log.d("AAA",u.toString());
            }
          	if (res > 0) {
               ToastUtil.show(this, "success");
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        mHelper = UserDBHelper.getInstance(this);
//        打开数据库读写连接
        mHelper.openWriteLink();
        mHelper.openReadLink();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mHelper.closeLink();
    }
}

事务

事务类主要API

  • beginTransaction:开始事务
  • setTransactionSuccessful:设置事务的成功标志
  • endTransaction:结束事务
    public long insert(User user) {
        ContentValues values = new ContentValues();
        values.put("name", user.name);
        try {
            //开始一个事务
            mWDB.beginTransaction();

            mWDB.insert(TABLE_NAME, null, values);
            mWDB.insert(TABLE_NAME, null, values);
            
            //标记事务成功
            mWDB.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //标记事务结束        
            mWDB.endTransaction();
        }
        return 1;
    }

数据库更新

	private static final int DB_VERSION = 1;
	
    private UserDBHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

当 DB_VERSION 改变时给表添加两个字段

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN phone VARCHAR;";
        db.execSQL(sql);
        sql = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN password VARCHAR;";
        db.execSQL(sql);
    }

UserDBHelper代码案例

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

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

相关文章

Docker更换阿里容器镜像源

以Mac为例&#xff0c; 一、获取阿里容器镜像加速器地址 访问阿里云官网https://cn.aliyun.com/ 登录阿里云&#xff0c;没有账号就注册一个 登录完成后在搜索框搜索&#xff0c;容器镜像服务&#xff0c;并打开 点击管理控制台&#xff0c;进入管理控制台 左侧点击镜像加速…

ubuntu重新安装clickhouse

1.卸载clickhouse 关闭原来的clickhouse sudo systemctl stop clickhouse-server 查看关闭clickhouse是否成功 sudo systemctl status clickhouse-server 备份配置文件 /etc/clickhouse-server/user.xml /etc/clickhouse-server/config.d/metrika.xml /etc/clickhouse…

蚂蚁Raft一致性算法库SOFAJRaft深入分析

大家好&#xff0c;我是 V 哥&#xff0c;SOFAJRaft 是蚂蚁金服开源的一个基于 Raft 共识算法的 Java 实现&#xff0c;它特别适合高负载、低延迟的分布式系统场景。SOFAJRaft 支持 Multi-Raft-Group&#xff0c;能够同时处理多个 Raft 集群&#xff0c;具有扩展性和强一致性保…

实验室ICPR 2024论文分享┆FPMT: 基于增强型半监督模型的交通事件检测(含详细视频解读)

目录 论文分享简介 1. 会议介绍 2. 研究背景及主要贡献 3. 方法 4. 实验 5. 结论 6. 论文介绍视频 论文分享简介 本推文详细介绍了一篇实验室的最新论文成果《FPMT: Enhanced Semi-Supervised Model for Traffic Incident Detection》&#xff0c;该论文已被第27届国际…

尚硅谷———-乐(智)尚代驾~~--------Day5----司机认证篇~

前言&#xff1a; Hello亲爱的uu们&#xff0c;在读过了一个愉快的周末后&#xff08;摸鱼了一会&#xff09;&#xff0c;我又回来更新啦&#xff0c;感谢uu们的阅读&#xff0c;话不多说~ 司机认证 当司机点击开始接单的时候&#xff0c;会先判断该司机有没有通过认证&…

关于PCA的一份介绍

在这篇文章中&#xff0c;我将介绍机器学习中的一种无监督学习算法——PCA&#xff0c;因为它主要有两种用途&#xff0c;即降维与特征提取&#xff0c;所以我将将围绕这两种用途来介绍它&#xff0c;包括基本概念&#xff0c;应用与代码实践。 一、 PCA 1.1 概念 PCA&#…

dev containers plugins for vscode构建虚拟开发环境

0. 需求说明 自用笔记本构建一套开发环境&#xff0c;用docker 虚拟插件 dev containers,实现开发环境的构建&#xff0c;我想构建一套LLMs的环境&#xff0c;由于环境配置太多&#xff0c;不想污染本地环境&#xff0c;所以选择隔离技术 1. 环境准备 vscodedocker 2. 步骤…

任意长度并行前缀和 扫描算法 《PMPP》笔记

下面的算法针对于任意长度输入 对于大数据集&#xff0c;首先将输入分为几段&#xff0c;每一段放进共享内存并用一个线程块处理&#xff0c;比如一个线程块使用1024个线程的话&#xff0c;每个块最多能处理2048个元素。 在前面代码中&#xff0c;一个块最后的执行结果保存到了…

桥接模式和NET模式的区别

桥接模式和NET模式的区别 NAT模式&#xff1a; NAT&#xff1a;网络地址转换&#xff08;模式&#xff09;&#xff1a;借助宿主机来上网&#xff0c;没桥接那么麻烦&#xff0c;只用配置DNS即可。 缺点&#xff1a;扎根于宿主机&#xff0c;不能和局域网内其它真实的主机进行…

用Python实现运筹学——Day 2: 线性规划的基本概念

一、学习内容 线性规划的定义&#xff1a; 线性规划&#xff08;Linear Programming, LP&#xff09;是一种用于求解约束条件下线性目标函数最优解的方法。线性规划问题通常涉及最大化或最小化一个线性目标函数&#xff0c;目标函数的变量受一组线性不等式或等式的约束。 目标…

C语言 | Leetcode C语言题解之第435题无重叠区间

题目&#xff1a; 题解&#xff1a; int cmp(int** a, int** b) {return (*a)[1] - (*b)[1]; }int eraseOverlapIntervals(int** intervals, int intervalsSize, int* intervalsColSize) {if (intervalsSize 0) {return 0;}qsort(intervals, intervalsSize, sizeof(int*), cm…

【React】Ant Design 5.x版本drawer抽屉黑边问题

环境 antd: ^5.14.1react: ^18 问题情况 <Drawer open{open} closable{false} mask{false} width{680}getContainer{props.getContainer || undefined}><p>Some contents...</p><p>Some contents...</p><p>Some contents...</p> …

[网络] 网络层--IP协议

目录 一、IP协议 1.1 基本概念 1.2 IP协议报头 1.3 如何将报头和有效载荷分离和分用 1.4 分片与组装 1.5 如何减少分片&#xff1f; 1.6 分片和封装的具体过程 二、网段划分 2.1 再次理解IP地址 2.2 了解DHCP 2.3 网络划分方案 2.4 为什么要进行网络划分 2.5 特殊的…

Java基础——字节流和字符流

字节流和字符流的用法几乎完全一样&#xff0c;区别在于字节流和字符流所操作的数据单元不同&#xff0c;字节流操作的单元是数据单元是8位的字节&#xff0c;字符流操作的是数据单元为16位的字符。 为什么要有字符流&#xff1f; Java中字符是采用Unicode标准&#xff0c;Un…

【Go语言】Go语言结构体全面解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

基于 Canvas 的可缩放拖动网格示例(Vue3以及TypeScript )

文章目录 1. 基本知识2. Vue33. TypeScript 1. 基本知识 基本知识讲解&#xff1a; Canvas API&#xff1a; 一种用于在网页上绘制图形的 HTML 元素&#xff0c;使用 JavaScript 的 Canvas API 来进行绘制 使用 getContext(2d) 方法获取 2D 绘图上下文&#xff0c;允许开发者绘…

MySQL数据库备份详解

文章目录 引言● 数据库备份的重要性 MySQL数据库备份的基础知识● 备份类型1、完全备份2、增量备份3、差异备份 ● 备份工具与方法1、逻辑备份工具——mysqldump2、物理备份工具——Xtrabackup3、第三方解决方案 MySQL数据库备份的实施步骤1、环境准备2、选择合适的备份工具与…

【Linux基础IO】深入解析Linux基础IO缓冲区机制:提升文件操作效率的关键

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;暂无 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux基础IO &#x1f4d2;1. 什么是缓…

14.第二阶段x86游戏实战2-C++语言开发环境搭建-VisualStudio2017

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

基于jsonpath_ng的JSON数据查改增删

jsonpath_ng支持JSON数据的读写操作。 安装 pip install jsonpath-ng测试数据 from jsonpath_ng import parse import jsonjson_data { "store": {"book": [ { "category": "reference","author": "Nigel Rees&qu…