第四十二篇:IOS 的 sqlite3 一些基本使用

一、sqlite3 使用操作

       前提:在項目中導入 libsqlite3.0.tdb 數據庫。

1.sqlite3 相關一些基本函數用法:

1.1、打開數據庫

SQLITE_API int sqlite3_open(
  constchar *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb         /* OUT: SQLite db handle */
);

該函數傳的兩個參數如下使用,例:

static sqlite3 * db ;
NSString * dataBaseFile = [dataBaseHandledataBaseFile];
int result = sqlite3_open([dataBaseFileUTF8String], &db);
if (result == SQLITE_OK) //說明已經打開數據庫;


1.2、當數據庫被打開後執行創建數據庫表:

SQLITE_API int sqlite3_exec(
  sqlite3*,                                 /* An open database */
  constchar *sql,                          /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**), /* Callback function */
  void *,                                   /* 1st argument to callback */
  char **errmsg                             /* Error msg written here */
);

// 創建數據庫表語句 , primary key autoincrement修飾主鍵在表中值是唯一存在(最後一個單詞自動增加)
// 條件:
// 1.表中必須要有一個主鍵;
// 2.在插入數據時主鍵自動增加使用 autoincrement修飾;
// 3.主鍵的值在表中是唯一的,如果插入的數據主鍵值一樣則不能添加在表內
NSString * sqliteStr = @"create table if not exists StudentList(stu_number integer primary key autoincrement,stu_name text,stu_gender text,stu_age integer)";
// 執行語句
sqlite3_exec(db, [sqliteStrUTF8String], NULL,NULL, NULL);


1.3、關閉數據庫

int result = sqlite3_close(db);
NSLog(@"%@",result ==SQLITE_OK ? @"關閉成功":@"關閉失敗");


1.4、插入數據相關幾個函數

1.4.1、驗證數據庫語句,nByte 傳 -1 時自動計算 zSql 數據庫語句長度

SQLITE_API int sqlite3_prepare_v2(
  sqlite3 *db,           /* Database handle */
  constchar *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,             /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt, /* OUT: Statement handle */
  constchar **pzTail     /* OUT: Pointer to unused portion of zSql */
);

1.4.2、數據庫管理指針 sqlite3_stmt 類型 

typedef structsqlite3_stmt  sqlite3_stmt;

1.4.3、綁定數據

// 第二個參數表示 數據庫語句中的第 k 個 "?" ,從 k>=1 。
SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,constchar*,int,void(*)(void*));
SQLITE_API int sqlite3_bind_int(sqlite3_stmt*,int, int);
SQLITE_API int sqlite3_bind_double(sqlite3_stmt*,int, double);
...............

如 sql 語句:

@"select * from StudentList where stu_number = ? and stu_name = ?"
// 綁定參數據如下:
// 幫定參數,在之前先省去了一些步驟,稍後看例子。
sqlite3_bind_int(stmt, 1, (int)number);
sqlite3_bind_text(stmt, 2, [@"李四"UTF8String], -1,NULL);

1.4.4、執行數據庫語句

SQLITE_API int sqlite3_step(sqlite3_stmt*);

1.4.5、釋放數據庫管理指針

SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);

插入數據示例:

// 插入數據
-(void)insertDataWithKeyValues:(StudentEntity *)entity
{
    // 1.打開數據庫
    [self openDataBase];
    
    // 2.插入語句
    NSString * sqlStr = @"insert into StudentList(stu_name,stu_gender,stu_age,stu_number)values(?,?,?,?)";

    // 3.創建數據管理指針
    sqlite3_stmt * stmt = nil ;
    
    // 4.驗證數據庫語句,
    int result = sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &stmt, NULL);
    
    if (result == SQLITE_OK) {
        NSLog(@"可以插入數據");
        // 5.幫定數據
        // 參數:數據庫管理指針 , 在 sqlStr 的第n個 ?, 數據庫語句 , 語句長度(-1表示自動計算長度) ,
        sqlite3_bind_text(stmt, 1, [entity.name UTF8String], -1, NULL);
        sqlite3_bind_text(stmt, 2, [entity.gender UTF8String], -1, NULL);
        sqlite3_bind_int(stmt, 3, (int)entity.age);
        sqlite3_bind_int(stmt, 4, (int)entity.number);

        // 6.讓 sql 語句執行
        sqlite3_step(stmt);
    }
    
    // 7.釋放
    sqlite3_finalize(stmt);
    
    // 8.關閉數據庫
    [self closeDataBase];
}

