iOS开发之数据库Sqlite

来源:互联网 发布:js删除数组中的空元素 编辑:程序博客网 时间:2024/06/05 12:32

先创建一个工程,导入libsqlite3.dylib库。

因为在对数据进行操作的时候,需要打开数据库和关闭数据库,所以单独抽离出一个类DataBase要用于打开和关闭数据库。

#import <Foundation/Foundation.h>

#import <sqlite3.h>

// 因为在对数据进行操作的时候,需要打开数据库和关闭数据库,所以单独抽离出一个类要用于打开和关闭数据库。

@interface DataBase : NSObject

//打开数据库

+(sqlite3 *)openDB;

//关闭数据库

+(void)closeDB;

@end

**************************************************************************

#import "DataBase.h"


@implementation DataBase

static sqlite3* db =nil;


+(sqlite3 *)openDB

{

    /**

     *  问题:

               1. 现在数据库文件在应用程序包[NSBundle mainBundle]里面,二我们无法对应用程序包进行修改,所以数据库文件没办法实现增删改。

     解决方法:虽然应用程序的包无法修改,当安装到手机上时,苹果会自动生成一个沙盒。沙盒是可以对数据库进行修改的,所有可以将数据库文件拷贝到沙盒中,然后对其进行修改。

     2、 如果每次都从应用程序里面拷贝一份到沙盒里面,会产生一个问题,那就是打开数据库永远都是最初的数据库。

     解决方法:不是每次都进行拷贝,而是先进行判断,如果沙盒里已经存在,直接打开数据库,如果不存在,进行拷贝。

     */

//    获取document的路径,判断是否存在数据库文件

    if (db) {

        returndb;

    }

    

    NSString * docPath = [NSSearchPathForDirectoriesInDomains(9,1,1) lastObject];

    NSString * filePath = [docPathstringByAppendingPathComponent:@"MySql.sqlite"];

    NSLog(@"%@",docPath);

    NSFileManager * fileManager = [NSFileManagerdefaultManager];

    if ([fileManagerfileExistsAtPath:filePath]== NO ) {

        NSString * bundlePath = [[NSBundlemainBundle]pathForResource:@"MySql"ofType:@"sqlite"];

        NSLog(@"%@",bundlePath);

        [fileManager copyItemAtPath:bundlePathtoPath:filePath error:nil];

    }

    sqlite3_open([filePathUTF8String], &db);

    returndb;

    

}

+(void)closeDB

{

    sqlite3_close(db);

}

再创建一个学生类作为数据库的增加,删除,查询,修改的对象

#import <Foundation/Foundation.h>


@interface Student : NSObject

@property (nonatomic ,retain)NSString * name;

@property (nonatomic ,assign)int number;

@property (nonatomic,retain )NSString  * sex;

-(instancetype)initWithNumber :(int) number name:(NSString *)name sex:(NSString *)sex;


@end

***********************

#import "Student.h"


@implementation Student

-(instancetype)initWithNumber :(int) number name:(NSString *)name sex:(NSString *)sex

{

    self = [superinit];

    if (self) {

        self.name = name;

        self.number = number;

        self.sex = sex;

    }

    returnself;

}

@end

接下来就是对数据库的操作,一般而言可以创建一个单例用于这些操作

#import <Foundation/Foundation.h>

#import "Student.h"

@interface StudentHandle :NSObject

//所有对于学生表的增删修改查找都放在该类里面。

+(StudentHandle *)standarHandle;

//查询;

//查询所有学生的信息:

-(NSArray *)allStudents;

//查询某条学生的信息:根据学号来查询

-(Student * )studentByNumber:(int)number;

// 增加;

-(BOOL)insertStudentWith:(NSString *)name  sex:(NSString *)sex;

//删除

-(void)deleteStudentByNumber :(int)number;

//修改

-(void)updateStudentWithname:(NSString *)name number:(int) number;

@end

****************************

#import "StudentHandle.h"

#import "DataBase.h"


@implementation StudentHandle

static StudentHandle * standarHandle =nil;

+(StudentHandle *)standarHandle

@synchronized(self)

    {

    if (standarHandle ==nil )

    {

        standarHandle = [[StudentHandlealloc]init];

    }

    returnstandarHandle;


    }

}


-(NSArray *)allStudents

{

//1. 打开数据库;

    sqlite3 * db = [DataBaseopenDB];

// 2.   准备SQL语句stateMent

    sqlite3_stmt * stmt =nil ;

    int result  =  sqlite3_prepare_v2(db, "select * from StuentInfo", -1, &stmt,nil);

    NSMutableArray * arr =nil;


    if (result ==SQLITE_OK) {

//3.执行stmt

         arr = [NSMutableArrayarrayWithCapacity:0];

        while (sqlite3_step(stmt) ==SQLITE_ROW) {

// 4. 获取数据

            int number =sqlite3_column_int(stmt, 0);

            constunsigned char * nameUTF =sqlite3_column_text(stmt, 1);

            constunsigned char * sexUTF =sqlite3_column_text(stmt, 2);

            NSString * name = [NSStringstringWithUTF8String:(  const char *)nameUTF];

            NSString * sex = [NSStringstringWithUTF8String:(constchar *)sexUTF];

            Student * stu= [[Studentalloc]initWithNumber:numbername:name sex:sex];

            [arr addObject:stu];

            }

        }

//  5.释放statement所占用的内存

    sqlite3_finalize(stmt);


     return arr;

}

