SQLite数据库

在学习SQLite之前,首先了解下数据持久化的几种方式:

定义:数据持久化是通过文件将数据存储在磁盘上

IOS下主要有四种数据持久化的方式:
1.属性列表Plist(通过将数组和字典写入一个文件进行存储,自定义的对象不能使用属性列表写入文件)
2.偏好设置Preference(NSUserDefaults,也是只能存数组和字典等简单数据)
2.对象归档(将自定义的对象写入文件)
3.SQLite数据库(纯C语言,轻量级)
4.CoreData(基于SQLite,OC版本,重量级)

持久化方式的对比:
1.属性列表,对象归档适合小数据量存储和查询操作(如果数据比较大,缺点:消耗内存,查询性能不好)
2.SQLite,CoreData适合大数据量存储和查询操作

数据库介绍
数据库(Database)是按照数据结构来组织,存储和管理数据的仓库
数据库管理系统是一种操纵和管理数据库的大型软件,用于建立,使用和维护数据库,常见的关系数据库管理系统有:
Oracl(甲骨文,一些大的企业级的软件都用Orcal开发数据)
MSSQLServer(微软的系统,用.Net开发的一个系统)
DB2(IBM开发的数据管理系统)
MySQL(一般是跟php组合使用,已被甲骨文收购)

数据库可以分为两大类:
1.关系型数据库(主流)
2.对象型数据库

SQLite介绍
SQLite是一种轻型的数据库,是一种关系型数据库管理系统,它的设计目的是嵌入式设备中使用(手机中)
SQLite占用资源很低,可能只需要哦几百K的内存就够了
SQLite的处理速度比Mysql,PostgreSQL这两款著名的数据库都快
SQLite占用资源非常低,非常适合移动设备中使用,而且是开源免费的
SQLite第一个版本诞生于2000年5月,现在已经更新到SQLite3版本
SQLite数据库是通过建表来存储数据的,表和表之间可以建立关系,所以叫关系型数据库

基础的SQL语句

SQL语句用于对数据进行存储,查询,更新等管理操作
1.创建表

CREATE TABLE Class99 (Stu_ID INTEGER PRIMARY KEY NOT NULL UNIQUE, name TEXT NOT NULL, gender TEXT NOT NULL DEFAULT M, age INTEGER NOT NULL)

2.插入一条数据

INSERT INTO Class99(Stu_ID,name,gender,age) VALUES(?,?,?,?)

3.更新一条数据

UPDATE Class99 SET gender = ? WHERE Stu_ID = ? 

4.删除一条数据

DELETE FROM Class99 WHERE Stu_ID = ?

5.查询一条数据

SELECT * FROM Class99 WHERE Stu_ID = ?

数据库操作流程

SQLite最新版本是3.0,使用前需要导入libsqlite3.0dylib
操作流程:
1.打开数据库
2.编译SQL语句
3.执行SQL语句,读取数据
4.语句完结
5.关闭数据库

SQL常用参数

1.sqlite3_open()     //打开数据库
2.sqlite3_close()     //关闭数据库
3.sqlite3_exec()     //执行sql语句,例如创建表
4.sqlite3_prepare_v2()    //编译SQL语句
5.sqlite3_step()    //执行sql语句
6.sqlite3_finaliza()    //结束sql语句
7.sqlite3_bind_text()   //绑定参数
8.sqlite3_column_text()    //查询字段上的数据

下面新建一个工程,使用以上SQLite的函数以及操作流程:

1.首先,给工程里面导入libsqlite3.tbd:

1.png

2.然后,使用storyboard,分别添加一下Button,关联到ViewController里面:


2.png

3. 新建一个类,声明这个类的属性,这个相当于建表


#import <Foundation/Foundation.h>

@interface Student : NSObject

@property(nonatomic,strong)NSString *name;

@property(nonatomic,strong)NSString *gender;

@property(nonatomic,assign)int age;

@property(nonatomic,assign)int Stu_ID;

-(instancetype)initWithName:(NSString *)name andAge:(int)age andGender:(NSString *)gender andStuID:(int)stu_ID;




@end
@implementation Student

-(void)setValue:(id)value forUndefinedKey:(NSString *)key{


}

-(NSString *)description{

    return [NSString stringWithFormat:@"%@",_name];
}

//自定义初始化方法
-(instancetype)initWithName:(NSString *)name andAge:(int)age andGender:(NSString *)gender andStuID:(int)stu_ID{
    
    if (self = [super init]) {
        
        _name = name;
        _age = age;
        _gender = gender;
        _Stu_ID = stu_ID;
        
        
    }
    
    return self;
}





@end

4.这里我们通过用单例来声明方法,然后在控制器里调用这些方法
这里结合SQLite的基础语句来声明这些方法:

#import <Foundation/Foundation.h>
@class Student;
@interface DataBase : NSObject

//创建单例
+(instancetype)shareDatabase;

