欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > 数据库 >内容正文

数据库

iOS - 使用 SQLite 数据库实现数据持久化

发布时间:2025/3/20 数据库 52 豆豆
生活随笔 收集整理的这篇文章主要介绍了 iOS - 使用 SQLite 数据库实现数据持久化 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

前言

SQLite 是一款主流的嵌入式关系型数据库,它的主要特点是轻量级和跨平台,是当前很多嵌入式操作系统中数据库的首选。

数据库也是客户端开发中常用的一种数据持久化手段,本文主要介绍在客户端开发中常用的数据库 SQLite,结合一个简单的理解讲解它引入、创建到后面 CRUD 的操作。

文章目录

  • 前言
  • 1. sqlite3 引入
  • 2. sqlite3 的使用
    • 2.1 VGUserDAO 的封装
    • 2.2 建表操作
    • 2.3 查询操作
    • 2.4 插入操作
    • 2.5 修改操作
    • 2.6 删除操作
  • 参考资料

1. sqlite3 引入

要想在 iOS 开发中使用 SQLite 数据库,先要导入 libsqlite3.tbd。具体路径是 TARGETS -> Build Phases -> Link Binary With Libraries。操作如下图所示:

2. sqlite3 的使用

这里以一个简单的例子来介绍 sqlite3 的使用,我们有个用户表,里面有用户id,用户名称和用户年龄等三个字段,我们使用 sqlite3 对它进行增删改查

下面是用户类的定义:

@interface VGUser : NSObject// 用户ID @property (nonatomic, copy) NSString *userId; // 用户名 @property (nonatomic, copy) NSString *userName; // 用户年龄 @property (nonatomic, assign) NSInteger userAge;- (instancetype)initWithUserId:(NSString *)userIduserName:(NSString *)userNameuserAge:(NSInteger)userAge;@end

2.1 VGUserDAO 的封装

为了满足我们的需求,我们封装一个 VGUserDAO 类来实现我们要的操作,主要实现下面方法:

@interface VGUserDAO : NSObject/// 获取 VGUserDAO 单例 + (instancetype)sheredInstance;/// 查找特定ID的用户 - (VGUser *)findById:(NSString *)userId;/// 查询所有用户 - (NSArray *)findAll;/// 在数据表中插入一行数据 - (void)create:(VGUser *)user;/// 删除特定ID的用户 - (void)remove:(NSString *)userId;/// 修改用户信息 - (void)modify:(VGUser *)user;@end

VGUserDAO.m 文件的部分代码

#import "VGUser.h" #import <sqlite3.h>#define DBFILE_NAME @"UserList.sqlite3"@interface VGUserDAO () {sqlite3 *_db; // 数据库对象 }// 数据库的存储路径 @property (nonatomic, strong) NSString *plistFilePath;@end@implementation VGUserDAO+ (instancetype)sheredInstance {static VGUserDAO *sharedInstance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^ {sharedInstance = [[VGUserDAO alloc] init];// 设置数据库的存储路径sharedInstance.plistFilePath = [sharedInstance applicationDocumentsDirectory];// 执行检表操作[sharedInstance createEditableDatabaseIfNeed];});return sharedInstance; }// 获取数据库的存储路径 - (NSString *)applicationDocumentsDirectory {NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, TRUE) lastObject];NSString *path = [docDir stringByAppendingPathComponent:DBFILE_NAME];return path; }//......@end

2.2 建表操作

建表操作主要包含以下几个步骤:

  • 使用 sqlite3_open 函数打开数据库
  • 使用 sqlite3_exec 函数执行建表的 SQL 语句,创建用户表
  • 使用 sqlite3_close 函数关闭数据库,释放资源

具体的代码实现如下:

- (void)createEditableDatabaseIfNeed {const char *cpath = self.plistFilePath.UTF8String;// sqlite3_open// 1. filename 是数据库文件的完整路径// 2. ppDb 是sqlite3类型指针变量的地址if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"数据库打开失败");} else {NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS User (user_id TEXT PRIMARY KEY, user_name TEXT, user_age INTEGER);"];const char *cSql = sql.UTF8String;// sqlite3_exec// 1. sqlite3类型指针变量,表示数据库// 2. sql 是要执行的sql语句// 3. 要回调的函数指针// 4. 要回调的函数的第一个参数// 5. 执行出错信息的字符串if (sqlite3_exec(_db, cSql, NULL, NULL, NULL) != SQLITE_OK) {NSLog(@"建表失败");}}// 关闭数据库sqlite3_close(_db); }

建表的时候需要指定数据类型,SQLite 支持的常见数据类型如下所示:

  • integer,有符号的整数类型
  • real,浮点数
  • text,字符串类型,采用 UTF-8 和 UTF-16 编码
  • blob,二进制大对象类型,能够存放任何二进制数据

2.3 查询操作

使用 sqlite3 执行查询操作,主要包括如下步骤:

  • 使用 sqlite3_open 函数打开数据库
  • 使用 sqlite3_prepare_v2 函数预处理 SQL 语句
  • 使用 sqlite3_bind_text 等函数绑定参数
  • 使用 sqlite3_step 函数执行 SQL 语句
  • 使用 sqlite3_column_text 等函数提取结果集中的字段
  • 使用 sqlite3_finalize 和 sqlite3_close 函数释放资源

下面是对根据 ID 查询特定用户的方法的实现:

- (VGUser *)findById:(NSString *)userId {const char *cpath = self.plistFilePath.UTF8String;if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"数据库打开失败");} else {NSString *sql = @"select user_id, user_name, user_age from user where user_id = ?";const char *cSql = sql.UTF8String;// 语句对象sqlite3_stmt *statement;// sqlite3_prepare_v2 SQL预处理函数// 1. db 是sqlite3类型指针变量,表示数据库// 2. zSql 是要执行的SQL语句// 3. nByte 是全部SQL字符串的最大长度// 4. ppStmt 是sqlite3_stmt类型指针的地址,表示语句对象// 5. pzTail 是zSql没有执行部分if (sqlite3_prepare_v2(_db, cSql, -1, &statement, NULL) == SQLITE_OK) {const char *cUserId = userId.UTF8String;// sqlite3_bind_text 绑定SQL语句TEXT类型的参数// 1. sqlite3_stmt类型指针// 2. 参数的序号,从 1 开始// 3. 参数的值// 4. 字符串长度// 5. 函数指针sqlite3_bind_text(statement, 1, cUserId, -1, NULL);// sqlite3_step 执行语句if (sqlite3_step(statement) == SQLITE_ROW) {// sqlite3_column_text 读取字符串类型数据// 1. 语句对象// 2. SELECT字段的索引,从 0 开始char *bufUserId = (char *)sqlite3_column_text(statement, 0);char *bufUserName = (char *)sqlite3_column_text(statement, 1);// sqlite3_column_int 读取int类型数据int bufUserAge = sqlite3_column_int(statement, 2);NSString *strUserId = [[NSString alloc] initWithUTF8String:bufUserId];NSString *strUserName = [[NSString alloc] initWithUTF8String:bufUserName];VGUser *user = [[VGUser alloc] initWithUserId:strUserIduserName:strUserNameuserAge:bufUserAge];// 释放语句对象sqlite3_finalize(statement);sqlite3_close(_db);return user;}}sqlite3_finalize(statement);}sqlite3_close(_db);return nil; }

下面是对查找所有用户的方法的实现:

- (NSArray *)findAll {const char *cpath = self.plistFilePath.UTF8String;NSMutableArray *userList = [NSMutableArray array];if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"数据库打开失败");} else {NSString *sql = @"select user_id, user_name, user_age from user";const char *cSql = sql.UTF8String;sqlite3_stmt *statement;if (sqlite3_prepare_v2(_db, cSql, -1, &statement, NULL) == SQLITE_OK) {// 常量 SQLITE_ROW 表示结果集中还有数据while (sqlite3_step(statement) == SQLITE_ROW) {char *bufUserId = (char *)sqlite3_column_text(statement, 0);char *bufUserName = (char *)sqlite3_column_text(statement, 1);int bufUserAge = sqlite3_column_int(statement, 2);NSString *strUserId = [[NSString alloc] initWithUTF8String:bufUserId];NSString *strUserName = [[NSString alloc] initWithUTF8String:bufUserName];VGUser *user = [[VGUser alloc] initWithUserId:strUserIduserName:strUserNameuserAge:bufUserAge];[userList addObject:user];}}sqlite3_finalize(statement);}sqlite3_close(_db);return [userList copy]; }

在进行字段读取的时候,根据字段类型的不同,有下面几种常用函数:

  • sqlite3_column_int()
  • sqlite3_column_int64()
  • sqlite3_column_double()
  • sqlite3_column_text()
  • sqlite3_column_text16()
  • sqlite3_column_blob()

我们可以根据字段的类型,选择合适的函数。参数绑定函数 sqlite3_bind_text 也是同理。

2.4 插入操作

使用 sqlite3 执行插入操作,主要包含如下步骤:

  • 使用 sqlite3_open 函数打开数据库
  • 使用 sqlite3_prepare_v2 函数预处理 SQL 语句
  • 使用 sqlite3_bind_text 等函数绑定参数
  • 使用 sqlite3_step 函数执行 SQL 语句
  • 使用 sqlite3_finalize 和 sqlite3_close 函数释放资源
- (void)create:(VGUser *)user {const char *cpath = self.plistFilePath.UTF8String;if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"数据库打开失败");} else {NSString *sql = @"insert or replace into user (user_id, user_name, user_age) values (?, ?, ?)";const char *cSql = sql.UTF8String;sqlite3_stmt *statement;if (sqlite3_prepare_v2(_db, cSql, -1, &statement, NULL) == SQLITE_OK) {const char *cUserId = user.userId.UTF8String;const char *cUserName = user.userName.UTF8String;const int cUserAge = (int)user.userAge;sqlite3_bind_text(statement, 1, cUserId, -1, NULL);sqlite3_bind_text(statement, 2, cUserName, -1, NULL);sqlite3_bind_int(statement, 3, cUserAge);if (sqlite3_step(statement) != SQLITE_DONE) {NSLog(@"数据插入失败");}}sqlite3_finalize(statement);}sqlite3_close(_db); }

