ios中对sqlite3的使用小结

来源:互联网 发布:ubuntu 精简版 编辑:程序博客网 时间:2024/05/29 04:34

       首先需要在项目中添加libsqlite3.dylib

       sqlite3中字段虽然不区分数据类型的,但是它的数据类型还是分为了以下几种:integer,text,float,real,blob

为了开发的需要我们首先需要创建一个person类,用来对应即将创建的数据库中的person表。person类的.h和.m文件分别如下

person.h内容:

import <Foundation/Foundation.h>

@interface Person : NSObject

/**
 *  工厂方法
 *
 *  @param ID      ID
 *  @param name    姓名
 *  @param age     年龄
 *  @param phoneNo 电话
 *
 *  @return 个人信息对象
 */
+ (id)personWithID:(NSInteger)ID name:(NSString *)name age:(NSInteger)age phoneNo:(NSString *)phoneNo;

@property (assign, nonatomic) NSInteger ID;
@property (strong, nonatomic) NSString *name;
@property (assign, nonatomic) NSInteger age;
@property (strong, nonatomic) NSString *phoneNo;

@end

 

person.m的内容:

#import "Person.h"

@implementation Person

+ (id)personWithID:(NSInteger)ID name:(NSString *)name age:(NSInteger)age phoneNo:(NSString *)phoneNo
{
    Person *p = [[Person alloc] init];
   
    p.ID = ID;
    p.name = name;
    p.age = age;
    p.phoneNo = phoneNo;
   
    return p;
}

 

//重写description,方便输出查看

- (NSString *)description
{
    return [NSString stringWithFormat:@"<Person: %p, ID: %d, name: %@, age: %d, phoneNo: %@>", self, _ID, _name, _age, _phoneNo];
}

@end

 

同时,我们还用到了一个自定义的单例工具类----singleton.h


// .h
#define single_interface(class)  + (class *)shared##class;

// .m
// \ 代表下一行也属于宏
// ## 是分隔符
#define single_implementation(class) \
static class *_instance; \
 \
+ (class *)shared##class \
{ \
    if (_instance == nil) { \
        _instance = [[self alloc] init]; \
    } \
    return _instance; \
} \
 \
+ (id)allocWithZone:(NSZone *)zone \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
}

 

 

借鉴mvc的分层实现原理,这里我们将与数据库的连接,读取数据等操作全部放到类似java中service层的单例类:PersonManager

PersonManager.h文件内容如下

#import <Foundation/Foundation.h>
#import "Singleton.h"
#import "Person.h"

@interface PersonManager : NSObject

single_interface(PersonManager)

// 新增个人记录
- (void)addPerson:(Person *)person;

// 修改个人记录(修改传入Person对象ID对应的数据库记录的内容)
- (void)updatePerson:(Person *)person;

// 删除个人记录
- (void)removePerson:(NSInteger)personID;

// 查询所有用户信息列表
- (NSArray *)allPersons;

/**
 *  模糊查询所有姓名中包含name字符串的用户记录
 *
 *  @param name 姓名部分字符串
 *
 *  @return 查询结果集
 */
- (NSArray *)personsWithName:(NSString *)name;

@end

 

PersonManager.m的实现内容如下:

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

@interface PersonManager()
{
    // SQLite数据库的连接,基于该连接可以进行数据库操作
    sqlite3 *_db;
}

@end

@implementation PersonManager
single_implementation(PersonManager)

// 在初始化方法中完成数据库连接工作
- (id)init
{
    self = [super init];
   
    if (self) {
        // 1. 创建(连接)数据库
        [self openDB];
       
        // 2. 创建数据表
        [self createTable];
    }
   
    return self;
}

#pragma mark - 数据库操作方法
/**
 *  打开数据库
 */
- (void)openDB
{
    // 生成存放在沙盒中的数据库完整路径
    NSString *docDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *dbName = [docDir stringByAppendingPathComponent:@"my.db"];
   
    // 如果数据库不存在,则创建并打开一个数据库,否则直接打开
    if (SQLITE_OK == sqlite3_open(dbName.UTF8String, &_db)) {
        NSLog(@"创建/打开数据库成功。");
    } else {
        NSLog(@"创建/打开数据库失败。");
    }
}

/**
 *  指定单步sql指令
 *
 *  @param sql sql语句
 *  @param msg 提示信息
 */
- (void)execSql:(NSString *)sql msg:(NSString *)msg
{
    char *errmsg;
    // 所谓回调:sqlite3_exec执行完成sql之后调用的方法,叫做回调方法
    if (SQLITE_OK == sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg)) {
        NSLog(@"%@成功", msg);
    } else {
        NSLog(@"%@失败 - %s", msg, errmsg);
    }
}

/**
 *  创建数据表
 */
- (void)createTable
{
    NSString *sql = @"CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT,name text,age integer,phoneNo text)";
   
    [self execSql:sql msg:@"创建数据表"];
}

#pragma mark - 成员方法
// 新增个人记录
- (void)addPerson:(Person *)person
{
    NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_person (name, age, phoneNo) VALUES (
'%@', %d,'%@')", person.name, person.age, person.phoneNo];
   
    [self execSql:sql msg:@"添加个人记录"];
   
}