1.5、從數據庫中取出每條數據的每一列對應的數據

// iCol 表示每個字段所在的列位置,從 0 開始。
SQLITE_API double sqlite3_column_double(sqlite3_stmt*,int iCol);
SQLITE_API int sqlite3_column_int(sqlite3_stmt*,int iCol);
SQLITE_API constunsigned char *sqlite3_column_text(sqlite3_stmt*,int iCol);
..................


1.6、數據庫操作語句

       ListName 爲創建的表名,one 、two 和 three 都是表中每一列的字段。

// 創建數據庫表
@"create table if not exists ListName(one text primary key autoincrement , two text , three integer,......)";

// 插入數據
@"insert into ListName(one , two , three,....) values(? , ? , ? , ....) ";

// 查詢
@"select * from ListName" // 查詢表中所有數據
@"select * from ListName where one = ? " //帶有一個條件的查詢
@"select * from ListName where one = ? and two = ?" // 滿足一個條件的查詢
@"select * from ListName where one = ? or three = ?"  // 滿足其中任意一個條件的查詢
@"select * from ListName where three > ?" // 表中滿足 three > 當前綁定的值 的 數據
@"select one,three from ListName where two = ? order by three disc(或是 asce)" // 查詢表中滿足(two = 當前綁定的值)條件的 one 和 three 值,並以 three 大小降序排列返回
@"select * from ListName where three > ? limit 5" // 滿足條件的5條數據
@"select * from ListName where three > ? limit 3,5" // 跳過前三條數據 接着取後5條
@"select one,two from ListName where ...... "  //選出滿足條件數據條的  one 和 two 值

// 模糊查詢所有字段 two 包含 likeName 內容的數據都找出來
[NSString stringWithFormat:@"select * from ListName where two  like '%%%@%%'",likeName];

// 修改數據
@"update ListName set one = ? where three >= ?"

// 刪除數據
@"delete from ListName" // 刪除表中所有數據
@"delete from ListName where one = ?" // 刪除表中滿足條件的數據

// 刪除整張表
@"drop table ListName"


2. 把 c 的字符串轉換成 OC 中的 NSString 類型

[NSStringstringWithUTF8String:(char *)sqlite3_column_text(stmt,1)]


3.整個項目代碼

3.1數據模型文件代碼

//
//  StudentEntity.h
//  DataBaseDome
//
//  Created by 瞿傑 on 2017/6/19.
//  Copyright © 2017年 yiniu. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface StudentEntity : NSObject

@property(nonatomic,assign)NSInteger number;
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *gender;
@property(nonatomic,assign)NSInteger age;

@end
//
//  StudentEntity.m
//  DataBaseDome
//
//  Created by 瞿傑 on 2017/6/19.
//  Copyright © 2017年 yiniu. All rights reserved.
//

#import "StudentEntity.h"

@implementation StudentEntity

@end

3.2 數據庫操作文件

//
//  DataBaseHandle.h
//  DataBaseDome
//
//  Created by 瞿傑 on 2017/6/19.
//  Copyright © 2017年 yiniu. All rights reserved.
//

#import <Foundation/Foundation.h>


@class StudentEntity ;

@interface DataBaseHandle : NSObject

+(instancetype)dataBaseHandleWithDataBaseName:(NSString *)dataBaseName;

// 打開數據庫
-(void)openDataBase ;
// 關閉數據庫
-(void)closeDataBase ;

// 插入數據
-(void)insertDataWithKeyValues:(StudentEntity *)entity ;

// 更新
-(void)updateStudentGender:(NSString *)gender byNumber:(NSInteger)number ;

