IOS中数据存储 sqlite3 的应用, 知识点: 数据库句柄 , 单例模式运用, Services服务层,sqlite3_open, sqlite3_exec, sqlite3_prepare_v2,sqlite3_step等等

相比于服务器端的数据存储,IOS中几种数据存储的技术:

(1)XML属性列表 —— PList

(2)NSKeyedArchiver 归档

(3)Preference(偏好设置)

(4)SQLite3

(5)Core Data(以面向对象的方式操作数据库SQLite)

发现用数据库进行数据的存储和缓存,才是王道,
比较有心得的体会:虽然通过文件的方式进行存储,读写速度相对数据库存储较快,但是涉及大批量的数据时,在查询/管理/优化方面,数据库的优势明显会更大些.而且作为移动端,SQLite数据库在数据缓存方面的运用则尤为重要.

工作之余,运用SQLite3的许多小知识点,写了一个小小的数据库增删改查操作,专门与sqlite3交互的个人信息管理类,直接上代码,望大牛指正:

底层架构图

核心代码实现:

(1) Services服务层封装

PesonManager.h


#import <Foundation/Foundation.h>
#import "Person.h"

@interface PersonManager : NSObject

+ (instancetype)sharedPersonManager;

// 1. 新增用户
- (void)addPerson:(Person *)person;

// 2. 更新用户(关于主键,永远都不要去修改)
- (void)updatePerson:(Person *)person;

// 3. 删除用户,使用主键来删除指定用户
- (void)removePerson:(NSInteger)personID;

// 4. 列表用户,查询所有用户
- (NSArray *)allPersons;

@end

PesonManager.m 

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

#import "PersonManager.h"

#import <sqlite3.h>

#import "NSString+JH.h"

// 全局变量

static PersonManager *_instance;

@interface
PersonManager()

{

    // 全局的数据库句柄

    sqlite3 *_db;

}

@end

@implementation
PersonManager

#pragma mark - 单例的方法

+ (id)allocWithZone:(struct
_NSZone *)zone

{

    static
dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instance = [super
allocWithZone:zone];

    });

 

    return
_instance;

}

+ (instancetype)sharedPersonManager

{

    if
(_instance == nil) {

        _instance = [[PersonManager alloc] init];

    }

    

    return
_instance;

}

#pragma mark - 类方法

- (id)init

{

    self
= [super
init];

    

    // 懒加载数据库连接及创建数据表

    if
(self) {

        // 1. 打开数据库

        [self
openDB];

        // 2. 创建数据表

        [self
createTable];

    }

    

    return
self;

}

#pragma mark 打开数据库

- (void)openDB

{

  

    NSString
*dbPath = [@"T_Person.db"
appendDocumentDir];

    _db = NULL;

    

    if
(SQLITE_OK == sqlite3_open([dbPath UTF8String], &_db)) {

        NSLog(@"数据库打开成功");

    } else
{

        NSLog(@"数据库打开失败");

    }

}

#pragma mark 单步执行SQL

- (void)execSQL:(NSString
*)sql message:(NSString
*)message

{

    char
*errmsg = NULL;

    if
(SQLITE_OK == sqlite3_exec(_db, [sql UTF8String], NULL, NULL, &errmsg)) {

        NSLog(@"%@成功!", message);

    } else
{

        NSLog(@"%@失败 - %s", message, errmsg);

    }

}

#pragma mark 创建数据表

- (void)createTable

{

    NSString
*sql = @"CREATE TABLE IF NOT EXISTS T_Person (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT, gender INTEGER, age INTEGER, height REAL)";

    

    [self
execSQL:sql message:@"创建数据表"];

}

- (void)addPerson:(Person *)person

{<br> // 1. SQL

    NSString
*sql = [NSString
stringWithFormat:@"INSERT INTO T_Person (name, gender, age, height) VALUES (‘%@‘, %d, %d, %f)", person.name, person.gender, person.age, person.height];

    [self
execSQL:sql message:@"新增个人记录"];

}

// 2. 更新用户(关于主键,永远都不要去修改)

- (void)updatePerson:(Person *)person where: (NSStirng
*)where

{

   NSString
*sql =  [NSString
stringWithFormat:@"UPDATE  T_Person  SET name = ‘%@‘, gender = %d, age = %d, height = %f where %@", person.name, person.gender, person.age, person.height , where];

    [self
execSQL:sql message:@"更新个人记录"];

}

// 3. 删除用户,使用主键来删除指定用户

- (void)removePerson:(NSInteger)personID

{

    NSString
*sql =[NSString
stringWithFormat: @"delete * from T_Person where id =%@",personID];

   [self
execSQL:sql message:@"删除记录成功"];

}

// 4. 列表用户,查询所有用户

- (NSArray
*)allPersons

{

    NSString
*sql = @"SELECT id, name, age, gender, height FROM T_Person ORDER BY name";

    sqlite3_stmt *stmt = NULL;

    NSMutableArray
*arrayM = [NSMutableArray
array];

    NSMutableArray
*persons = nil;

    if
(SQLITE_OK == sqlite3_prepare_v2(_db, [sql UTF8String], -1, &stmt, NULL)) {

        persons = [NSMutableArray
array];

        while
(SQLITE_ROW == sqlite3_step(stmt)) {

            int
ID = sqlite3_column_int(stmt, 0);

            const
unsigned char
*name = sqlite3_column_text(stmt, 1);

            int
age = sqlite3_column_int(stmt, 2);

            int
gender = sqlite3_column_int(stmt, 3);

            CGFloat height = sqlite3_column_double(stmt, 4);

            

            // const unsigned char *直接输出看不出结果,需要转换

            NSString
*nameUTF8 = [NSString
stringWithUTF8String:(const
char *)name];

            

            Person *p = [Person personWithID:ID name:nameUTF8 age:age gender:gender height:height];

            

            [persons addObject:p];

        }

    } else
{

        NSLog(@"语法错误");

    }

    

    return
persons;

}

