侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

ISO:数据持久化4(sqlite3)

2023-12-01 星期五 / 0 评论 / 0 点赞 / 43 阅读 / 15274 字

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

 

广告 广告

评论区