SQLite3详解
SQLite是嵌入式的和轻量级的SQL数据库。SQLite是由C实现的。广泛用于包括浏览器(支持HTML5的大部分浏览器,IE除外)、iOS、Android以及一些便携需求的小型web应用系统。
1 使用原因:存储、检索信息
2 SQLite是MySQL精简版。但无需服务器就能进行。
3 两个限制:1)必须手动创建数据库 2)没有面向对象的接口。
4 如何手动创建数据库。
使用SQLite前的准备
使用SQLite是很多做iOS开发中第一次面对C的情况,包括我。因为SQLite是C写的,Objective-C可以直接使用C代码。在SQLite前,一般都会使用Cocoa Touch框架,都是基于Objective-C的。
首先,添加framework:libsqlite3.0.dylib
需要在对应文件的头文件中加入:
#import "sqlite3.h" |
并在Frameworks中加入所需的库,否则会报错:
Undefined symbols: "_sqlite3_open", referenced from: |
加入库的方法是:
或者点击 你的应用程序名,(最上面带图标的那个)中间视图会出现frameworks的图表,左下脚有一个加号,就是添加新的frameworks的地方了,在搜索里输入需要的......,添加进去就OK了!
选择sqlite库:
选择完的效果:
1 static NoteDAO *sharedManager = nil; 2 3 + (NoteDAO*)sharedManager 4 { 5 static dispatch_once_t once; 6 dispatch_once(&once, ^{ 7 8 sharedManager = [[self alloc] init]; 9 [sharedManager createEditableCopyOfDatabaseIfNeeded]; 10 11 12 }); 13 return sharedManager; 14 } 15 16 //打开数据库 17 - (void)createEditableCopyOfDatabaseIfNeeded { 18 19 NSString *writableDBPath = [self applicationDocumentsDirectoryFile]; 20 21 if (sqlite3_open([writableDBPath UTF8String], &db) != SQLITE_OK) { 22 sqlite3_close(db); 23 NSAssert(NO,@"数据库打开失败。"); 24 } else { 25 char *err; 26 NSString *createSQL = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS Note (cdate TEXT PRIMARY KEY, content TEXT);"]; 27 if (sqlite3_exec(db,[createSQL UTF8String],NULL,NULL,&err) != SQLITE_OK) { 28 sqlite3_close(db); 29 NSAssert1(NO, @"建表失败, %s", err); 30 } 31 sqlite3_close(db); 32 } 33 } 34 35 - (NSString *)applicationDocumentsDirectoryFile { 36 NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 37 NSString *path = [documentDirectory stringByAppendingPathComponent:DBFILE_NAME]; 38 39 return path; 40 } 41 42 43 //插入Note方法 44 -(int) create:(Note*)model 45 { 46 47 NSString *path = [self applicationDocumentsDirectoryFile]; 48 49 if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) { 50 sqlite3_close(db); 51 NSAssert(NO,@"数据库打开失败。"); 52 } else { 53 54 NSString *sqlStr = @"INSERT OR REPLACE INTO note (cdate, content) VALUES (?,?)"; 55 56 sqlite3_stmt *statement; 57 //预处理过程 58 if (sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) { 59 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 60 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 61 NSString *nsdate = [dateFormatter stringFromDate:model.date]; 62 63 //绑定参数开始 64 sqlite3_bind_text(statement, 1, [nsdate UTF8String], -1, NULL); 65 sqlite3_bind_text(statement, 2, [model.content UTF8String], -1, NULL); 66 67 //执行插入 68 if (sqlite3_step(statement) != SQLITE_DONE) { 69 NSAssert(NO, @"插入数据失败。"); 70 } 71 } 72 73 sqlite3_finalize(statement); 74 sqlite3_close(db); 75 } 76 77 return 0; 78 } 79 80 //删除Note方法 81 -(int) remove:(Note*)model 82 { 83 NSString *path = [self applicationDocumentsDirectoryFile]; 84 85 if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) { 86 sqlite3_close(db); 87 NSAssert(NO,@"数据库打开失败。"); 88 } else { 89 90 NSString *sqlStr = @"DELETE from note where cdate =?"; 91 92 sqlite3_stmt *statement; 93 //预处理过程 94 if (sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) { 95 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 96 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 97 NSString *nsdate = [dateFormatter stringFromDate:model.date]; 98 99 //绑定参数开始 100 sqlite3_bind_text(statement, 1, [nsdate UTF8String], -1, NULL); 101 //执行 102 if (sqlite3_step(statement) != SQLITE_DONE) { 103 NSAssert(NO, @"删除数据失败。"); 104 } 105 } 106 107 sqlite3_finalize(statement); 108 sqlite3_close(db); 109 } 110 111 return 0; 112 } 113 114 //修改Note方法 115 -(int) modify:(Note*)model 116 { 117 118 NSString *path = [self applicationDocumentsDirectoryFile]; 119 120 if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) { 121 sqlite3_close(db); 122 NSAssert(NO,@"数据库打开失败。"); 123 } else { 124 125 NSString *sqlStr = @"UPDATE note set content=? where cdate =?"; 126 127 sqlite3_stmt *statement; 128 //预处理过程 129 if (sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) { 130 131 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 132 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 133 NSString *nsdate = [dateFormatter stringFromDate:model.date]; 134 135 //绑定参数开始 136 sqlite3_bind_text(statement, 1, [model.content UTF8String], -1, NULL); 137 sqlite3_bind_text(statement, 2, [nsdate UTF8String], -1, NULL); 138 //执行 139 if (sqlite3_step(statement) != SQLITE_DONE) { 140 NSAssert(NO, @"修改数据失败。"); 141 } 142 } 143 144 sqlite3_finalize(statement); 145 sqlite3_close(db); 146 } 147 return 0; 148 } 149 150 //查询所有数据方法 151 -(NSMutableArray*) findAll 152 { 153 154 NSString *path = [self applicationDocumentsDirectoryFile]; 155 NSMutableArray *listData = [[NSMutableArray alloc] init]; 156 157 if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) { 158 sqlite3_close(db); 159 NSAssert(NO,@"数据库打开失败。"); 160 } else { 161 162 NSString *qsql = @"SELECT cdate,content FROM Note"; 163 164 sqlite3_stmt *statement; 165 //预处理过程 166 if (sqlite3_prepare_v2(db, [qsql UTF8String], -1, &statement, NULL) == SQLITE_OK) { 167 168 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 169 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 170 171 //执行 172 while (sqlite3_step(statement) == SQLITE_ROW) { 173 char *cdate = (char *) sqlite3_column_text(statement, 0); 174 NSString *nscdate = [[NSString alloc] initWithUTF8String: cdate]; 175 176 char *content = (char *) sqlite3_column_text(statement, 1); 177 NSString * nscontent = [[NSString alloc] initWithUTF8String: content]; 178 179 Note* note = [[Note alloc] init]; 180 note.date = [dateFormatter dateFromString:nscdate]; 181 note.content = nscontent; 182 183 [listData addObject:note]; 184 185 } 186 } 187 188 sqlite3_finalize(statement); 189 sqlite3_close(db); 190 191 } 192 return listData; 193 } 194 195 //按照主键查询数据方法 196 -(Note*) findById:(Note*)model 197 { 198 199 NSString *path = [self applicationDocumentsDirectoryFile]; 200 201 if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) { 202 sqlite3_close(db); 203 NSAssert(NO,@"数据库打开失败。"); 204 } else { 205 206 NSString *qsql = @"SELECT cdate,content FROM Note where cdate =?"; 207 208 sqlite3_stmt *statement; 209 //预处理过程 210 if (sqlite3_prepare_v2(db, [qsql UTF8String], -1, &statement, NULL) == SQLITE_OK) { 211 //准备参数 212 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 213 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 214 NSString *nsdate = [dateFormatter stringFromDate:model.date]; 215 //绑定参数开始 216 sqlite3_bind_text(statement, 1, [nsdate UTF8String], -1, NULL); 217 218 //执行 219 if (sqlite3_step(statement) == SQLITE_ROW) { 220 char *cdate = (char *) sqlite3_column_text(statement, 0); 221 NSString *nscdate = [[NSString alloc] initWithUTF8String: cdate]; 222 223 char *content = (char *) sqlite3_column_text(statement, 1); 224 NSString * nscontent = [[NSString alloc] initWithUTF8String: content]; 225 226 Note* note = [[Note alloc] init]; 227 note.date = [dateFormatter dateFromString:nscdate]; 228 note.content = nscontent; 229 230 sqlite3_finalize(statement); 231 sqlite3_close(db); 232 233 return note; 234 } 235 } 236 237 sqlite3_finalize(statement); 238 sqlite3_close(db); 239 240 } 241 return nil; 242 }
注:SQLite中也没有定义日期时间类型,日期时间可以用TEXT,REAL,orINTEGER存储
TEXT:存储为字符串("YYYY-MM-DDHH:MM:SS.SSS").
REAL:asJuliandaynumbers,thenumberofdayssincenooninGreenwichonNovember24,4714B.C.accordingtotheprolepticGregoriancalendar.
INTEGER:asUnixTime,thenumberofsecondssince1970-01-0100:00:00UTC.
SQLiteTypeAffinity(类型检测)
用于自动检测值的类型,以下列举Affinity如何决定类型的规则
(1)如果类型声明中有int,则使用INTEGERaffinity.
(2)如果类型声明中有"CHAR","CLOB",or"TEXT",则使用Textaffinity
(3)如果类型声明中有BLOB或没有指定类型,则使用affinityNONE
http://mobile.51cto.com/iphone-321872.htm
(4)如果类型声明中有"REAL","FLOA",or"DOUB",则使用REALaffinity
(5)否则使用Numericaffinity
类型比较NULL
memcmp函数原型
intmemcmp(constvoid*ptr1,constvoid*ptr2,size_tnum);
比较两个指针指向内存的前num个byte
比较之前的类型转换
l(INTEGER,REALorNUMERIC)和(TEXTorNONE)比较,则TEXT,NONE会被转换成NUMERIC
lTEXT和NONE比较,则NONE会被转换成TEXT
其他情况直接比较。
iOS SQLite3具有的数据类型
NULL:NULLvalue
Integer:值是signedinteger类型,大小可以是1,2,3,4,6,8bytes
REAL:浮点类型
TEXT:以UTF-8,UTF-16BEorUTF-16LE编码存储的字符类型
BLOB:二进制数据
其它数据类型说明