// 查詢
// 查詢所有數據
-(NSArray<StudentEntity *> *)selectAllKeyValues ;

// 根據條件查詢
-(StudentEntity *)selectOneStudentByNumber:(NSInteger)number ;

// 模糊查詢,只要包含 likeName 內容
-(StudentEntity *)selectOneStudentLikeName:(NSString *)likeName ;

// 刪除表中數據
-(void)deleteOneStudentByNumber:(NSInteger)number ;

// 刪除表
-(void)dropTable;


@end
//
//  DataBaseHandle.m
//  DataBaseDome
//
//  Created by 瞿傑 on 2017/6/19.
//  Copyright © 2017年 yiniu. All rights reserved.
//

#import "DataBaseHandle.h"

#import "StudentEntity.h"
#import <sqlite3.h>

@interface DataBaseHandle ()

@property (nonatomic , copy)NSString * dataBaseName ;

@end

@implementation DataBaseHandle

static sqlite3 * db ;

+(instancetype)dataBaseHandleWithDataBaseName:(NSString *)dataBaseName
{
    DataBaseHandle * dataBaseHandle = [[self alloc] init];
    dataBaseHandle.dataBaseName = dataBaseName ;
    
    NSString * dataBaseFile = [dataBaseHandle dataBaseFile];
    
    // 打開數據庫
    int result = sqlite3_open([dataBaseFile UTF8String], &db);
    
    if (result == SQLITE_OK) {
        // 創建數據庫表語句 , primary key autoincrement 修飾主鍵在表中值是唯一存在(最後一個單詞自動增加)
        // 條件:
        // 1.表中必須要有一個主鍵;
        // 2.在插入數據時主鍵自動增加使用 autoincrement 修飾;
        // 3.主鍵的值在表中是唯一的,如果插入的數據主鍵值一樣則不能添加在表內
        NSString * sqliteStr = @"create table if not exists StudentList(stu_number integer primary key autoincrement,stu_name text,stu_gender text,stu_age integer)";
        // 執行語句
        sqlite3_exec(db, [sqliteStr UTF8String], NULL, NULL, NULL);
    }
    
    return dataBaseHandle ;
}

// 數據庫文件存放所在的 Caches 文件夾路徑
-(NSString *)dataBasePath
{
    return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
}

// 數據庫文件路徑
-(NSString *)dataBaseFile
{
    return [[self dataBasePath] stringByAppendingPathComponent:[self.dataBaseName stringByAppendingString:@".db"]];
}

// 打開數據庫
-(void)openDataBase
{
    NSString * dataBaseFile = [self dataBaseFile];

    NSLog(@"%@",dataBaseFile);
    
    int result = sqlite3_open([dataBaseFile UTF8String], &db);
    
    if (result == SQLITE_OK) {
        NSLog(@"打開成功");
    }
    else{
        NSLog(@"打開失敗");
    }
}

// 關閉數據庫
-(void)closeDataBase
{
    int result = sqlite3_close(db);
    NSLog(@"%@",result == SQLITE_OK ? @"關閉成功":@"關閉失敗");
}

// 插入數據
-(void)insertDataWithKeyValues:(StudentEntity *)entity
{
    // 1.打開數據庫
    [self openDataBase];
    
    // 2.插入語句
    NSString * sqlStr = @"insert into StudentList(stu_name,stu_gender,stu_age,stu_number)values(?,?,?,?)";

    // 3.創建數據管理指針
    sqlite3_stmt * stmt = nil ;
    
    // 4.驗證數據庫語句,
    int result = sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &stmt, NULL);
    
    if (result == SQLITE_OK) {
        NSLog(@"可以插入數據");
        // 5.幫定數據
        // 參數:數據庫管理指針 , 在 sqlStr 的第n個 ?, 數據庫語句 , 語句長度(-1表示自動計算長度) ,
        sqlite3_bind_text(stmt, 1, [entity.name UTF8String], -1, NULL);
        sqlite3_bind_text(stmt, 2, [entity.gender UTF8String], -1, NULL);
        sqlite3_bind_int(stmt, 3, (int)entity.age);
        sqlite3_bind_int(stmt, 4, (int)entity.number);

        // 6.讓 sql 語句執行
        sqlite3_step(stmt);
    }
    
    // 7.釋放
    sqlite3_finalize(stmt);
    
    // 8.關閉數據庫
    [self closeDataBase];
}