//打开数据库
-(void)openDB;

//关闭数据库
-(void)closeDB;

//添加
-(void)insertStudent:(Student *)stu;

//删除
-(void)deleteStudent:(int)stu_ID;

//修改
-(void)updateStudentgender:(NSString *)gender andStuID:(int)stu_id;

//查询所有
-(NSArray *)selectAllStudents;

//查询单个
-(Student *)selectStudengWithID:(int)stu_id;



@end

****在.m里实现这些方法:***
首先在.m里导入数据库,并且创建单例:

#import "DataBase.h"
#import <sqlite3.h>
#import "Student.h"

@implementation DataBase
static DataBase *dataBase  = nil;

+(instancetype)shareDatabase{
    //加锁
    @synchronized(self) {
        
        if (nil == dataBase) {
            dataBase = [[DataBase alloc] init];
            //打开数据库
            [dataBase openDB];
        }
        
    }
   

    return dataBase;
}

//创建数据库对象
static sqlite3 *db = nil;

***打开数据库和关闭数据库:****

//打开数据库
-(void)openDB{
  
  //如果数据库已经打开,则不需要执行后面的操作
  if (db != nil) {
      return;
  }
  

  //创建保存数据库的路径
  NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  documentPath = [documentPath stringByAppendingString:@"/LOClass.sqlite"];
  
  NSLog(@"%@",documentPath);
  //打开数据库 (如果该数据库存在,则直接打开,否则自动创建一个再打开)
  int result = sqlite3_open([documentPath UTF8String], &db);
  if (result == SQLITE_OK) {
      NSLog(@"成功打开");
      //建表
      //准备sql语句
      NSString *sql = @"CREATE TABLE Class43 (Stu_ID INTEGER PRIMARY KEY NOT NULL UNIQUE, name TEXT NOT NULL, gender TEXT NOT NULL DEFAULT M, age INTEGER NOT NULL);";
      //执行sql语句
      sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
      
  }else{
      NSLog(@"%d",result);
  }
  
  

}

//关闭数据库
-(void)closeDB{
  int result = sqlite3_close(db);
  if (result == SQLITE_OK) {
      NSLog(@"关闭成功");
      //关闭数据库的时候,将db置为空,是因为打开数据库的时候,我们需要使用nil来判断
      db = nil;
      
      
  }else{
      
      NSLog(@"关闭失败:%d",result);
      
  }
 

}

实现添加

//添加
-(void)insertStudent:(Student *)stu{

    //1.打开数据库
    [self openDB];

    //2.创建跟随指针
    sqlite3_stmt *stmt = nil;
    //3.准备sqlite语句
     NSString *sql = @"INSERT  INTO CLASS43(Stu_ID,name,gender,age) VALUES(?,?,?,?)";
    //4.验证sql语句的正确性
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    
    //5.  执行
    if (result == SQLITE_OK) {
        
        NSLog(@"数据库添加成功");
        //一旦sql语句没有问题,就要开始绑定数据,替换?
        //(1)跟随指针  (2)问号的顺序(从1开始)  (3)要绑定的值
        sqlite3_bind_int(stmt, 1, stu.Stu_ID);
        sqlite3_bind_text(stmt, 2, [stu.name UTF8String], -1, nil);
        sqlite3_bind_text(stmt, 3, [stu.gender UTF8String], -1, nil);
        sqlite3_bind_int(stmt, 4, stu.age);
        
        //6单步执行q
        sqlite3_step(stmt);
        
        
        
        
    }else{
    
        NSLog(@"数据库添加失败:%d",result);
    }
    
    //7 释放跟随指针占用的内存
    sqlite3_finalize(stmt);
 
}

我们可以 通过打开数据库里的方法中的路径,去查询数据:
在finder中前往文件夹,会找到后缀.sqlite的文档,通过SQLiteManager(一种管理数据的工具)打开,可以看到代码中的数据成功添加了:

3.png

删除


//删除
-(void)deleteStudent:(int)stu_ID{

    //1.打开数据库
    [self openDB];
    
    //2.创建跟随指针
    sqlite3_stmt *stmt = nil;
    //3.准备sql语句
    NSString *sql = @"DELETE FROM Class43 WHERE Stu_ID=?";

    //4.验证sql正确性
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);

    //5.
    if (result == SQLITE_OK) {
        NSLog(@"删除成功");
        //开始绑定
        sqlite3_bind_int(stmt, 1, stu_ID);
        
        //执行
        sqlite3_step(stmt);
        
        
    }else{
    
    
        NSLog(@"删除失败%d",result);
    }

//7.释放内存
    sqlite3_finalize(stmt);


}

修改

