日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

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

發(fā)布時間:2025/3/20 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS - 使用 SQLite 数据库实现数据持久化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

SQLite 是一款主流的嵌入式關(guān)系型數(shù)據(jù)庫,它的主要特點是輕量級和跨平臺,是當(dāng)前很多嵌入式操作系統(tǒng)中數(shù)據(jù)庫的首選。

數(shù)據(jù)庫也是客戶端開發(fā)中常用的一種數(shù)據(jù)持久化手段,本文主要介紹在客戶端開發(fā)中常用的數(shù)據(jù)庫 SQLite,結(jié)合一個簡單的理解講解它引入、創(chuàng)建到后面 CRUD 的操作。

文章目錄

  • 前言
  • 1. sqlite3 引入
  • 2. sqlite3 的使用
    • 2.1 VGUserDAO 的封裝
    • 2.2 建表操作
    • 2.3 查詢操作
    • 2.4 插入操作
    • 2.5 修改操作
    • 2.6 刪除操作
  • 參考資料

1. sqlite3 引入

要想在 iOS 開發(fā)中使用 SQLite 數(shù)據(jù)庫,先要導(dǎo)入 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 類來實現(xiàn)我們要的操作,主要實現(xiàn)下面方法:

@interface VGUserDAO : NSObject/// 獲取 VGUserDAO 單例 + (instancetype)sheredInstance;/// 查找特定ID的用戶 - (VGUser *)findById:(NSString *)userId;/// 查詢所有用戶 - (NSArray *)findAll;/// 在數(shù)據(jù)表中插入一行數(shù)據(jù) - (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; // 數(shù)據(jù)庫對象 }// 數(shù)據(jù)庫的存儲路徑 @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];// 設(shè)置數(shù)據(jù)庫的存儲路徑sharedInstance.plistFilePath = [sharedInstance applicationDocumentsDirectory];// 執(zhí)行檢表操作[sharedInstance createEditableDatabaseIfNeed];});return sharedInstance; }// 獲取數(shù)據(jù)庫的存儲路徑 - (NSString *)applicationDocumentsDirectory {NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, TRUE) lastObject];NSString *path = [docDir stringByAppendingPathComponent:DBFILE_NAME];return path; }//......@end

2.2 建表操作

建表操作主要包含以下幾個步驟:

  • 使用 sqlite3_open 函數(shù)打開數(shù)據(jù)庫
  • 使用 sqlite3_exec 函數(shù)執(zhí)行建表的 SQL 語句,創(chuàng)建用戶表
  • 使用 sqlite3_close 函數(shù)關(guān)閉數(shù)據(jù)庫,釋放資源

具體的代碼實現(xiàn)如下:

