iOS疯狂详解之SQlite数据库增删改查

时间:2021-09-19 19:18:13
//
//  SqLiteManager.h
//  MySqlite
//
//  Created by long on 15/9/15.
//  Copyright (c) 2015年 WLong. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "LanOuStudent.h"
#import <sqlite3.h>
@interface SqLiteManager : NSObject


+ (SqLiteManager *)shareManager;


//  打开数据库
- (sqlite3 *)openDB;

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

//  创建表
- (void)createTable;

//  插入数据
- (void)insertWithStudent:(LanOuStudent *)student;

//  删除数据
- (void)deleteWithAge:(NSInteger)age;

//  更改数据  根据名字 更改学号
- (void)updateName:(NSString *)name byAge:(NSInteger)age;

//  查询学生  根据名字和学号
- (LanOuStudent *)queryStudentWithName:(NSString *)name age:(NSInteger)age;

//  查询全部学生
- (NSArray *)queryAllStudent;


@end

//
//  SqLiteManager.m
//  MySqlite
//
//  Created by long on 15/9/15.
//  Copyright (c) 2015年 WLong. All rights reserved.
//

#import "SqLiteManager.h"

@implementation SqLiteManager

+ (SqLiteManager *)shareManager
{
    static SqLiteManager *manager = nil;
    if (manager == nil) {
        manager = [[SqLiteManager alloc] init];
    }
    return manager;
}


//  定义一个静态区指针 连接数据库 让数据库再程序结束后自动释放
static sqlite3 *db = nil;

- (sqlite3 *)openDB
{
    //  说明已经打开数据库
    if (db != nil) {
        return db;
    }
    
    //  创建数据库
    //  先搞路径
    NSString *dbPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"Student.sqlite"];
    
    NSLog(@"%@",dbPath);
    
    //  如果没有Student.sqlite文件 会创建一个
    int result = sqlite3_open(dbPath.UTF8String, &db);
    
    if (result == SQLITE_OK) {
        NSLog(@"打开数据库成功");
    } else {
        NSLog(@"打开数据库失败");
    }
    
    return db;
}


- (void)closeDB
{
    int result = sqlite3_close(db);
    if (result == SQLITE_OK) {
        
        //  把指针 重置为空 方便下次打开
        db = nil;
        
        NSLog(@"关闭数据库成功");
        
    } else {
        NSLog(@"关闭数据库失败");
    }
}

//  创建表
- (void)createTable
{
    // 1.打开数据库
    db = [self openDB];
    
    //  2.写sql语句 根据model 创建表
    //  create table Student (Student 是表名)
    //  number integer primary key not NULL 主键值 如果不操作 自增
    NSString *sql = @"create table IF NOT EXISTS lanOuStudent(number integer primary key not NULL, name text not NULL, gender text not NULL, age integer not NULL)";
    
    //  3.执行sql语句 创建表

    /**
     *  第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。
        第2个参数constchar*sql是一条sql 语句,以\0结尾。
        第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
        第4个参数void*是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写
            法,以及这个参数的使用。
        第5个参数char** errmsg 是错误信息。
     *
     */
    
    int result = sqlite3_exec(db, sql.UTF8String, NULL, NULL, NULL);
    
    if (result == SQLITE_OK) {
        NSLog(@"创建表成功");
    } else {
        NSLog(@"创建表失败");
    }
    
    //  4.关闭数据库
    [self closeDB];
    

}

//  插入数据
- (void)insertWithStudent:(LanOuStudent *)student
{
    //  1.打开数据库
    db = [self openDB];
    //  2.写sql语句
    NSString *sql = [NSString stringWithFormat:@"insert into lanOuStudent(name ,gender ,age , number) values('%@' ,'%@' , '%ld' , '%ld')",student.name,student.gender,student.age,student.number];
    //  3.执行语句
    int result = sqlite3_exec(db, sql.UTF8String, NULL, NULL, NULL);
    if (result == SQLITE_OK) {
        NSLog(@"插入成功");
    } else {
        NSLog(@"插入失败");
    }
    //  4.关闭数据库
    [self closeDB];
}

//  删除数据
- (void)deleteWithAge:(NSInteger)age
{
    //  1.打开数据库
    db = [self openDB];
    //  2.写sql语句
    NSString *sql = [NSString stringWithFormat:@"delete from lanOuStudent where age > '%ld'",age];
    //  3.执行语句
    int result = sqlite3_exec(db, sql.UTF8String, NULL, NULL, NULL);
    if (result == SQLITE_OK) {
        NSLog(@"删除成功");
    } else {
        NSLog(@"删除失败");
    }

    //  4.关闭数据库
    [self closeDB];

}


