先创建一个工程,导入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) {
return db;
}
NSString * docPath = [NSSearchPathForDirectoriesInDomains(9,1, 1) lastObject];
NSString * filePath = [docPath stringByAppendingPathComponent:@"MySql.sqlite"];
NSLog(@"%@",docPath);
NSFileManager * fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePath]== NO ) {
NSString * bundlePath = [[NSBundle mainBundle]pathForResource:@"MySql" ofType:@"sqlite"];
NSLog(@"%@",bundlePath);
[fileManager copyItemAtPath:bundlePath toPath:filePath error:nil];
}
sqlite3_open([filePath UTF8String], &db);
return db;
}
+(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 = [super init];
if (self) {
self.name = name;
self.number = number;
self.sex = sex;
}
return self;
}
@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 = [[StudentHandle alloc]init];
}
return standarHandle;
}
}
-(NSArray *)allStudents
{
//1. 打开数据库;
sqlite3 * db = [DataBase openDB];
// 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 = [NSMutableArray arrayWithCapacity:0];
while (sqlite3_step(stmt) == SQLITE_ROW) {
// 4. 获取数据
int number = sqlite3_column_int(stmt, 0);
const unsigned char * nameUTF = sqlite3_column_text(stmt, 1);
const unsigned char * sexUTF = sqlite3_column_text(stmt, 2);
NSString * name = [NSString stringWithUTF8String:( const char *)nameUTF];
NSString * sex = [NSString stringWithUTF8String:(const char *)sexUTF];
Student * stu= [[Student alloc]initWithNumber:number name:name sex:sex];
[arr addObject:stu];
}
}
// 5.释放statement所占用的内存
sqlite3_finalize(stmt);
return arr;
}
-(Student * )studentByNumber:(int)number
{//1.打开数据库
sqlite3 * db = [DataBase openDB];
// 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.获取数据
const unsigned char * nameUTF = sqlite3_column_text(stmt, 0);
int number = sqlite3_column_int(stmt, 1);
const unsigned char * sexUTF = sqlite3_column_text(stmt, 2);
stu = [[Student alloc]initWithNumber:number name:[NSString stringWithUTF8String:(const char *)nameUTF] sex:[NSString stringWithUTF8String:(const char *)sexUTF]];
}
}
sqlite3_finalize(stmt);
return stu;
}
-(BOOL)insertStudentWith:(NSString *)name sex:(NSString *)sex
{
sqlite3 *db = [DataBase openDB];
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 = [DataBase openDB];
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 = [DataBase openDB];
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
*/