Objective-C语言的数据库交互
Objective-C语言的数据库交互
引言
在现代应用程序开发过程中,数据库在数据存储和管理方面起着至关重要的作用。对于iOS应用开发者而言,掌握如何在Objective-C中与数据库交互显得尤为重要。本文将全面探讨Objective-C的数据库交互,包括SQLite的基本用法、数据模型的设计、常用的数据库操作及在实际应用中的综合示例。
1. 数据库基础
在深入Objective-C的数据库交互之前,我们首先来了解一下数据库的基本概念。数据库(Database)是一种长期存储数据的结构化集合。根据数据模型的不同,数据库可以分为关系型数据库和非关系型数据库。关系型数据库(如MySQL、SQLite)使用表格来存储数据,而非关系型数据库(如MongoDB)则使用键值对、文档等方式。
1.1 SQLite简介
SQLite是一种轻量级的关系型数据库,广泛应用于移动应用程序中。它的特点是:
- 轻量级:SQLite数据库文件通常只需一个简单的文件即可。
- 跨平台:可以在多种平台上运行,包括iOS、Android等。
- 无服务器:SQLite不需要安装任何服务器软件,方便快捷。
- 事务处理支持:支持ACID特性,保证数据的完整性。
2. Objective-C与SQLite的结合
2.1 引入SQLite库
在iOS项目中使用SQLite之前,我们需要引入SQLite库。打开Xcode,在项目的“Build Phases”选项中找到“Link Binary With Libraries”,然后添加libsqlite3.tbd
。
2.2 导入头文件
在需要进行数据库操作的类中,我们需要导入SQLite的头文件:
```objc
import
```
2.3 创建数据库
在使用SQLite之前,我们需要创建一个数据库文件。以下是一个创建数据库的基本代码示例:
```objc - (NSString )getDatabasePath { NSString docsDir; NSArray *dirPaths;
// 获取文档目录
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];// 数据库文件名
return [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:@"mydatabase.db"]];
}
-
(void)createDatabase { NSString *dbPath = [self getDatabasePath];
// 创建数据库 sqlite3 *database; if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) { NSLog(@"数据库创建成功"); } else { NSLog(@"数据库创建失败"); } sqlite3_close(database); } ```
在上述代码中,我们首先获取了应用程序的文档目录,然后在该目录下创建了一个名为mydatabase.db
的数据库。
2.4 创建数据表
创建完数据库后,我们需要定义数据表的结构。例如,我们创建一个用于存储用户信息的表:
```objc - (void)createTable { NSString dbPath = [self getDatabasePath]; sqlite3 database;
// 打开数据库
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {const char *sqlStatement = "CREATE TABLE IF NOT EXISTS Users (ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT, Age INTEGER)";char *errMsg;// 执行SQL语句if (sqlite3_exec(database, sqlStatement, NULL, NULL, &errMsg) != SQLITE_OK) {NSLog(@"创建表失败: %s", errMsg);} else {NSLog(@"表创建成功");}
}
sqlite3_close(database);
} ```
在这里,我们使用SQL的CREATE TABLE语句创建了一个名为Users
的表,其中包括ID
、Name
和Age
三个字段。
2.5 插入数据
在创建了表之后,我们可以开始插入数据。以下是插入数据的示例代码:
```objc - (void)insertUserWithName:(NSString )name age:(NSInteger)age { NSString dbPath = [self getDatabasePath]; sqlite3 *database;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {// 准备SQL语句const char *sqlStatement = "INSERT INTO Users (Name, Age) VALUES (?, ?)";sqlite3_stmt *statement;// 编译SQL语句if (sqlite3_prepare_v2(database, sqlStatement, -1, &statement, NULL) == SQLITE_OK) {// 绑定参数sqlite3_bind_text(statement, 1, [name UTF8String], -1, SQLITE_TRANSIENT);sqlite3_bind_int(statement, 2, (int)age);// 执行SQL语句if (sqlite3_step(statement) == SQLITE_DONE) {NSLog(@"插入用户成功");} else {NSLog(@"插入用户失败");}} else {NSLog(@"准备SQL语句失败");}sqlite3_finalize(statement);
}
sqlite3_close(database);
} ```
上述代码展示了如何通过INSERT
语句将用户信息插入到Users
表中。我们使用sqlite3_prepare_v2
来编译SQL语句,并使用sqlite3_bind_text
和sqlite3_bind_int
绑定参数。
2.6 查询数据
获取数据也是数据库交互中一个重要的部分。以下是查询用户信息的示例代码:
```objc - (void)fetchAllUsers { NSString dbPath = [self getDatabasePath]; sqlite3 database;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {const char *sqlStatement = "SELECT * FROM Users";sqlite3_stmt *statement;if (sqlite3_prepare_v2(database, sqlStatement, -1, &statement, NULL) == SQLITE_OK) {while (sqlite3_step(statement) == SQLITE_ROW) {// 获取数据NSInteger ID = sqlite3_column_int(statement, 0);char *nameChars = (char *)sqlite3_column_text(statement, 1);NSInteger age = sqlite3_column_int(statement, 2);NSString *name = [[NSString alloc] initWithUTF8String:nameChars];NSLog(@"ID: %ld, Name: %@, Age: %ld", (long)ID, name, (long)age);}} else {NSLog(@"准备SQL语句失败");}sqlite3_finalize(statement);
}
sqlite3_close(database);
} ```
在这个方法中,我们选择所有用户并打印出他们的信息。通过sqlite3_column_int
和sqlite3_column_text
函数,我们可以获取到查询结果中的数据。
2.7 更新数据
更新数据使用UPDATE
语句。以下是更新用户年龄的示例代码:
```objc - (void)updateUserAgeWithID:(NSInteger)userID newAge:(NSInteger)newAge { NSString dbPath = [self getDatabasePath]; sqlite3 database;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {const char *sqlStatement = "UPDATE Users SET Age = ? WHERE ID = ?";sqlite3_stmt *statement;if (sqlite3_prepare_v2(database, sqlStatement, -1, &statement, NULL) == SQLITE_OK) {sqlite3_bind_int(statement, 1, (int)newAge);sqlite3_bind_int(statement, 2, (int)userID);if (sqlite3_step(statement) == SQLITE_DONE) {NSLog(@"更新用户成功");} else {NSLog(@"更新用户失败");}} else {NSLog(@"准备SQL语句失败");}sqlite3_finalize(statement);
}
sqlite3_close(database);
} ```
2.8 删除数据
删除数据使用DELETE
语句。以下是删除用户的示例代码:
```objc - (void)deleteUserWithID:(NSInteger)userID { NSString dbPath = [self getDatabasePath]; sqlite3 database;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {const char *sqlStatement = "DELETE FROM Users WHERE ID = ?";sqlite3_stmt *statement;if (sqlite3_prepare_v2(database, sqlStatement, -1, &statement, NULL) == SQLITE_OK) {sqlite3_bind_int(statement, 1, (int)userID);if (sqlite3_step(statement) == SQLITE_DONE) {NSLog(@"删除用户成功");} else {NSLog(@"删除用户失败");}} else {NSLog(@"准备SQL语句失败");}sqlite3_finalize(statement);
}
sqlite3_close(database);
} ```
3. 实践示例
为了更好地理解SQLite与Objective-C的结合,我们可以设计一个简单的用户管理应用程序。该程序将允许用户添加、查看、更新和删除用户信息。以下是我们应用程序的基本逻辑结构:
- 用户界面:使用UIKit进行简单的界面布局。
- 数据模型:使用SQLite存储用户信息,包括名字和年龄。
- 功能实现:实现上述数据库操作的方法。
3.1 用户界面
我们可以使用UITableView
来显示用户列表,并提供UIButton
来添加新的用户。界面设计可以是这样的:
- 一个文本框用于输入名字
- 一个文本框用于输入年龄
- 一个按钮用于添加用户
- 一个表格用于显示用户列表
3.2 数据模型
我们可以将关于用户的操作封装到一个UserDatabaseManager
类中,提供使用SQLite进行所有数据库操作的方法。
3.3 应用逻辑
结合上面的增、删、改、查功能,我们的应用程序将从用户输入中获取数据,并通过UserDatabaseManager
类将数据与SQLite数据库进行交互。
总结
数据库交互是现代应用开发中不可或缺的一部分。Objective-C对SQLite的支持使得开发者能够轻松地构建数据驱动的应用程序。通过本文的介绍,相信您已经掌握了使用Objective-C与SQLite进行基本数据库操作的能力。在实际应用开发中,开发者可以根据项目需求进行更加复杂的数据库设计和操作。
后续的学习可以深入到ORM(对象关系映射)框架(如FMDB)和更复杂的查询优化等方面,以提升交互性能和开发效率。希望本文能为您的学习与开发提供帮助!
相关文章:
Objective-C语言的数据库交互
Objective-C语言的数据库交互 引言 在现代应用程序开发过程中,数据库在数据存储和管理方面起着至关重要的作用。对于iOS应用开发者而言,掌握如何在Objective-C中与数据库交互显得尤为重要。本文将全面探讨Objective-C的数据库交互,包括SQLi…...