// 更新數據
-(void)updateStudentGender:(NSString *)gender byNumber:(NSInteger)number
{
    [self openDataBase];
    
    sqlite3_stmt * stmt = nil ;
    
    NSString * sql = @"update StudentList set stu_gender = ? where stu_number = ?";
    
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    
    if (result == SQLITE_OK) { // 是否可以執行
        
        sqlite3_bind_text(stmt, 1, [gender UTF8String], -1, NULL);
        sqlite3_bind_int(stmt, 2, (int)number);
        
        sqlite3_step(stmt);
    }
    
    sqlite3_finalize(stmt);
    [self closeDataBase];
}

// 查詢所有數據
-(NSArray<StudentEntity *> *)selectAllKeyValues
{
    
    // 1.打開數據庫
    [self openDataBase];
    
    // 2.準備語句
    NSString * sql = @"select * from StudentList ";
    
    // 3.創建數據管理指針
    sqlite3_stmt * stmt = nil ;
    
    // 4.驗證語句是否正確
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    
    NSMutableArray * mArr = [[NSMutableArray alloc] initWithCapacity:0];

    if (result == SQLITE_OK) {
        
        // 5.獲取數據
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            StudentEntity * entity = [[StudentEntity alloc] init];
            [mArr addObject:entity];
            
            entity.number = sqlite3_column_int(stmt, 0);
            entity.name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 1)];
            entity.gender = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 2)];
            entity.age = sqlite3_column_int(stmt, 3);
        }
    }
    
    // 6.釋放 和 關閉數據庫
    sqlite3_finalize(stmt);
    [self closeDataBase];
    
    return mArr ;
}

// 查詢某一個滿足條件的數據
-(StudentEntity *)selectOneStudentByNumber:(NSInteger)number
{
    [self openDataBase];
    
    // 數據庫語句:* 表示每條數據的所有字段;? 表示需要幫定的值
    NSString * sql = @"select * from StudentList where stu_number = ?";
    // 多條件查詢如:@"select * from StudentList where stu_number = ? and stu_name = ?"
    // @"select * from StudentList where stu_number = ? or stu_name"
    // @"select * from StudentList where stu_number > ?"
    // @"select * from StudentList where stu_number > ? limit 5" 滿足條件的5條數據
    // @"select * from StudentList where stu_number > ? limit 3,5" 跳過前三條數據 接着取後5條
    // @"select * from StudentList where stu_number > ?  order by stu_age disc " 在數據庫中的數據滿足條件 stu_number > ?(幫定的值) 選出的個數,然後以 stu_age 列把數據降序排列
    // @"select stu_name,stu_age from StudentList where ...... " 選出滿足條件數據條的 stu_name 和 stu_age 值

    
    // 創建數據管理指針
    sqlite3_stmt * stmt = nil ;
    StudentEntity * entity = [[StudentEntity alloc] init];
    
    // 驗證語句是否正確
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    
    if (result == SQLITE_OK) {
        // 幫定參數
        sqlite3_bind_int(stmt, 1, (int)number);
        sqlite3_bind_text(stmt, 2, [@"李四" UTF8String], -1, NULL);
        
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            entity.number = sqlite3_column_int(stmt, 0);
            entity.name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 1)];
            entity.gender = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 2)];
            entity.age = sqlite3_column_int(stmt, 3);
        }
    }
    
    sqlite3_finalize(stmt);
    [self closeDataBase];
    
    return entity ;
}

// 模糊查詢
-(StudentEntity *)selectOneStudentLikeName:(NSString *)likeName
{
    [self openDataBase];
    
    sqlite3_stmt * stmt = nil ;
    StudentEntity * entit = [[StudentEntity alloc] init] ;
    
    NSString * sql = [NSString stringWithFormat:@"select * from StudentList where stu_name like '%%%@%%'",likeName];
    
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"可以模糊查詢");
        
