SQLite3 1、简介 SQLite使用C语言编写,可移植性性强,可靠性高,小而易用,运行时同使用它的应用程序公用相同的进程空间,并不会出现在两个不同的进程里; SQLite提供了SQL-92标准的
SQLite3
1、简介
SQLite使用C语言编写,可移植性性强,可靠性高,小而易用,运行时同使用它的应用程序公用相同的进程空间,并不会出现在两个不同的进程里;
SQLite提供了SQL-92标准的支持,支持多表、索引、事务、视图和触发。
SQLite是无数据类型的数据库,虽然是无数据类型的数据库,但是代码编写必须按照一定的规范,SQLite支持的常见数据类型如下,
- INTEGER : 有符号整数类型
- REAL : 实数(浮点数)
- TEXT : 文本字符串,采用UTF-8和UTF-16字符编码
- BLOB : 二进制大对象类型,能够存放任何二进制的数据,比如文件,图片之类的
SQLite中没有boolean型,可以采用0和1代替;
SQLite中没有日期和时间类型,他们存储在INTEGER、REAL、TEXT类型中
- 可以将VARCHAR、CHAR、CLOB转换为TEXT类型
- 可以将FLOAT、DOUBLE转换为REAL类型
- 可以将NUMERIC转换为INTEGER或者REAL类型
2、使用
2.1 添加SQLite数据库
(1)工程中添加sql
首先要在工程中添加SQLite3库,TARGETS-->Build Phases--> Link Binary With Libraries(0 items),如下图
点击下面的+号,弹出下面对话框,选择libsqlite3.0tbd或者libsqlite3.tbd,单后点击add按钮
(2)创建数据库、使用数据库
代码如下:
//#################################DBHelper.h##################################import <Foundation/Foundation.h>@interface DBHelper:NSObject-(void) dropDB;-(void) createDB;-(void) insertData;-(void) queryData;-(void) closeDB;@end//#################################DBHelper.m##################################import <Foundation/Foundation.h>#import "sqlite3.h"#import "DBHelper.h"#import "Student.h"@interface DBHelper() { //声明一个扩展 sqlite3 *db;}@end@implementation DBHelper- (sqlite3 *)openDB { NSLog(@"##########sqlite openDB##########"); //db不为空,说明已经打开数据库 if (db != nil) { return db; } //1.设置文件名 NSString *filename = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"students.db"]; NSLog(@"%@",filename); // 2、如果没有students.db文件 就会创建一个 int result = sqlite3_open(filename.UTF8String, &db); if (result == SQLITE_OK) { NSLog(@"打开数据库成功"); } else { NSLog(@"打开数据库失败"); } return db;}-(void) dropDB{ NSLog(@"##########sqlite dropDB##########"); db = [self openDB]; if (db != nil) { char *errmsg = NULL; sqlite3_exec(db, "DROP TABLE IF EXISTS t_student;", NULL, NULL, &errmsg); if (errmsg) { NSLog(@"drop table error!%s", errmsg); } else { NSLog(@"drop table success!"); } } else { NSLog(@"open db failed!"); }}-(void) createDB{ //1、打开数据库 db = [self openDB]; if (db != nil) { NSLog(@"##########sqlite createDB##########"); //2、创建一个数据库表 const char *sql = "CREATE TABLE IF NOT EXISTS t_student (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, height INTEGER);"; char *errmsg = NULL; //sqlite3_exec(db, "DROP TABLE IF EXISTS t_student)", NULL, NULL, &errmsg); sqlite3_exec(db, sql, NULL, NULL, &errmsg); if (errmsg) { NSLog(@"create table error!%s", errmsg); } else { NSLog(@"create table success!"); } } else { NSLog(@"open db failed!"); }}- (void)insertData { db = [self openDB]; NSLog(@"##########sqlite insertData##########"); NSString *name;//姓名 int age;//年龄 int height;//身高 for (NSInteger i = 0; i < 10; i++) { name = [NSString stringWithFormat:@"name-%d", arc4random_uniform(10000)]; age = arc4random_uniform(18) + 2; height = arc4random_uniform(160) + 30; NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student (name, age, height) VALUES ('%@', %d, %d)", name, age, height];//这里特别要注意,VALUES ('%@', %d, %d)中的'%@',不能是%@,这里是text类型 NSLog(sql); char *errmsg = NULL; sqlite3_exec(db, sql.UTF8String, NULL, NULL, &errmsg); if (errmsg) { NSLog(@"error:%s", errmsg); } } NSLog(@"insert over!"); [self closeDB];}- (void)queryData { [self openDB]; NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:1000]; char *sql = "select name, age, height from t_student;"; sqlite3_stmt *stmt; NSInteger result = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); if (result == SQLITE_OK) { while (sqlite3_step(stmt) == SQLITE_ROW) { char *name = (char *)sqlite3_column_text(stmt, 0); int age = sqlite3_column_int(stmt, 1); int height = sqlite3_column_int(stmt, 2); //创建对象 Student *student = [[Student alloc] init]; student.name = [NSString stringWithFormat:@"%s", name]; student.age = age; student.height = height; [mArray addObject:student]; }// self.dataList = mArray; for(Student *s in mArray) { NSLog(@"{%@, %ld, %ld}", s.name, s.age, s.height); } } else { NSLog(@"open error %dl", result); } sqlite3_finalize(stmt); [self closeDB];}-(void) closeDB{ NSLog(@"##########sqlite closeDB##########"); int result = sqlite3_close(db); if (result == SQLITE_OK) { // 把指针 重置为空 方便下次打开 db = nil; NSLog(@"关闭数据库成功"); } else { NSLog(@"关闭数据库失败"); }}@end//#################################使用##################################import "ViewController.h"#import "AFNetworking.h"#import "sqlite3.h"#import "Student.h"#import "DBHelper.h"@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //创建数据库 UIButton *createView = [UIButton buttonWithType:UIButtonTypeCustom]; createView.frame = CGRectMake(0, 30, [UIScreen mainScreen].bounds.size.width, 45); [createView setTitle:@"创建数据库" forState:UIControlStateNormal]; [createView addTarget:self action:@selector(createClick:) forControlEvents:UIControlEventTouchUpInside]; [createView setTitleColor:(UIColor.whiteColor) forState:UIControlStateNormal]; [createView setBackgroundColor:UIColor.brownColor]; createView.translatesAutoresizingMaskIntoConstraints = YES; [self.view addSubview:createView]; //插入数据 UIButton *insertView = [UIButton buttonWithType:UIButtonTypeCustom]; insertView.frame = CGRectMake(0, 90, [UIScreen mainScreen].bounds.size.width, 45); [insertView setTitle:@"插入数据" forState:UIControlStateNormal]; [insertView addTarget:self action:@selector(insertClick:) forControlEvents:UIControlEventTouchUpInside]; [insertView setTitleColor:(UIColor.whiteColor) forState:UIControlStateNormal]; [insertView setBackgroundColor:UIColor.brownColor]; insertView.translatesAutoresizingMaskIntoConstraints = YES; [self.view addSubview:insertView]; //查询数据 UIButton *queryView = [UIButton buttonWithType:UIButtonTypeCustom]; queryView.frame = CGRectMake(0, 150, [UIScreen mainScreen].bounds.size.width, 45); [queryView setTitle:@"查询数据" forState:UIControlStateNormal]; [queryView addTarget:self action:@selector(queryClick:) forControlEvents:UIControlEventTouchUpInside]; [queryView setTitleColor:(UIColor.whiteColor) forState:UIControlStateNormal]; [queryView setBackgroundColor:UIColor.brownColor]; queryView.translatesAutoresizingMaskIntoConstraints = YES; [self.view addSubview:queryView]; //删除数据表 UIButton *dropView = [UIButton buttonWithType:UIButtonTypeCustom]; dropView.frame = CGRectMake(0, 210, [UIScreen mainScreen].bounds.size.width, 45); [dropView setTitle:@"删除数据表" forState:UIControlStateNormal]; [dropView addTarget:self action:@selector(dropClick:) forControlEvents:UIControlEventTouchUpInside]; [dropView setTitleColor:(UIColor.whiteColor) forState:UIControlStateNormal]; [dropView setBackgroundColor:UIColor.brownColor]; dropView.translatesAutoresizingMaskIntoConstraints = YES; [self.view addSubview:dropView];}-(void)createClick:(UIButton *)btn { DBHelper *dbHelper = [[DBHelper alloc]init]; [dbHelper createDB];}-(void)insertClick:(UIButton *)btn { DBHelper *dbHelper = [[DBHelper alloc]init]; [dbHelper insertData];}-(void)queryClick:(UIButton *)btn { DBHelper *dbHelper = [[DBHelper alloc]init]; [dbHelper queryData];}-(void)dropClick:(UIButton *)btn { DBHelper *dbHelper = [[DBHelper alloc]init]; [dbHelper dropDB];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
上面代码创建一个students.db的数据库,并且打开了它,创建了一张t_student的表,然后可操作删除表、创建数据库、插入数据、查询数据、关闭数据库
- -(void) dropDB;
- -(void) createDB;
- -(void) insertData;
- -(void) queryData;
- -(void) closeDB;
3、第三方SQLite封装框架FMDB
3.1 什么是FMDB
iOS使用C语言函数对原生SQLite数据库进行增删改查等操作比较复杂和麻烦,因此就出现了一系列针对原生SQLite API进行封装的库,FMDB便是其中之一。
FMDB是针对libsqlite3框架进行封装的三方库,其以OC的方式封装了SQLite的C语言的API,使用步骤与SQLite相似
3.2 FMDB的优点:
(1) 使用时面向对象,避免了复杂的C语言代码
(2) 对比Core Data框架,更加轻量级和灵活
(3) 提供多线程安全操作数据库的方法,保证多线程安全跟数据准确性
3.3 FMDB缺点
(1) 因为是OC语言开发,只能在iOS平台上使用,所以实现跨平台操作时存在限制性
FMDB 在Git上的下载链接地址:https://github.com/ccgus/fmdb
3.4 主要类
FMDatabase:一个FMDatabase对象代表一个单独的SQLite数据库,通过SQLite语句执行数据库的增删改查操作
FMResultSet:使用FMDatabase对象查询数据库后的结果集
FMDatabaseQueue:用于多线程操作数据库,它保证线程安全
3.5 FMDB使用方式
(1) 使用pod管理依赖(cocoapods安装参考:https://blog.devtang.com/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/)
(2) 在Podfile文件中添加:pod 'FMDB', '~> 2.7'
(3)cd 到项目根目录:命令行运行pod install将依赖库装载进来
(4) 导入libsqlite3.0框架,导入头文件 #import <FMDatabase.h>
(5) 指定数据库路径,创建数据库,操作前开启数据库,构建操作SQLite语句,数据库执行增删改查操作,操作完关闭数据库
3.6.FMDB基本使用示例:
#import "ViewController.h"#import "sqlite3.h"#import <FMDatabase.h>@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //删除数据表 UIButton *fmdbView = [UIButton buttonWithType:UIButtonTypeCustom]; fmdbView.frame = CGRectMake(0, 270, [UIScreen mainScreen].bounds.size.width, 45); [fmdbView setTitle:@"测试FMDB" forState:UIControlStateNormal]; [fmdbView addTarget:self action:@selector(fmdbClick:) forControlEvents:UIControlEventTouchUpInside]; [fmdbView setTitleColor:(UIColor.whiteColor) forState:UIControlStateNormal]; [fmdbView setBackgroundColor:UIColor.brownColor]; fmdbView.translatesAutoresizingMaskIntoConstraints = YES; [self.view addSubview:fmdbView]; }-(void)fmdbClick:(UIButton *)btn { [self testFMD];}-(void) testFMD{ NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *dbPath = [documentPath stringByAppendingPathComponent:@"users.db"]; NSLog(@"dbPath %@!", dbPath); FMDatabase *db = [[FMDatabase alloc]initWithPath:dbPath]; if (![db open]) { NSLog(@"open error!"); return; } else { NSLog(@"open ok!"); } BOOL result = [db executeUpdate:@"create table if not exists text1 (name text,age,integer,ID integer)"]; if (result) { NSLog(@"create table success"); } //1.开启事务 [db beginTransaction]; NSDate *begin = [NSDate date]; BOOL rollBack = NO; @try { //2.在事务中执行任务 for (int i = 0; i< 10000; i++) { NSString *name = [NSString stringWithFormat:@"user_%d",i]; NSInteger age = i; NSInteger ID = i *10000; BOOL result = [db executeUpdate:@"insert into text1(name,age,ID) values(:name,:age,:ID)" withParameterDictionary:@{@"name":name,@"age":[NSNumber numberWithInteger:age],@"ID":@(ID)}]; if (result) { NSLog(@"在事务中insert success"); } } } @catch(NSException *exception) { //3.在事务中执行任务失败,退回开启事务之前的状态 rollBack = YES; [db rollback]; } @finally { //4. 在事务中执行任务成功之后 rollBack = NO; [db commit]; } NSDate *end = [NSDate date]; NSTimeInterval time = [end timeIntervalSinceDate:begin]; NSLog(@"在事务中执行插入任务 所需要的时间 = %f",time); }@end
存储路径:沙箱目录/Documents/users.db
通过cd到该目录下可以看到该文件,可以使用第三方sqlite工具,查看user.db这张表的数据
数据库操作10000条数据,进行对比测试,
不用事务:所需要的时间 = 26.322180
使用事务:所需要的时间 = 4.538053