@end

接下来在控制器里面封装模型取出相应数据即可,关于SQLite3中运用的知识点,总结如下:


1.  sqlite3_open 打开数据库
* 如果数据库已经存在,直接打开
* 如果数据库不存在,新建一个空白的数据库(0KB),然后再打开

2. 创建数据表
* 定义数据操作SQL
* 调用sqlite3_exec执行SQL
提示:为了避免重复建表,可以在建表SQL中增加 IF NOT EXISTS

3. 单步执行操作
增/删/改/查数据

4. 查询语句
1> 准备SQL
2> 检查SQL语句是否正确 sqlite3_prepare_v2
3> 单步执行,依次获取查询到的记录 SQLITE_ROW == sqlite3_step...
4> 按照查询顺序,依次取出每一个字段的内容
sqlite3_column_text 取字符串
sqlite3_column_int 取整数
sqlite3_column_double 取浮点数

5.操作SQLite数据库需要5个方法
sqlite3_open
sqlite3_exec

sqlite3_prepare_v2
sqlite3_step

sqlite3_column_text 取字符串
sqlite3_column_int 取整数
sqlite3_column_double 取浮点数
两个枚举
SQLITE_OK
SQLITE_ROW

当然,一般在实际开发中都会直接封装成一套数据库操作类,但是对于SQL结构化查询,无论是服务器开发,还是客户端开发,都是万变不离其中.

IOS中数据存储 sqlite3 的应用, 知识点: 数据库句柄 , 单例模式运用,
Services服务层,sqlite3_open, sqlite3_exec,
sqlite3_prepare_v2,sqlite3_step等等

时间: 2024-08-24 14:05:13

IOS中数据存储 sqlite3 的应用, 知识点: 数据库句柄 , 单例模式运用, Services服务层,sqlite3_open, sqlite3_exec, sqlite3_prepare_v2,sqlite3_step等等的相关文章

ios中数据存储方式

以上三种不能存储大批量数据 plist只能先取出来 里面的数据 覆盖存储 SQLLite3 数据库 纯C语言 轻量级 CoreData  基于SQLLite3 OC版本 重量级 大批量数据缓存 SQLLite3

IOS开发数据存储篇—IOS中的几种数据存储方式

IOS开发数据存储篇—IOS中的几种数据存储方式 发表于2016/4/5 21:02:09  421人阅读 分类: 数据存储 在项目开发当中,我们经常会对一些数据进行本地缓存处理.离线缓存的数据一般都保存在APP所在的沙盒之中.一般有以下几种: 1.PList(XML属性列表) 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦 //写入文件 NSString *doc = [NSSearchPathForDirectoriesInDomains(

IOS应用数据存储

IOS应用数据存储 常用方式 - XML属性列表(plist)归档 - Preference(偏好设置) - NSKeyedArchiver归档(NSCoding) - SQLite3 - Core Data 应用程序沙盒 每个应用程序都有自己的应用沙盒(应用沙盒就是文件系统目录)与其它文件系统隔离.应用必须呆在 自己的沙盒里,其它应用不能访问该沙盒 应用沙盒目录<假设应用名字Layer>  应用沙盒结构分析 应用沙盒的常见获取方式 沙盒根目录:NSString *home = NSHomeD

iOS应用数据存储的常用方式

ios程序中数据数据存储有下列5种方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core Data 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒 应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer) 模拟器应用沙盒的根路径在: (apple是用户名, 7.0是模拟器版本) /Users/apple/L

iOS 应用数据存储方式(XML属性列表-plist)

iOS 应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存储自定义对象) 4.SQLite3(数据库,关系型数据库,不能直接存储对象,要编写一些数据库的语句,将对象拆开存储) 5.Core Data(对象型的数据库,把内部环节屏蔽) 二.应用沙盒 每个iOS应用都有?己的应?沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应?必须待在?己的沙盒里,其他应用不能访问该

ios应用数据存储方式(XML属性列表-plist)

ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存储自定义对象) 4.SQLite3(数据库,关系型数据库,不能直接存储对象,要编写一些数据库的语句,将对象拆开存储) 5.Core Data(对象型的数据库,把内部环节屏蔽) 二.应用沙盒 每个iOS应用都有?己的应?沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应?必须待在?己的沙盒里,其他应用不能访问该沙

iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist

iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存储自定义对象) 4.SQLite3(数据库,关系型数据库,不能直接存储对象,要编写一些数据库的语句,将对象拆开存储) 5.Core Data(对象型的数据库,把内部环节屏蔽) 二.应用沙盒 每个iOS应用都有?己的应?沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应?必须待在?己的沙盒里,其

OS开发UI篇—ios应用数据存储方式(归档)

OS开发UI篇—ios应用数据存储方式(归档)  一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同一个文件夹下面,且主要用于存储应用的设置信息) 归档:因为前两者都有一个致命的缺陷,只能存储常用的类型.归档可以实现把自定义的对象存放在文件中. 二.代码示例 1.文件结构 2.代码示例 YYViewController.m文件 1 // 2 // YYViewController.m 3 // 02

iOS开发UI篇—ios应用数据存储方式(归档)

iOS开发UI篇-ios应用数据存储方式(归档)  一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同一个文件夹下面,且主要用于存储应用的设置信息) 归档:因为前两者都有一个致命的缺陷,只能存储常用的类型.归档可以实现把自定义的对象存放在文件中. 二.代码示例 1.文件结构 2.代码示例 YYViewController.m文件 1 // 2 // YYViewController.m 3 // 0