//        sqlite3_bind_text(stmt, 1, [likeName UTF8String], -1, NULL);
        
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            entit.number = sqlite3_column_int(stmt, 0);
            entit.name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 1)];
            entit.gender = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 2)];
            entit.age = sqlite3_column_int(stmt, 3);
        }
    }
    
    sqlite3_finalize(stmt);
    [self closeDataBase];
    
    return entit ;
}

// 刪除表中的數據
-(void)deleteOneStudentByNumber:(NSInteger)number
{
    [self openDataBase];
    
    NSString * sql = @"delete from StudentList where stu_number = ?";
    
    sqlite3_stmt * stmt = nil ;
    
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    
    if (result == SQLITE_OK) {
        
        sqlite3_bind_int(stmt, 1, (int)number);
        
        // 執行語句
        sqlite3_step(stmt);
    }
    
    sqlite3_finalize(stmt);
    [self closeDataBase];
}

// 刪除整個表
-(void)dropTable
{
    [self openDataBase];
    
    NSString * sql = @"drop table StudentList";
    
    sqlite3_stmt * stmt = nil ;
    
    int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    
    if (result == SQLITE_OK) {
        NSLog(@"成功刪除當前表");
        sqlite3_step(stmt);
    }
    
    sqlite3_finalize(stmt);
    [self closeDataBase];
}


@end



3.3 使用數據庫操作的測試代碼

//
//  ViewController.h
//  DataBaseDome
//
//  Created by 瞿傑 on 2017/6/19.
//  Copyright © 2017年 yiniu. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end


//
//  ViewController.m
//  DataBaseDome
//
//  Created by 瞿傑 on 2017/6/19.
//  Copyright © 2017年 yiniu. All rights reserved.
//

#import "ViewController.h"

#import "DataBaseHandle.h"
#import "StudentEntity.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    
    DataBaseHandle * dataBaseHandle = [DataBaseHandle dataBaseHandleWithDataBaseName:@"StudentDB"];
    
    // 查詢所有緩存的數據
    NSArray * allStudents = [dataBaseHandle selectAllKeyValues];
    
    
    // 1.插入數據
    StudentEntity * entity = [[StudentEntity alloc] init];
    entity.number = 1000 ;
    entity.name = @"張三";
    entity.gender = @"男";
    entity.age = 20 ;
    
    StudentEntity * entity2 = [[StudentEntity alloc] init];
    entity2.number = 1001 ;
    entity2.name = @"李四";
    entity2.gender = @"女";
    entity2.age = 25 ;
    
    [dataBaseHandle insertDataWithKeyValues:entity];
    [dataBaseHandle insertDataWithKeyValues:entity2];

    // 2.查詢所有數據
    allStudents = [dataBaseHandle selectAllKeyValues];
    
    // 查詢單個數據
    StudentEntity * selectStudent = [dataBaseHandle selectOneStudentByNumber:1000];
    StudentEntity * selectStudent2 = [dataBaseHandle selectOneStudentByNumber:1001];
    
    
    
    // 3.更新數據
    [dataBaseHandle updateStudentGender:@"女" byNumber:1000];
    [dataBaseHandle updateStudentGender:@"男" byNumber:1001];
    
    // 查詢所有數據
    allStudents = [dataBaseHandle selectAllKeyValues];
    
    
    
    [dataBaseHandle deleteOneStudentByNumber:1001];
    
    // 查詢所有數據
    allStudents = [dataBaseHandle selectAllKeyValues];
    
    // 查詢單個數據
    selectStudent = [dataBaseHandle selectOneStudentByNumber:1000];
    selectStudent2 = [dataBaseHandle selectOneStudentByNumber:1001];
    
    // 刪除整張表
    [dataBaseHandle dropTable];
    
    // 查詢所有數據
    allStudents = [dataBaseHandle selectAllKeyValues];
}




- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end




4. 在 git 上的代碼倉庫DataBaseDome






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章