2.5 修改操作

对与修改操作而言,已经没有新东西可言了,主要差别还是在 SQL 语句,插入、修改和删除用的分别是 insert、 update 和 delete。

- (void)modify:(VGUser *)user {const char *cpath = self.plistFilePath.UTF8String;if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"数据库打开失败");} else {NSString *sql = @"update user set user_name = ?, user_age = ? where user_id = ?";const char *cSql = sql.UTF8String;sqlite3_stmt *statement;if (sqlite3_prepare_v2(_db, cSql, -1, &statement, NULL) == SQLITE_OK) {const char *cUserId = user.userId.UTF8String;const char *cUserName = user.userName.UTF8String;const int cUserAge = (int)user.userAge;sqlite3_bind_text(statement, 1, cUserName, -1, NULL);sqlite3_bind_int(statement, 2, cUserAge);sqlite3_bind_text(statement, 3, cUserId, -1, NULL);if (sqlite3_step(statement) != SQLITE_DONE) {NSLog(@"数据修改失败");}}sqlite3_finalize(statement);}sqlite3_close(_db); }

2.6 删除操作

- (void)remove:(NSString *)userId {const char *cpath = self.plistFilePath.UTF8String;if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"数据库打开失败");} else {NSString *sql = @"delete from user where user_id = ?";const char *cSql = sql.UTF8String;sqlite3_stmt *statement;if (sqlite3_prepare_v2(_db, cSql, -1, &statement, NULL) == SQLITE_OK) {const char *cUserId = userId.UTF8String;sqlite3_bind_text(statement, 1, cUserId, -1, NULL);if (sqlite3_step(statement) != SQLITE_DONE) {NSLog(@"数据删除失败");}}sqlite3_finalize(statement);}sqlite3_close(_db); }

参考资料

  • 《iOS开发指南:从Hello World到App Store上架(第5版)》

总结

以上是生活随笔为你收集整理的iOS - 使用 SQLite 数据库实现数据持久化的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。