静以修身,俭以养德html
原文连接git
SQLite
数据库,也能够是XML文件、甚至是内存; 比较流行的第三方框架FMDB是对SQLite操做的封装Realm:适用于iOS (一样适用于Swift&Objective-C)和Android的跨平台移动数据库,是NoSQL框架,官方定位是取代SQLite。具体可参考Realm(Java)那些事github
Realm很是的特点是数据变动通知,查询,存储性能比SQLite好,可是体积大、存入Realm的对象必须继承RealmObject,侵入性强,Realm中存储对象不允跨线程访问sql
非关系型数据库还有LevelDB、RocksDB数据库
说明:线程模式能够在编译时(经过源码编译SQLite库时)、启动时(使用SQLite的应用程序初始化时)或者运行时(建立数据库链接时)来指定。通常而言,运行时指定的模式将覆盖启动时的指定模式,启动时指定的模式将覆盖编译时指定的模式。可是,单线程模式一旦被指定,将没法被覆盖。默认的线程模式是串行模式。api
//0:单线程模式;
//1:串行模式;
//2:多线程模式
复制代码
//FMDB 中代码
+ (BOOL)isSQLiteThreadSafe {
// make sure to read the SQLite headers on this guy!
return SQLite3_threadsafe() != 0;
}
复制代码
假如在编译时没有指定单线程模式,就能够在应用程序初始化时使用SQLite3_config()函数修改线程模式。缓存
SQLite_CONFIG_SINGLETHREAD //单线程模式
SQLite_CONFIG_MULTITHREAD //多线程模式
SQLite_CONFIG_SERIALIZED //串行模式
复制代码
SQLite_OPEN_NOMUTEX //建立多线程模式的链接(没有指定单线程模式的状况下)
SQLite_OPEN_FULLMUTEX //建立串行模式的链接
复制代码
要保证数据库使用安全,通常能够采用以下几种模式安全
SQLite
采用单线程模型,用专门的线程(同时只能有一个任务执行访问) 进行访问SQLite
采用多线程模型,每一个线程都使用各自的数据库链接 (即 SQLite3 *
)SQLite
采用串行模型,全部线程都公用同一个数据库链接。 写操做的并发性并很差,当多线程进行访问时实际上仍旧须要互相等待,而读操做所须要的 SHARED
锁是能够共享的,因此为了保证最高的并发性,推荐bash
WAL
模式SQLite3_prepare
编译结果BEGIN
和 COMMIT
作显示事务,减小屡次的自动事务消耗//打开数据库链接 定义
SQLite_API int SQLite3_open(
const char *filename, /* Database filename (UTF-8) */
SQLite3 **ppDb /* OUT: SQLite db handle */
);
//使用数据库链接
//db是SQLite3对象,SQLite3 *db = nil;
SQLite3_open([sqlPath UTF8String], &db);
//打开
int SQLite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
SQLite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);
复制代码
参数1:数据库的路径(由于须要的是C语言的字符串,而不是NSString因此必须进行转换)微信
参数2:SQLite的数据库的操做句柄(指向指针的指针)
//执行sql语句 定义
SQLite_API int SQLite3_exec(
SQLite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
//使用
int result = SQLite3_exec(db, sql.UTF8String, nil, nil, nil);
if (result == SQLite_OK) {
//exec ok
} else {
//exec failed
}
复制代码
//将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针,它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句。
SQLite_API int SQLite3_prepare_v2(
SQLite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
SQLite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
//使用
result = SQLite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0);
if (result == SQLite_OK) {
//exec ok
} else {
//exec failed
}
复制代码
//关闭数据库 定义
SQLite_API int SQLite3_close(SQLite3*);
//使用
SQLite3_close(db);
复制代码
说明:具体API参考C-language Interface Specification for SQLite,FMDB中对SQLite3的操做作了很好的封装,具体可参考FMDB的FMDatabase文件
参考 SQLite线程模式探讨
FMDB是iOS平台的SQLite数据库框架,iOS项目中使用十分普遍。
说明:在FMDB中,SQLite运行在多线程模式,一个数据库链接在同一个时间只能在一个线程操做 ,应该是在编译时候肯定的,固然也能够在打开数据库链接时候,指定线程模式是 多线程或串行。
FMDatabase
经过一个 SQLite 数据库文件路径建立的,此路径能够是:
一个文件的系统路径。磁盘中能够不存在此文件,由于若是不存在会自动为你建立。
一个空的字符串 `@""`。会在临时位置建立一个空的数据库,当 `FMDatabase` 链接关闭时,该数据库会被删除。
NULL`。会在内存中建立一个数据库,当 `FMDatabase` 链接关闭时,该数据库会被销毁。
复制代码
FMDatabase
必须执行open,在这里才能正在建立并打开SQLite3对象。
FMDatabase *db = [FMDatabase databaseWithPath:dbpath];
[db open];
//...
//关闭
[db close];
复制代码
//数据库查询
FMResultSet *rs = [db executeQuery:@"select * from people"];
//利用next函数
while ([rs next]) {
NSLog(@"%@ %@",[rs stringForColumn:@"name"],[rs stringForColumn:@"age"]);
}
复制代码
FMResultSet
经过调用 -executeQuery...
方法之一执行 SELECT
语句返回数据库查询结果FMResultSet
对象,而后就能够遍历查询结果了。SQL 语句中除过 SELECT
语句均可以称之为更新操做。包括 CREATE
,UPDATE
,INSERT
,ALTER
,COMMIT
,BEGIN
,DETACH
,DROP
,END
,EXPLAIN
,VACUUM
,REPLACE
等。
执行更新语句后会返回一个 BOOL
值,返回 YES
表示执行更新语句成功,返回 NO
表示出现错误,能够经过调用 -lastErrorMessage
和 -lastErrorCode
方法获取更多错误信息。
//建立表
[db executeUpdate:@"CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER DEFAULT 1)"];
//插入操做
[db executeUpdate:@"INSERT INTO people(name,age) VALUES (?,?)", @"LiLei",[NSNumber numberWithInteger:28]]
复制代码
FMDatabaseQueue *databaseQueue = [FMDatabaseQueue databaseQueueWithPath:dbpath];
[databaseQueue inDatabase:^(FMDatabase *db) {
//
[db executeUpdate:@"CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER DEFAULT 1)"];
}];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[databaseQueue inDatabase:^(FMDatabase *db) {
BOOL isSuccess = [db executeUpdate:@"INSERT INTO people(name,age) VALUES (?,?)", @"LiLei",[NSNumber numberWithInteger:28]];
if (isSuccess) {
NSLog(@"插入成功1");
}
}];
});
dispatch_async(queue, ^{
[databaseQueue inDatabase:^(FMDatabase *db) {
BOOL isSuccess = [db executeUpdate:@"INSERT INTO people(name,age) VALUES (?,?)", @"LiLei",[NSNumber numberWithInteger:28]];
if (isSuccess) {
NSLog(@"插入成功2");
}
}];
});
复制代码
基于FMDB实现的ORM框架