基于 Spring Boot 和 Vue.js 的全栈购物平台开发实践
在现代 Web 开发中,前后端分离的架构已经成为主流。本文将分享如何使用 Spring Boot 和 Vue.js构建一个全栈购物平台,涵盖从后端 API 开发到前端页面实现的完整流程。 1. 技术栈介绍 后端技术栈 JDK 1.8:稳定且广泛使用的 Java 版本。 Spring…...
笔记(数据运营方向)
以下是一些在工作过程中的小笔记,写的比较杂乱,后续再进行分类~ 1、掌握sql窗口函数 窗口函数又名开窗函数,属于分析函数的一种。用于解决复杂报表统计需求的功能强大的函数。窗口函数用于计算基于组的某种聚合值,它和聚合函数的…...

qt vs ios开发应用环境搭建和上架商店的记录
qt 下载链接如下 https://download.qt.io/new_archive/qt/5.14/5.14.2/qt-opensource-mac-x64-5.14.2.dmg 安装选项全勾选就行,这里特别说明下qt5.14.2/qml qt5.14.2对qml支持还算成熟,但很多特性还得qt6才行,这里用qt5.14.2主要是考虑到服…...
[cg] glDrawBuffers MRT的应用
glDrawBuffers 是 OpenGL 中的一个函数,用于指定渲染结果输出到哪些颜色缓冲区。它通常在多渲染目标(MRT, Multiple Render Targets)中使用,允许一个渲染操作同时将结果输出到多个颜色缓冲区,而不是默认情况下的单个颜…...