-(Student * )studentByNumber:(int)number

{//1.打开数据库

    sqlite3 * db = [DataBaseopenDB];

//  2.  准备SQL语句

    sqlite3_stmt * stmt =nil ;

    /**

     *     sqlite3_prepare_v2(<#sqlite3 *db#>, <#const char *zSql#>, <#int nByte#>, <#sqlite3_stmt **ppStmt#>, <#const char **pzTail#>)


     *

     *  @param db#>     <#db#>   数据库指针 description#>

     *  @param zSql#>   <#zSql#>  SQL指针  description#>

     *  @param nByte#>  <#nByte#> 执行SQL语句的长度,如果想执行所有的SQL语句可以给值为-1; description#>

     *  @param ppStmt#> <#ppStmt#>    语句对象 description#>

     *  @param pzTail#> <#pzTail#>  没有执行的SQL语句,一般情况下给nil; description#>

     *

     *  @return <#return value description#>

     */

    

    

    int result =sqlite3_prepare_v2(db, "select name,number,sex from StuentInfo where number = ? ", -1, &stmt,nil);

    

    Student * stu =nil;

    if (result ==SQLITE_OK) {

//       3. 绑定number对应的value值

        /**

         *  sqlite_bind_int  ()函数参数的含义如下:

         1.语句对象

         2.SQL语句中的第几个问号?

         3.用户所要传得参数

         */

        sqlite3_bind_int(stmt,1, number);

//       4. 执行语句对象

        /**

         *   sqlite3_column_int(<#sqlite3_stmt *#>, <#int iCol#>)

第一个参数语句对象stmt

         第二个参数 在表中的第几列

         */

        if (sqlite3_step(stmt ) ==SQLITE_ROW) {

//5.获取数据

            constunsigned char * nameUTF =sqlite3_column_text(stmt, 0);

            int number =sqlite3_column_int(stmt, 1);

            constunsigned char * sexUTF =sqlite3_column_text(stmt, 2);

            stu = [[Studentalloc]initWithNumber:numbername:[NSStringstringWithUTF8String:(constchar *)nameUTF] sex:[NSStringstringWithUTF8String:(constchar *)sexUTF]];

                   }

      

    }

      sqlite3_finalize(stmt);

    return stu;

}

-(BOOL)insertStudentWith:(NSString *)name  sex:(NSString *)sex

{

    sqlite3 *db = [DataBaseopenDB];

    sqlite3_stmt * stmt =nil;

    int result = sqlite3_prepare_v2(db, "insert into stuentinfo (name,sex) values(?,?)", -1, &stmt,nil);

    BOOL  insertInfo =NO;

    if (result ==SQLITE_OK) {

        /**

         *   sqlite3_bind_text(stmt, 1, [name UTF8String], -1,nil );

         1.语句对象

         2.第几个问好

         3.用户传过来的值

         4.读取参数的长度(给负数的话,会读取全部内容)

         5. 任意类型的函数指针,主要用来传值。一般情况下给nil

         */

        sqlite3_bind_text(stmt,1, [name UTF8String], -1,nil );

        sqlite3_bind_text(stmt,2, [sex UTF8String], -1,nil);

        if (sqlite3_step(stmt) ==SQLITE_DONE) {

            insertInfo = YES;

        }

    }

    return  insertInfo;

}

//删除

-(void)deleteStudentByNumber :(int)number

{


    sqlite3 *db = [DataBaseopenDB];

    sqlite3_stmt * stmt =nil;

    int result =sqlite3_prepare_v2(db, "delete from stuentinfo where number = ?", -1, &stmt,nil);

    if (result ==SQLITE_OK) {

        sqlite3_bind_int(stmt,1, number);

    }

    sqlite3_finalize(stmt);

}

//修改

-(void)updateStudentWithname:(NSString *)name number:(int)number

{

    sqlite3 * db = [DataBaseopenDB];

    sqlite3_stmt * stmt =nil;

    int result =sqlite3_prepare_v2(db,"update stuentinfo set name = ? where number = ?", -1, &stmt,nil);

    if (result ==SQLITE_OK) {

        sqlite3_bind_int(stmt,2, number);

         sqlite3_bind_text(stmt,1, [name UTF8String]  , -1,nil);

    }

     sqlite3_finalize(stmt);

   

}



/**

 *  绑定二进制流NSData* data= nil;

  sqlite3_bind_blob(stmt, 3, [data bytes], (int)[data length], nil]

 1. 语句对象

 2. 第几个问号

 3. 二进制流对应的c语言下的内容

 4.读取的长度(必须要给完整地二进制流的长度,否则出错)

 5.任意类型的函数指针,可以给nil

 */



0 0
原创粉丝点击