SQLite3

一、导入sqlite3库和头文件

在iOS中使用SQLite3,首先要添加库文件libsqlite3.dylib和导入主头文件

clipboard.pngclipboard.png

#import <sqlite3.h>

二、创建、打开、关闭数据库

1.创建或打开数据库

// 数据库放入沙盒中 
// ~/Library/Application Support/iPhone Simulator/
// path为:~/Documents/person.db
sqlite3 *db = NULL;
int result = sqlite3_open([path UTF8String], &db);

2.代码解析:

  • sqlite3_open()将根据文件路径打开数据库,如果不存在,则会创建一个新的数-据库。如果result等于常量SQLITE_OK,则表示成功打开数据库

  • sqlite3 *db:一个打开的数据库实例

  • 数据库文件的路径必须以C字符串(而非NSString)传入

3.关闭数据库:sqlite3_close(db);

三、执行不返回数据的SQL语句

执行创表语句

char *errorMsg = NULL;  // 用来存储错误信息

char *sql = "create table if not exists t_person(id integer primary key autoincrement, name text, age integer);";

int result = sqlite3_exec(db, sql, NULL, NULL, &errorMsg);

代码解析:

  • sqlite3_exec()可以执行任何SQL语句,比如创表、更新、插入和删除操作。但是一般不用它执行查询语句,因为它不会返回查询到的数据

  • sqlite3_exec()还可以执行的语句:

①开启事务:begin transaction;
②回滚事务:rollback;
③提交事务:commit;

四、带占位符插入数据

char *sql = "insert into t_person(name, age) values(?, ?);";

sqlite3_stmt *stmt;

if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) {

    sqlite3_bind_text(stmt, 1, "母鸡", -1, NULL);

    sqlite3_bind_int(stmt, 2, 27);

}

if (sqlite3_step(stmt) != SQLITE_DONE) {

    NSLog(@"插入数据错误");

}

sqlite3_finalize(stmt);

•代码解析:
usqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题
usqlite3_bind_text():大部分绑定函数都只有3个参数
①第1个参数是sqlite3_stmt *类型
②第2个参数指占位符的位置,第一个占位符的位置是1,不是0
③第3个参数指占位符要绑定的值
④第4个参数指在第3个参数中所传递数据的长度,对于C字符串,可以传递-1代替字符串的长度
⑤第5个参数是一个可选的函数回调,一般用于在语句执行后完成内存清理工作
usqlite_step():执行SQL语句,返回SQLITE_DONE代表成功执行完毕
usqlite_finalize():销毁sqlite3_stmt *对象

五、查询数据

char *sql = "select id,name,age from t_person;";

sqlite3_stmt *stmt;

if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) {

    while (sqlite3_step(stmt) == SQLITE_ROW) {

        int _id = sqlite3_column_int(stmt, 0);

        char *_name = (char *)sqlite3_column_text(stmt, 1);

        NSString *name = [NSString stringWithUTF8String:_name];

        int _age = sqlite3_column_int(stmt, 2);

        NSLog(@"id=%i, name=%@, age=%i", _id, name, _age);

    }

}

sqlite3_finalize(stmt);

•代码解析
usqlite3_step()返回SQLITE_ROW代表遍历到一条新记录
usqlite3_column_*()用于获取每个字段对应的值,第2个参数是字段的索引,从0开始

完整示例:
图片描述

//
//  IWViewController.m
//  sqlite编码学习
//
//  Created by kaiyi on 16-6-27.
//  Copyright (c) 2016年 kaiyi. All rights reserved.
//

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

@interface IWViewController ()
{
    sqlite3 *_db;   // db代表着整个数据库
}
- (IBAction)insert;
- (IBAction)update;
- (IBAction)delete;
- (IBAction)select;

@end

@implementation IWViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 0.获得沙盒中的数据库文件名
    NSString *filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"student.sqlite"];
    
    // 1.创建(打开)数据库,(如果数据库文件不存在,会自动创建)
    // 将OC类型转为C语言类型,filename.UTF8String
    int result = sqlite3_open(filename.UTF8String, &_db);
    if(result == SQLITE_OK)
    {
        NSLog(@"成功打开数据库");
        
        // 2.创表
        const char *sql = "create table if not exists student_tbl (id integer primary key autoincrement, name text, age integer)";
        
        char *errorMesg = NULL;
        int result = sqlite3_exec(_db, sql, NULL, NULL, &errorMesg);
        
        if(result == SQLITE_OK)
        {
            NSLog(@"创建表student_tbl成功");
            
        }
        else
        {
            NSLog(@"创建表student_tbl失败:%s", errorMesg);
        }
        
        
    }
    else
    {
        NSLog(@"打开数据库失败");
        
    }
}

- (IBAction)insert
{
    for(int i = 0; i< 30; i++)
    {
        // 名字、年龄随机
        NSString *name = [NSString stringWithFormat:@"jack-%d", arc4random()%100];
        int age = arc4random()%100;
        
        // 查询SQL为字符串拼接
        NSString *sql = [NSString stringWithFormat:@"insert into student_tbl (name, age) values('%@', %d);", name, age];
        char *errorMesg = NULL;
        int resutl = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errorMesg);
        if(resutl == SQLITE_OK)
        {
            NSLog(@"成功添加数据");
            
        }
        else
        {
            NSLog(@"添加数据失败:%s", errorMesg);
            
        }

        
    }
    
  }

- (IBAction)update {
}

- (IBAction)delete {
}

- (IBAction)select {
    
    // SQL 注入漏洞
    /**
     *   登陆
     *   1.用户输入账号和密码
     *   账号: 123' or 1 = 1' or '' =  ';
     *   密码: 123456
     *
     */
    // $sql = "select * from user_tbl where username=’username' and password='pwd'";
    // $sql = select * from user_tbl where username=’123' or 1 = 1' or '' =  '' and password='pwd';
    // 1.定义SQL语句(通过占位符,可以判断输入的内容合法)
    const char *sql = "select * from student_tbl where name = ?;";
    
    // 2.定义一个stmt存放结果集
    sqlite3_stmt *stmt = NULL;
    
    // 3.检测sql语法的合法性
    int result = sqlite3_prepare_v2(_db, sql, -1, &stmt, NULL);
    if(result == SQLITE_OK)
    {
         NSLog(@"查询语句合法");
        
        // 设置占位符的内容
        sqlite3_bind_text(stmt, 1, "jack", -1, NULL);
        
        // 4.执行SQL语句
        // int stepResult = sqlite3_step(stmt);
       
        while (sqlite3_step(stmt) == SQLITE_ROW){  // 真的查询到一行数据
            // 获得这行对应的数据
            
            // 获得第0列的ID
            int sid = sqlite3_column_int(stmt, 0);
            
            // 获得第一列的name
            const unsigned char *sname = sqlite3_column_text(stmt, 1);
            
            // 获得第二列的age
            int sage = sqlite3_column_int(stmt, 2);
            
            NSLog(@"%d %s %d", sid, sname, sage);
        }
        
    }
    else
    {
      NSLog(@"查询语句非法");
    }
    
}

@end


Corwien
6.3k 声望1.6k 粉丝

为者常成,行者常至。