//  更改数据  根据名字 更改学号
- (void)updateName:(NSString *)name byAge:(NSInteger)age
{
    //  1.打开数据库
    db = [self openDB];
    //  2.写sql语句  where 后面是根据什么
    NSString *sql = [NSString stringWithFormat:@"update lanOuStudent set age = '%ld' where name = '%@'",age,name];
    //  3.执行语句
    int result = sqlite3_exec(db, sql.UTF8String, NULL, NULL, NULL);
    
    if (result == SQLITE_OK) {
        NSLog(@"更改成功");
    } else {
        NSLog(@"更改失败");
    }
    
    //  4.关闭数据库
    [self closeDB];

}

//  查询学生  根据名字和学号
- (LanOuStudent *)queryStudentWithName:(NSString *)name age:(NSInteger)age
{
    //  1.打开数据库
    db = [self openDB];
    
    //  2.写sql语句  *表示 查询所有字段
    NSString *sql = [NSString stringWithFormat:@"select * from lanOuStudent where name = '%@' and age = '%ld'",name,age];
    
    //  3.创建跟随指针 保存sql语句
    sqlite3_stmt *stmt = nil;
    
    //  4.执行语句
    //  -1 指sql语句长度 可以无限长
    //  &stmt 跟随指针 地址
    //  第四个参数 截取sql语句未使用部分
    
    
    int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, NULL);
    
    //  5.判断语句是否正确
    if (result == SQLITE_OK) {
        NSLog(@"查询语句正确");
        
        //  6.进行查询值的绑定 也就是问号? 的绑定
        //  第二个参数 指第几个问号 从1开始
        sqlite3_bind_text(stmt, 1, name.UTF8String, -1, NULL);
        sqlite3_bind_int(stmt, 2, (int)age); //  注意转换类型
        
        //  7.进行查询
        //  如果 查询结果 返回 SQLITE_ROW 那么查询正确 执行循环
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            //  8.满足条件 读取数据
            //  第二个参数 指的是 表中的列数 从0开始
            char *name = (char *)sqlite3_column_text(stmt, 1);
            char *gender = (char *)sqlite3_column_text(stmt, 2);
            int age = sqlite3_column_int(stmt, 3);
            int number = sqlite3_column_int(stmt, 0);
            
            //  9.赋值学生对象 字符串需要转换格式
            LanOuStudent *student = [[LanOuStudent alloc] init];
            student.name = [NSString stringWithUTF8String:name];
            student.gender = [NSString stringWithUTF8String:gender];
            student.age = age;
            student.number = number;
            
            //  10.释放跟随指针
            sqlite3_finalize(stmt);
            
            return student;

        }
        
        
        
    } else {
        NSLog(@"查询语句错误");
    }

    //  查询语句错误 也要释放跟随指针
    sqlite3_finalize(stmt);
    
    //  11.关闭数据库
    [self closeDB];

    return nil;
}


//  查询全部学生
- (NSArray *)queryAllStudent
{
    //  1.打开数据库
    db = [self openDB];
    //  2.写sql语句
    NSString *sql = @"select * from lanOuStudent";
    //  3.创建跟随指针
    sqlite3_stmt *stmt = nil;
    //  4.执行语句
    int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, NULL);
    //  5.判断语句是否正确
    if (result == SQLITE_OK) {
        NSLog(@"查询语句正确");
        //  6.创建数组
        NSMutableArray *array = [NSMutableArray array];
        //  7.执行查询
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            
            //  8.满足条件 读取数据
            char *name = (char *)sqlite3_column_text(stmt, 1);
            char *gender = (char *)sqlite3_column_text(stmt, 2);
            int age = sqlite3_column_int(stmt, 3);
            int number = sqlite3_column_int(stmt, 0);
            
            //  9.赋值学生对象 字符串需要转换格式
            LanOuStudent *student = [[LanOuStudent alloc] init];
            student.name = [NSString stringWithUTF8String:name];
            student.gender = [NSString stringWithUTF8String:gender];
            student.age = age;
            student.number = number;
            
            //  10.装进数组
            [array addObject:student];
            
            //  11.释放学生对象
            [student release];
        }
        
        //  12.释放跟随指针
        sqlite3_finalize(stmt);
        
        return array;
        
        
    } else {
        NSLog(@"查询语句错误");
    }
    
    //  查询语句错误 也要释放跟随指针
    sqlite3_finalize(stmt);
    
    //  11.关闭数据库
    [self closeDB];

    return nil;
}


@end


<pre name="code" class="objc">//
//  LanOuStudent.h
//  MySqlite
//
//  Created by long on 15/9/15.
//  Copyright (c) 2015年 WLong. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface LanOuStudent : NSObject
@property (nonatomic,retain) NSString *name;
@property (nonatomic,retain) NSString *gender;
@property (nonatomic,assign) NSInteger age;
@property (nonatomic,assign) NSInteger number;
@end