IO模型与NIO基础二
抽象基类之二 FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流,并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能,以及mark()和res…...

【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)
单例模式 作用:单例模式的核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全,调用效率高 ,但是不能延迟加载懒汉式线程安全,调用效率不高,能延迟加载双重检…...
T-SQL语言的数据库交互
T-SQL语言的数据库交互 引言 随着信息技术的不断发展,数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL(Transact-SQL)作为微软SQL Server的重要扩展语言…...

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)
inode 和 block 的映射 该博文中有详细解释:【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题: 问题一: 我们访问文件,都是用的文件名,没用过 inode 号啊? 之前总是说可以通过一个…...

慧集通(DataLinkX)iPaaS集成平台-业务建模之域
通过左侧导航菜单〖业务建模〗→〖域〗,进入该界面;在该界面可以查看到系统中已存在的域列表。 新建域 在慧集通平台中进入【业务建模】的【域】页面,点击【新建】按钮进入新建页面;输入编码,名称、模块以及对应数据类…...
【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题
【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络,通过对抗生成网络生成少数类样本,平衡欺诈数据中正类样本极…...
android wifi framework与wpa_supplicant的交互
android frmework直接与wpa_supplicant进行交互,使用aidl或者hidl 二、事件 framework注册事件的地方: packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…...

初学stm32 --- flash模仿eeprom
目录 STM32内部FLASH简介 内部FLASH构成(F1) FLASH读写过程(F1) 闪存的读取 闪存的写入 内部FLASH构成(F4 / F7 / H7) FLASH读写过程(F4 / F7 / H7) 闪存的读取 闪存的写入 …...

使用C语言实现栈的插入、删除和排序操作
栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...

C语言程序环境和预处理详解
本章重点: 程序的翻译环境 程序的执行环境 详解:C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...

基于机器学习随机森林算法的个人职业预测研究
1.背景调研 随着信息技术的飞速发展,特别是大数据和云计算技术的广泛应用,各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式,为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步,如深度学习、强化学习等…...

三种文本相似计算方法:规则、向量与大模型裁判
文本相似计算 项目背景 目前有众多工作需要评估字符串之间的相似(相关)程度: 比如,RAG 智能问答系统文本召回阶段需要计算用户文本与文本库内文本的相似分数,返回前TopK个候选文本。 在评估大模型生成的文本阶段,也需要评估…...
Python语言的计算机基础
Python语言的计算机基础 绪论 在当今信息技术飞速发展的时代,编程已经成为了一种必备技能。Python凭借其简洁、易读和强大的功能,逐渐成为初学者学习编程的首选语言。本文将以Python语言为基础,探讨计算机科学的基本概念,并帮助…...

Dify应用-工作流
目录 DIFY 工作流参考 DIFY 工作流 2025-1-15 老规矩感谢参考文章的作者,避免走弯路。 2025-1-15 方便容易上手 在dify的一个桌面上,添加多个节点来完成一个任务。 每个工作流必须有一个开始和结束节点。 节点之间用线连接即可。 每个节点可以有输入和输出 输出类型有,字符串,…...
02.02、返回倒数第 k 个节点
02.02、[简单] 返回倒数第 k 个节点 1、题目描述 实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。 2、题解思路 本题的关键在于使用双指针法,通过两个指针(fast 和 slow),让 fast 指针比 slow 指针…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...