// 修改个人记录(修改传入Person对象ID对应的数据库记录的内容)
- (void)updatePerson:(Person *)person
{
   
}

// 删除个人记录
- (void)removePerson:(NSInteger)personID
{
   
}

/**
 *  返回指定sql查询语句运行的结果集
 *
 *  @param sql sql
 *
 *  @return 结果集
 */
- (NSArray *)queryPersonsWithSql:(NSString *)sql
{
    // 1. 评估准备SQL语法是否正确
    sqlite3_stmt *stmt = NULL;
   
    //    NSMutableArray *persons = [NSMutableArray array];
    NSMutableArray *persons = nil;
   
    if (SQLITE_OK == sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL)) {
        // 2. 如果能够正常查询,调用单步执行方法,依次取得查询结果
        // 如果得到一行记录
        persons = [NSMutableArray array];
       
        while (SQLITE_ROW == sqlite3_step(stmt)) {
            // 3. 获取/显示查询结果
            // sqlite3_column_xxx方法的第二个参数与sql语句中的字段顺寻一一对应(从0开始)
            int ID = sqlite3_column_int(stmt, 0);
            const unsigned char *name = sqlite3_column_text(stmt, 1);
            int age = sqlite3_column_int(stmt, 2);
            const unsigned char *phoneNo = sqlite3_column_text(stmt, 3);
           
            NSString *nameUTF8 = [NSString stringWithUTF8String:(const char *)name];//UTF8String转换成nsstring类型
            NSString *phoneNoUTF8 = [NSString stringWithUTF8String:(const char *)phoneNo];
           
            Person *p = [Person personWithID:ID name:nameUTF8 age:age phoneNo:phoneNoUTF8];
            [persons addObject:p];
        }
       
    } else {
        NSLog(@"SQL语法错误");
    }
   
    // 4. 释放句柄
    sqlite3_finalize(stmt);
   
    return persons;
}

// 查询所有用户信息列表
- (NSArray *)allPersons
{
    NSString *sql = @"SELECT id, name, age, phoneNo FROM t_person";
   
    return [self queryPersonsWithSql:sql];
}

- (NSArray *)personsWithName:(NSString *)name
{
    // 如果在NSString中包含%,可以使用%%表示
    NSString *sql = [NSString stringWithFormat:@"SELECT id, name, age, phoneNo FROM t_person WHERE name LIKE
'%%%@%%'", name];
   
    return [self queryPersonsWithSql:sql];
}

@end

 

在做了以上的种种处理之后,在controller中,我们要想查询数据表中所有的个人信息,只要做以下操作
 NSArray *_personList   = [[PersonManager sharedPersonManager] allPersons];

 

 

 

总结:sqlite3数据操作的基本步骤大概是有以下几步

1、创建数据库

首先先创建类之内的全局变量
    // SQLite数据库的连接,基于该连接可以进行数据库操作
    sqlite3 *_db;
然后打开数据库

   // 生成存放在沙盒中的数据库完整路径
    NSString *docDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *dbName = [docDir stringByAppendingPathComponent:@"my.db"];
   
    // 如果数据库不存在,则创建并打开一个数据库,否则直接打开
    if (SQLITE_OK == sqlite3_open(dbName.UTF8String, &_db)) {
        NSLog(@"创建/打开数据库成功。");
    } else {
        NSLog(@"创建/打开数据库失败。");
    }

2、创建数据库表

- (void)createTable
{
    NSString *sql = @"CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT,name text,age integer,phoneNo text)";

    char *errmsg;
    // 所谓回调:sqlite3_exec执行完成sql之后调用的方法,叫做回调方法
    if (SQLITE_OK == sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errmsg)) {
        NSLog(@"%@成功", msg);
    } else {
        NSLog(@"%@失败 - %s", msg, errmsg);
    }

 

3、查询结果集,返回一个NSMutableArray数组

   // 1. 评估准备SQL语句sql的语法是否正确
    sqlite3_stmt *stmt = NULL;
   
    //    NSMutableArray *persons = [NSMutableArray array];
    NSMutableArray *persons = nil;
   
    if (SQLITE_OK == sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL)) {
        // 2. 如果能够正常查询,调用单步执行方法,依次取得查询结果
        // 如果得到一行记录
        persons = [NSMutableArray array];
       
        while (SQLITE_ROW == sqlite3_step(stmt)) {
            // 3. 获取/显示查询结果
            // sqlite3_column_xxx方法的第二个参数与sql语句中的字段顺寻一一对应(从0开始)
            int ID = sqlite3_column_int(stmt, 0);
            const unsigned char *name = sqlite3_column_text(stmt, 1);
            int age = sqlite3_column_int(stmt, 2);
            const unsigned char *phoneNo = sqlite3_column_text(stmt, 3);
           
            NSString *nameUTF8 = [NSString stringWithUTF8String:(const char *)name];//UTF8String转换成nsstring类型
            NSString *phoneNoUTF8 = [NSString stringWithUTF8String:(const char *)phoneNo];
           
            Person *p = [Person personWithID:ID name:nameUTF8 age:age phoneNo:phoneNoUTF8];
            [persons addObject:p];
        }
       
    } else {
        NSLog(@"SQL语法错误");
    }

 

 

0 0