//修改
-(void)updateStudentgender:(NSString *)gender andStuID:(int)stu_id{

    [self openDB];
    
    sqlite3_stmt *stmt = nil;
    
    NSString *sql = @"UPDATE Class43 SET gender = ? WHERE Stu_ID = ?";
    
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        NSLog(@"修改成功");
        
        //绑定  (绑定的是问号)  (1和2 代表问号)
        sqlite3_bind_text(stmt, 1, [gender UTF8String], -1, NULL);
        
        sqlite3_bind_int(stmt, 2, stu_id);
        
        sqlite3_step(stmt);
        
        
    }else{
        NSLog(@"修改失败");
    }
    

    sqlite3_finalize(stmt);
    
    
}

查找


-(NSArray *)selectAllStudents{
    
    //1.打开数据库
    [self openDB];
    //2.跟随指针
    sqlite3_stmt *stmt = nil;
    //3.
    NSString *sql = @"SELECT * FROM Class43";
    //4.验证
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        //创建可变数组,用来存放查询到的学生
        NSMutableArray *array = [NSMutableArray array];
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            //根据sql语句,将搜索到的符合条件的值取出来
            //0代表数据库表的第一列
            int stu_id = sqlite3_column_int(stmt, 0);
            NSString *name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];
            NSString *gender = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 2)];
            int age = sqlite3_column_int(stmt, 3);
            
            //将取出来的信息赋值给学生模型
            Student *stu = [[Student alloc] initWithName:name andAge:age andGender:gender andStuID:stu_id];
            
            //将学生添加到可变数组里面
            [array addObject:stu];
            
        }
        
        sqlite3_finalize(stmt);
        return array;
        
        
    }else{
        NSLog(@"查询失败:%d",result);
    }
    
    sqlite3_finalize(stmt);
    
    return nil;
}
-(Student *)selectStudengWithID:(int)stu_id{

    //1.
    [self openDB];
//2.
    sqlite3_stmt *stmt = nil;
//3.
NSString *sql = @"SELECT * FROM Class43 WHERE Stu_ID= ?";
    
  //4.
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    //5
    if (result == SQLITE_OK) {
        
        //绑定
        sqlite3_bind_int(stmt, 1, stu_id);
        //执行
        Student *stu = [Student new];
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            
            int stu_id = sqlite3_column_int(stmt, 0);
            NSString *name  = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(stmt, 1)];
            NSString *gender = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(stmt, 2)];
            int age = sqlite3_column_int(stmt, 3);
            
            stu.Stu_ID = stu_id;
            stu.name = name;
            stu.age = age;
            stu.gender = gender;
        }
        sqlite3_finalize(stmt);
        return stu;
        
    }else{
        NSLog(@"查询失败%d",result);
    }
    sqlite3_finalize(stmt);

    return nil;
}

5.在关联的控制器里调用这些方法


- (void)viewDidLoad {
    [super viewDidLoad];
    DataBase *db = [DataBase shareDatabase];
    
   // [db closeDB];
    
    
    
}

- (IBAction)inserBtn:(UIButton *)sender {
    NSLog(@"添加");
    Student *stu = [Student new];
    stu.Stu_ID = 1;
    stu.name = @"影魔";
    stu.gender = @"sf";
    stu.age = 100;
    
    Student *stu1 = [[Student alloc] initWithName:@"大队长" andAge:25 andGender:@"女" andStuID:2];
    Student *stu2 = [[Student alloc] initWithName:@"爱君" andAge:18 andGender:@"女" andStuID:3];
    Student *stu3 = [[Student alloc] initWithName:@"屠夫" andAge:99 andGender:@"男" andStuID:4];
    
    
    DataBase *db = [DataBase shareDatabase];
    [db insertStudent:stu];
    [db insertStudent:stu1];
    [db insertStudent:stu2];
    [db insertStudent:stu3];
  
}


- (IBAction)deleteBtn:(UIButton *)sender {
     NSLog(@"删除");
    
    DataBase *db = [DataBase shareDatabase];
    [db deleteStudent:4];
    
    
    
    
    
}

- (IBAction)searchBtn:(UIButton *)sender {
     NSLog(@"查询所有");
    
    DataBase *da = [DataBase shareDatabase];
  
    NSArray *array = [da selectAllStudents];
    NSLog(@"%@",array);
    
    
    
    
}


- (IBAction)oneSearchBtn:(UIButton *)sender {
     NSLog(@"查询单个");
    DataBase *db = [DataBase shareDatabase];
    Student *stu = [db selectStudengWithID:1];
    NSLog(@"%@",stu);
    
    
    
}



- (IBAction)changeBtn:(UIButton *)sender {
    NSLog(@"修改");
    
    DataBase *db = [DataBase shareDatabase];
    
    [db updateStudentgender:@"nv" andStuID:4];
    
}

由于资源占用少、性能良好和零管理成本,嵌入式数据库有了它的用武之地,像Android、iPhone都有内置的SQLite数据库供开发人员使用,它的易用性可以加快应用程序的开发,并使得复杂的数据存储变得轻松了许多。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容