- (void)createEditableDatabaseIfNeed {const char *cpath = self.plistFilePath.UTF8String;// sqlite3_open// 1. filename 是數(shù)據(jù)庫文件的完整路徑// 2. ppDb 是sqlite3類型指針變量的地址if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"數(shù)據(jù)庫打開失敗");} 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類型指針變量,表示數(shù)據(jù)庫// 2. sql 是要執(zhí)行的sql語句// 3. 要回調(diào)的函數(shù)指針// 4. 要回調(diào)的函數(shù)的第一個參數(shù)// 5. 執(zhí)行出錯信息的字符串if (sqlite3_exec(_db, cSql, NULL, NULL, NULL) != SQLITE_OK) {NSLog(@"建表失敗");}}// 關(guān)閉數(shù)據(jù)庫sqlite3_close(_db); }

建表的時候需要指定數(shù)據(jù)類型,SQLite 支持的常見數(shù)據(jù)類型如下所示:

  • integer,有符號的整數(shù)類型
  • real,浮點數(shù)
  • text,字符串類型,采用 UTF-8 和 UTF-16 編碼
  • blob,二進制大對象類型,能夠存放任何二進制數(shù)據(jù)

2.3 查詢操作

使用 sqlite3 執(zhí)行查詢操作,主要包括如下步驟:

  • 使用 sqlite3_open 函數(shù)打開數(shù)據(jù)庫
  • 使用 sqlite3_prepare_v2 函數(shù)預(yù)處理 SQL 語句
  • 使用 sqlite3_bind_text 等函數(shù)綁定參數(shù)
  • 使用 sqlite3_step 函數(shù)執(zhí)行 SQL 語句
  • 使用 sqlite3_column_text 等函數(shù)提取結(jié)果集中的字段
  • 使用 sqlite3_finalize 和 sqlite3_close 函數(shù)釋放資源

下面是對根據(jù) ID 查詢特定用戶的方法的實現(xiàn):

- (VGUser *)findById:(NSString *)userId {const char *cpath = self.plistFilePath.UTF8String;if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"數(shù)據(jù)庫打開失敗");} 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預(yù)處理函數(shù)// 1. db 是sqlite3類型指針變量,表示數(shù)據(jù)庫// 2. zSql 是要執(zhí)行的SQL語句// 3. nByte 是全部SQL字符串的最大長度// 4. ppStmt 是sqlite3_stmt類型指針的地址,表示語句對象// 5. pzTail 是zSql沒有執(zhí)行部分if (sqlite3_prepare_v2(_db, cSql, -1, &statement, NULL) == SQLITE_OK) {const char *cUserId = userId.UTF8String;// sqlite3_bind_text 綁定SQL語句TEXT類型的參數(shù)// 1. sqlite3_stmt類型指針// 2. 參數(shù)的序號,從 1 開始// 3. 參數(shù)的值// 4. 字符串長度// 5. 函數(shù)指針sqlite3_bind_text(statement, 1, cUserId, -1, NULL);// sqlite3_step 執(zhí)行語句if (sqlite3_step(statement) == SQLITE_ROW) {// sqlite3_column_text 讀取字符串類型數(shù)據(jù)// 1. 語句對象// 2. SELECT字段的索引,從 0 開始char *bufUserId = (char *)sqlite3_column_text(statement, 0);char *bufUserName = (char *)sqlite3_column_text(statement, 1);// sqlite3_column_int 讀取int類型數(shù)據(jù)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; }

下面是對查找所有用戶的方法的實現(xiàn):

- (NSArray *)findAll {const char *cpath = self.plistFilePath.UTF8String;NSMutableArray *userList = [NSMutableArray array];if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"數(shù)據(jù)庫打開失敗");} 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 表示結(jié)果集中還有數(shù)據(jù)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]; }

在進行字段讀取的時候,根據(jù)字段類型的不同,有下面幾種常用函數(shù):

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

我們可以根據(jù)字段的類型,選擇合適的函數(shù)。參數(shù)綁定函數(shù) sqlite3_bind_text 也是同理。

2.4 插入操作

使用 sqlite3 執(zhí)行插入操作,主要包含如下步驟:

  • 使用 sqlite3_open 函數(shù)打開數(shù)據(jù)庫
  • 使用 sqlite3_prepare_v2 函數(shù)預(yù)處理 SQL 語句
  • 使用 sqlite3_bind_text 等函數(shù)綁定參數(shù)
  • 使用 sqlite3_step 函數(shù)執(zhí)行 SQL 語句
  • 使用 sqlite3_finalize 和 sqlite3_close 函數(shù)釋放資源
- (void)create:(VGUser *)user {const char *cpath = self.plistFilePath.UTF8String;if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"數(shù)據(jù)庫打開失敗");} 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(@"數(shù)據(jù)插入失敗");}}sqlite3_finalize(statement);}sqlite3_close(_db); }

2.5 修改操作

對與修改操作而言,已經(jīng)沒有新東西可言了,主要差別還是在 SQL 語句,插入、修改和刪除用的分別是 insert、 update 和 delete。

- (void)modify:(VGUser *)user {const char *cpath = self.plistFilePath.UTF8String;if (sqlite3_open(cpath, &_db) != SQLITE_OK) {NSLog(@"數(shù)據(jù)庫打開失敗");} 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(@"數(shù)據(jù)修改失敗");}}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(@"數(shù)據(jù)庫打開失敗");} 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(@"數(shù)據(jù)刪除失敗");}}sqlite3_finalize(statement);}sqlite3_close(_db); }

參考資料

  • 《iOS開發(fā)指南:從Hello World到App Store上架(第5版)》

總結(jié)

以上是生活随笔為你收集整理的iOS - 使用 SQLite 数据库实现数据持久化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。